Class: ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Defined in:
- lib/active_record/connection_adapters/sqlite3_adapter.rb
Overview
The SQLite3 adapter works SQLite 3.6.16 or newer with the sqlite3-ruby drivers (available as gem from rubygems.org/gems/sqlite3).
Options:
-
:database
- Path to the database file.
Defined Under Namespace
Classes: StatementPool
Constant Summary collapse
- ADAPTER_NAME =
'SQLite'.freeze
- NATIVE_DATABASE_TYPES =
{ primary_key: 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL', string: { name: "varchar" }, text: { name: "text" }, integer: { name: "integer" }, float: { name: "float" }, decimal: { name: "decimal" }, datetime: { name: "datetime" }, time: { name: "time" }, date: { name: "date" }, binary: { name: "blob" }, boolean: { name: "boolean" } }
Constants inherited from AbstractAdapter
Instance Attribute Summary
Attributes inherited from AbstractAdapter
#logger, #owner, #pool, #prepared_statements, #schema_cache, #visitor
Attributes included from QueryCache
#query_cache, #query_cache_enabled
Attributes included from DatabaseStatements
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#allowed_index_name_length ⇒ Object
Returns 62.
-
#arel_visitor ⇒ Object
:nodoc:.
-
#begin_db_transaction ⇒ Object
:nodoc:.
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#change_column_default(table_name, column_name, default_or_changes) ⇒ Object
:nodoc:.
-
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:.
-
#clear_cache! ⇒ Object
Clears the prepared statements cache.
-
#columns(table_name) ⇒ Object
Returns an array of
Column
objects for the table specified bytable_name
. -
#commit_db_transaction ⇒ Object
:nodoc:.
- #data_source_exists?(table_name) ⇒ Boolean
- #data_sources ⇒ Object
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#encoding ⇒ Object
Returns the current database encoding format as a string, eg: ‘UTF-8’.
- #exec_delete(sql, name = 'SQL', binds = []) ⇒ Object (also: #exec_update)
- #exec_query(sql, name = nil, binds = [], prepare: false) ⇒ Object
-
#exec_rollback_db_transaction ⇒ Object
:nodoc:.
-
#execute(sql, name = nil) ⇒ Object
:nodoc:.
-
#explain(arel, binds = []) ⇒ Object
– DATABASE STATEMENTS ====================================== ++.
-
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
-
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
constructor
A new instance of SQLite3Adapter.
- #last_inserted_id(result) ⇒ Object
-
#native_database_types ⇒ Object
:nodoc:.
-
#primary_keys(table_name) ⇒ Object
:nodoc:.
-
#remove_column(table_name, column_name, type = nil, options = {}) ⇒ Object
:nodoc:.
-
#remove_index(table_name, options = {}) ⇒ Object
:nodoc:.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:.
-
#rename_table(table_name, new_name) ⇒ Object
Renames a table.
- #requires_reloading? ⇒ Boolean
-
#schema_creation ⇒ Object
:nodoc:.
- #supports_datetime_with_precision? ⇒ Boolean
- #supports_ddl_transactions? ⇒ Boolean
- #supports_explain? ⇒ Boolean
- #supports_index_sort_order? ⇒ Boolean
-
#supports_migrations? ⇒ Boolean
Returns true, since this connection adapter supports migrations.
- #supports_multi_insert? ⇒ Boolean
- #supports_partial_index? ⇒ Boolean
-
#supports_primary_key? ⇒ Boolean
:nodoc:.
- #supports_savepoints? ⇒ Boolean
-
#supports_statement_cache? ⇒ Boolean
Returns true, since this connection adapter supports prepared statement caching.
- #supports_views? ⇒ Boolean
- #table_exists?(table_name) ⇒ Boolean
-
#tables(name = nil) ⇒ Object
SCHEMA STATEMENTS ========================================.
-
#valid_alter_table_type?(type) ⇒ Boolean
See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement.
- #valid_type?(type) ⇒ Boolean
-
#view_exists?(view_name) ⇒ Boolean
:nodoc:.
-
#views ⇒ Object
:nodoc:.
Methods included from ActiveRecord::ConnectionAdapters::SQLite3::Quoting
#quote_column_name, #quote_string, #quote_table_name_for_assignment, #quoted_time
Methods inherited from AbstractAdapter
#adapter_name, #case_insensitive_comparison, #case_sensitive_comparison, #close, #collector, #column_name_for_operation, #combine_bind_parameters, #disable_extension, #disable_referential_integrity, #enable_extension, #expire, #extensions, #get_advisory_lock, #index_algorithms, #lease, #lookup_cast_type, #new_column, #prefetch_primary_key?, #raw_connection, #reconnect!, #release_advisory_lock, #reset!, #supports_advisory_locks?, #supports_bulk_alter?, #supports_comments?, #supports_comments_in_create?, #supports_expression_index?, #supports_extensions?, #supports_json?, #supports_transaction_isolation?, type_cast_config_to_boolean, type_cast_config_to_integer, #type_map, #unprepared_statement, #verify!
Methods included from Savepoints
#create_savepoint, #current_savepoint_name, #exec_rollback_to_savepoint, #release_savepoint
Methods included from ColumnDumper
#column_spec, #column_spec_for_primary_key, #migration_keys, #prepare_column_options
Methods included from QueryCache
#cache, #clear_query_cache, dirties_query_cache, #disable_query_cache!, #enable_query_cache!, included, #select_all, #uncached
Methods included from DatabaseLimits
#column_name_length, #columns_per_multicolumn_index, #columns_per_table, #in_clause_length, #index_name_length, #indexes_per_table, #joins_per_query, #sql_query_length, #table_alias_length, #table_name_length
Methods included from Quoting
#fetch_type_metadata, #lookup_cast_type_from_column, #prepare_binds_for_database, #quote, #quote_column_name, #quote_default_expression, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_date, #quoted_false, #quoted_time, #quoted_true, #type_cast, #type_cast_from_column, #unquoted_false, #unquoted_true
Methods included from DatabaseStatements
#add_transaction_record, #begin_isolated_db_transaction, #cacheable_query, #default_sequence_name, #delete, #empty_insert_statement_value, #exec_insert, #insert, #insert_fixture, #join_to_update, #reset_sequence!, #reset_transaction, #rollback_db_transaction, #rollback_to_savepoint, #sanitize_limit, #select_all, #select_one, #select_rows, #select_value, #select_values, #to_sql, #transaction, #transaction_isolation_levels, #transaction_open?, #transaction_state, #truncate, #update
Methods included from SchemaStatements
#add_foreign_key, #add_index, #add_index_options, #add_reference, #add_timestamps, #assume_migrated_upto_version, #change_column_comment, #change_table, #change_table_comment, #column_exists?, #columns_for_distinct, #create_join_table, #create_table, #drop_join_table, #drop_table, #dump_schema_information, #foreign_key_column_for, #foreign_key_exists?, #foreign_key_for, #foreign_key_for!, #foreign_key_options, #foreign_keys, #index_exists?, #index_name, #index_name_exists?, #initialize_internal_metadata_table, #initialize_schema_migrations_table, #insert_versions_sql, #internal_string_options_for_primary_key, #options_include_default?, #primary_key, #remove_columns, #remove_foreign_key, #remove_reference, #remove_timestamps, #rename_index, #table_alias_for, #table_comment, #table_options, #type_to_sql, #update_table_definition
Constructor Details
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
Returns a new instance of SQLite3Adapter.
86 87 88 89 90 91 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 86 def initialize(connection, logger, , config) super(connection, logger, config) @active = nil @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) end |
Instance Method Details
#active? ⇒ Boolean
136 137 138 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 136 def active? @active != false end |
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
371 372 373 374 375 376 377 378 379 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 371 def add_column(table_name, column_name, type, = {}) #:nodoc: if valid_alter_table_type?(type) super(table_name, column_name, type, ) else alter_table(table_name) do |definition| definition.column(column_name, type, ) end end end |
#allowed_index_name_length ⇒ Object
Returns 62. SQLite supports index names up to 64 characters. The rest is used by rails internally to perform temporary rename operations
164 165 166 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 164 def allowed_index_name_length index_name_length - 2 end |
#arel_visitor ⇒ Object
:nodoc:
82 83 84 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 82 def arel_visitor # :nodoc: Arel::Visitors::SQLite.new(self) end |
#begin_db_transaction ⇒ Object
:nodoc:
235 236 237 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 235 def begin_db_transaction #:nodoc: log('begin transaction',nil) { @connection.transaction } end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 404 def change_column(table_name, column_name, type, = {}) #:nodoc: alter_table(table_name) do |definition| include_default = () definition[column_name].instance_eval do self.type = type self.limit = [:limit] if .include?(:limit) self.default = [:default] if include_default self.null = [:null] if .include?(:null) self.precision = [:precision] if .include?(:precision) self.scale = [:scale] if .include?(:scale) self.collation = [:collation] if .include?(:collation) end end end |
#change_column_default(table_name, column_name, default_or_changes) ⇒ Object
:nodoc:
387 388 389 390 391 392 393 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 387 def change_column_default(table_name, column_name, default_or_changes) #:nodoc: default = extract_new_default_value(default_or_changes) alter_table(table_name) do |definition| definition[column_name].default = default end end |
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:
395 396 397 398 399 400 401 402 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 395 def change_column_null(table_name, column_name, null, default = nil) #:nodoc: unless null || default.nil? exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") end alter_table(table_name) do |definition| definition[column_name].null = null end end |
#clear_cache! ⇒ Object
Clears the prepared statements cache.
149 150 151 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 149 def clear_cache! @statements.clear end |
#columns(table_name) ⇒ Object
Returns an array of Column
objects for the table specified by table_name
.
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 302 def columns(table_name) # :nodoc: table_name = table_name.to_s table_structure(table_name).map do |field| case field["dflt_value"] when /^null$/i field["dflt_value"] = nil when /^'(.*)'$/m field["dflt_value"] = $1.gsub("''", "'") when /^"(.*)"$/m field["dflt_value"] = $1.gsub('""', '"') end collation = field['collation'] sql_type = field['type'] = (sql_type) new_column(field['name'], field['dflt_value'], , field['notnull'].to_i == 0, table_name, nil, collation) end end |
#commit_db_transaction ⇒ Object
:nodoc:
239 240 241 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 239 def commit_db_transaction #:nodoc: log('commit transaction',nil) { @connection.commit } end |
#data_source_exists?(table_name) ⇒ Boolean
279 280 281 282 283 284 285 286 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 279 def data_source_exists?(table_name) return false unless table_name.present? sql = "SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'" sql << " AND name = #{quote(table_name)}" select_values(sql, 'SCHEMA').any? end |
#data_sources ⇒ Object
265 266 267 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 265 def data_sources select_values("SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'", 'SCHEMA') end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
142 143 144 145 146 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 142 def disconnect! super @active = false @connection.close rescue nil end |
#encoding ⇒ Object
Returns the current database encoding format as a string, eg: ‘UTF-8’
173 174 175 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 173 def encoding @connection.encoding.to_s end |
#exec_delete(sql, name = 'SQL', binds = []) ⇒ Object Also known as: exec_update
221 222 223 224 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 221 def exec_delete(sql, name = 'SQL', binds = []) exec_query(sql, name, binds) @connection.changes end |
#exec_query(sql, name = nil, binds = [], prepare: false) ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 190 def exec_query(sql, name = nil, binds = [], prepare: false) type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) } log(sql, name, binds) do # Don't cache statements if they are not prepared unless prepare stmt = @connection.prepare(sql) begin cols = stmt.columns unless without_prepared_statement?(binds) stmt.bind_params(type_casted_binds) end records = stmt.to_a ensure stmt.close end stmt = records else cache = @statements[sql] ||= { :stmt => @connection.prepare(sql) } stmt = cache[:stmt] cols = cache[:cols] ||= stmt.columns stmt.reset! stmt.bind_params(type_casted_binds) end ActiveRecord::Result.new(cols, stmt.to_a) end end |
#exec_rollback_db_transaction ⇒ Object
:nodoc:
243 244 245 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 243 def exec_rollback_db_transaction #:nodoc: log('rollback transaction',nil) { @connection.rollback } end |
#execute(sql, name = nil) ⇒ Object
:nodoc:
231 232 233 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 231 def execute(sql, name = nil) #:nodoc: log(sql, name) { @connection.execute(sql) } end |
#explain(arel, binds = []) ⇒ Object
– DATABASE STATEMENTS ====================================== ++
185 186 187 188 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 185 def explain(arel, binds = []) sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}" SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', [])) end |
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 322 def indexes(table_name, name = nil) #:nodoc: exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", 'SCHEMA').map do |row| sql = <<-SQL SELECT sql FROM sqlite_master WHERE name=#{quote(row['name'])} AND type='index' UNION ALL SELECT sql FROM sqlite_temp_master WHERE name=#{quote(row['name'])} AND type='index' SQL index_sql = exec_query(sql).first['sql'] match = /\sWHERE\s+(.+)$/i.match(index_sql) where = match[1] if match IndexDefinition.new( table_name, row['name'], row['unique'] != 0, exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col| col['name'] }, nil, nil, where) end end |
#last_inserted_id(result) ⇒ Object
227 228 229 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 227 def last_inserted_id(result) @connection.last_insert_row_id end |
#native_database_types ⇒ Object
:nodoc:
168 169 170 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 168 def native_database_types #:nodoc: NATIVE_DATABASE_TYPES end |
#primary_keys(table_name) ⇒ Object
:nodoc:
346 347 348 349 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 346 def primary_keys(table_name) # :nodoc: pks = table_structure(table_name).select { |f| f['pk'] > 0 } pks.sort_by { |f| f['pk'] }.map { |f| f['name'] } end |
#remove_column(table_name, column_name, type = nil, options = {}) ⇒ Object
:nodoc:
381 382 383 384 385 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 381 def remove_column(table_name, column_name, type = nil, = {}) #:nodoc: alter_table(table_name) do |definition| definition.remove_column column_name end end |
#remove_index(table_name, options = {}) ⇒ Object
:nodoc:
351 352 353 354 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 351 def remove_index(table_name, = {}) #:nodoc: index_name = index_name_for_remove(table_name, ) exec_query "DROP INDEX #{quote_column_name(index_name)}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:
419 420 421 422 423 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 419 def rename_column(table_name, column_name, new_column_name) #:nodoc: column = column_for(table_name, column_name) alter_table(table_name, rename: {column.name => new_column_name.to_s}) rename_column_indexes(table_name, column.name, new_column_name) end |
#rename_table(table_name, new_name) ⇒ Object
Renames a table.
Example:
rename_table('octopuses', 'octopi')
360 361 362 363 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 360 def rename_table(table_name, new_name) exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}" rename_table_indexes(table_name, new_name) end |
#requires_reloading? ⇒ Boolean
120 121 122 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 120 def requires_reloading? true end |
#schema_creation ⇒ Object
:nodoc:
78 79 80 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 78 def schema_creation # :nodoc: SQLite3::SchemaCreation.new self end |
#supports_datetime_with_precision? ⇒ Boolean
128 129 130 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 128 def supports_datetime_with_precision? true end |
#supports_ddl_transactions? ⇒ Boolean
93 94 95 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 93 def supports_ddl_transactions? true end |
#supports_explain? ⇒ Boolean
177 178 179 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 177 def supports_explain? true end |
#supports_index_sort_order? ⇒ Boolean
153 154 155 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 153 def supports_index_sort_order? true end |
#supports_migrations? ⇒ Boolean
Returns true, since this connection adapter supports migrations.
112 113 114 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 112 def supports_migrations? #:nodoc: true end |
#supports_multi_insert? ⇒ Boolean
132 133 134 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 132 def supports_multi_insert? sqlite_version >= '3.7.11' end |
#supports_partial_index? ⇒ Boolean
101 102 103 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 101 def supports_partial_index? sqlite_version >= '3.8.0' end |
#supports_primary_key? ⇒ Boolean
:nodoc:
116 117 118 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 116 def supports_primary_key? #:nodoc: true end |
#supports_savepoints? ⇒ Boolean
97 98 99 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 97 def supports_savepoints? true end |
#supports_statement_cache? ⇒ Boolean
Returns true, since this connection adapter supports prepared statement caching.
107 108 109 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 107 def supports_statement_cache? true end |
#supports_views? ⇒ Boolean
124 125 126 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 124 def supports_views? true end |
#table_exists?(table_name) ⇒ Boolean
269 270 271 272 273 274 275 276 277 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 269 def table_exists?(table_name) ActiveSupport::Deprecation.warn(<<-MSG.squish) #table_exists? currently checks both tables and views. This behavior is deprecated and will be changed with Rails 5.1 to only check tables. Use #data_source_exists? instead. MSG data_source_exists?(table_name) end |
#tables(name = nil) ⇒ Object
SCHEMA STATEMENTS ========================================
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 249 def tables(name = nil) # :nodoc: ActiveSupport::Deprecation.warn(<<-MSG.squish) #tables currently returns both tables and views. This behavior is deprecated and will be changed with Rails 5.1 to only return tables. Use #data_sources instead. MSG if name ActiveSupport::Deprecation.warn(<<-MSG.squish) Passing arguments to #tables is deprecated without replacement. MSG end data_sources end |
#valid_alter_table_type?(type) ⇒ Boolean
See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement
367 368 369 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 367 def valid_alter_table_type?(type) type.to_sym != :primary_key end |
#valid_type?(type) ⇒ Boolean
157 158 159 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 157 def valid_type?(type) true end |
#view_exists?(view_name) ⇒ Boolean
:nodoc:
292 293 294 295 296 297 298 299 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 292 def view_exists?(view_name) # :nodoc: return false unless view_name.present? sql = "SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'" sql << " AND name = #{quote(view_name)}" select_values(sql, 'SCHEMA').any? end |
#views ⇒ Object
:nodoc:
288 289 290 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 288 def views # :nodoc: select_values("SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'", 'SCHEMA') end |