Class: ActiveRecord::ConnectionAdapters::AbstractAdapter

Inherits:
Object
  • Object
show all
Includes:
ColumnDumper, DatabaseLimits, DatabaseStatements, QueryCache, Quoting, SchemaStatements, ActiveSupport::Callbacks, MonitorMixin
Defined in:
activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Overview

Active Record supports multiple database systems. AbstractAdapter and related classes form the abstraction layer which makes this possible. An AbstractAdapter represents a connection to a database, and provides an abstract interface for database-specific functionality such as establishing a connection, escaping values, building the right SQL fragments for ':offset' and ':limit' options, etc.

All the concrete database adapters follow the interface laid down in this class. ActiveRecord::Base.connection returns an AbstractAdapter object, which you can use.

Most of the methods in the adapter are useful during migrations. Most notably, the instance methods provided by SchemaStatement are very useful.

Defined Under Namespace

Classes: SchemaCreation

Constant Summary collapse

SIMPLE_INT =
/\A\d+\z/

Constants included from ActiveSupport::Callbacks

ActiveSupport::Callbacks::CALLBACK_FILTER_TYPES

Instance Attribute Summary collapse

Attributes included from QueryCache

#query_cache, #query_cache_enabled

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ColumnDumper

#column_spec, #migration_keys, #prepare_column_options

Methods included from ActiveSupport::Callbacks

#run_callbacks

Methods included from ActiveSupport::Concern

#append_features, extended, #included

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

#allowed_index_name_length, #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

#quote, #quote_column_name, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_date, #quoted_false, #quoted_true, #type_cast

Methods included from DatabaseStatements

#add_transaction_record, #begin_db_transaction, #begin_isolated_db_transaction, #begin_transaction, #case_sensitive_equality_operator, #commit_db_transaction, #commit_transaction, #current_transaction, #default_sequence_name, #delete, #empty_insert_statement_value, #exec_delete, #exec_insert, #exec_query, #exec_update, #execute, #insert, #insert_fixture, #join_to_delete, #join_to_update, #limited_update_conditions, #reset_sequence!, #reset_transaction, #rollback_db_transaction, #rollback_transaction, #sanitize_limit, #select_all, #select_one, #select_rows, #select_value, #select_values, #supports_statement_cache?, #to_sql, #transaction, #transaction_isolation_levels, #transaction_open?, #update, #within_new_transaction

Methods included from SchemaStatements

#add_column, #add_index, #add_reference, #add_timestamps, #assume_migrated_upto_version, #change_column, #change_column_default, #change_column_null, #change_table, #column_exists?, #columns, #columns_for_distinct, #create_join_table, #create_table, #drop_join_table, #drop_table, #dump_schema_information, #index_exists?, #index_name, #index_name_exists?, #initialize_schema_migrations_table, #native_database_types, #remove_column, #remove_columns, #remove_index, #remove_index!, #remove_reference, #remove_timestamps, #rename_column, #rename_index, #rename_table, #table_alias_for, #table_exists?, #type_to_sql

Constructor Details

#initialize(connection, logger = nil, pool = nil) ⇒ AbstractAdapter

:nodoc:


89
90
91
92
93
94
95
96
97
98
99
100
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 89

def initialize(connection, logger = nil, pool = nil) #:nodoc:
  super()

  @connection          = connection
  @in_use              = false
  @instrumenter        = ActiveSupport::Notifications.instrumenter
  @last_use            = false
  @logger              = logger
  @pool                = pool
  @schema_cache        = SchemaCache.new self
  @visitor             = nil
end

Instance Attribute Details

#in_useObject (readonly) Also known as: in_use?

Returns the value of attribute in_use


70
71
72
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 70

def in_use
  @in_use
end

#last_useObject (readonly)

Returns the value of attribute last_use


70
71
72
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 70

def last_use
  @last_use
end

#loggerObject (readonly)

Returns the value of attribute logger


70
71
72
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 70

def logger
  @logger
end

#poolObject

Returns the value of attribute pool


69
70
71
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 69

def pool
  @pool
end

#schema_cacheObject

Returns the value of attribute schema_cache


70
71
72
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 70

def schema_cache
  @schema_cache
end

#visitorObject

Returns the value of attribute visitor


69
70
71
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 69

def visitor
  @visitor
end

Class Method Details

.type_cast_config_to_boolean(config) ⇒ Object


81
82
83
84
85
86
87
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 81

def self.type_cast_config_to_boolean(config)
  if config == "false"
    false
  else
    config
  end
end

.type_cast_config_to_integer(config) ⇒ Object


73
74
75
76
77
78
79
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 73

def self.type_cast_config_to_integer(config)
  if config =~ SIMPLE_INT
    config.to_i
  else
    config
  end
end

Instance Method Details

#active?Boolean

Checks whether the connection to the database is still active. This includes checking whether the database is actually capable of responding, i.e. whether the connection isn't stale.

Returns:

  • (Boolean)

326
327
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 326

def active?
end

#adapter_nameObject

Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.


219
220
221
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 219

def adapter_name
  'Abstract'
end

#case_insensitive_comparison(table, attribute, column, value) ⇒ Object


401
402
403
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 401

def case_insensitive_comparison(table, attribute, column, value)
  table[attribute].lower.eq(table.lower(value))
end

#case_sensitive_modifier(node) ⇒ Object


397
398
399
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 397

def case_sensitive_modifier(node)
  node
end

#clear_cache!Object

Clear any caching the database adapter may be doing, for example clearing the prepared statement cache. This is database specific.


357
358
359
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 357

def clear_cache!
  # this should be overridden by concrete adapters
end

#closeObject

Check the connection back in to the connection pool


410
411
412
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 410

def close
  pool.checkin self
end

#create_savepointObject


388
389
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 388

def create_savepoint
end

#current_savepoint_nameObject


405
406
407
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 405

def current_savepoint_name
  "active_record_#{open_transactions}"
end

#disable_referential_integrityObject

Override to turn off referential integrity while executing &block.


317
318
319
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 317

def disable_referential_integrity
  yield
end

#disconnect!Object

Disconnects from the database if already connected. Otherwise, this method does nothing.


339
340
341
342
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 339

def disconnect!
  clear_cache!
  reset_transaction
end

#expireObject


202
203
204
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 202

def expire
  @in_use = false
end

#extensionsObject

A list of extensions, to be filled in by adapters that support them. At the moment only postgresql does.


296
297
298
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 296

def extensions
  []
end

#index_algorithmsObject

A list of index algorithms, to be filled by adapters that support them. MySQL and PostgreSQL have support for them right now.


302
303
304
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 302

def index_algorithms
  {}
end

#leaseObject


188
189
190
191
192
193
194
195
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 188

def lease
  synchronize do
    unless in_use
      @in_use   = true
      @last_use = Time.now
    end
  end
end

#open_transactionsObject


384
385
386
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 384

def open_transactions
  @transaction.number
end

#prefetch_primary_key?(table_name = nil) ⇒ Boolean

Should primary key values be selected from their corresponding sequence before the insert statement? If true, next_sequence_value is called before each insert to set the record's primary key. This is false for all adapters but Firebird.

Returns:

  • (Boolean)

263
264
265
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 263

def prefetch_primary_key?(table_name = nil)
  false
end

#raw_connectionObject

Provides access to the underlying database driver for this adapter. For example, this method returns a Mysql object in case of MysqlAdapter, and a PGconn object in case of PostgreSQLAdapter.

This is useful for when you need to call a proprietary method such as PostgreSQL's lo_* methods.


380
381
382
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 380

def raw_connection
  @connection
end

#reconnect!Object

Disconnects from the database if already connected, and establishes a new connection with the database. Implementors should call super if they override the default implementation.


332
333
334
335
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 332

def reconnect!
  clear_cache!
  reset_transaction
end

#release_savepointObject


394
395
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 394

def release_savepoint
end

#requires_reloading?Boolean

Returns true if its required to reload the connection between requests for development mode. This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.

Returns:

  • (Boolean)

363
364
365
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 363

def requires_reloading?
  false
end

#reset!Object

Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state. Usually a database-dependent operation.

The default implementation does nothing; the implementation should be overridden by concrete adapters.


350
351
352
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 350

def reset!
  # this should be overridden by concrete adapters
end

#rollback_to_savepointObject


391
392
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 391

def rollback_to_savepoint
end

#schema_creationObject


184
185
186
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 184

def schema_creation
  SchemaCreation.new self
end

#substitute_at(column, index) ⇒ Object

Returns a bind substitution value given a bind index and column NOTE: The column param is currently being used by the sqlserver-adapter


310
311
312
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 310

def substitute_at(column, index)
  Arel::Nodes::BindParam.new '?'
end

#supports_bulk_alter?Boolean

Returns:

  • (Boolean)

249
250
251
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 249

def supports_bulk_alter?
  false
end

#supports_count_distinct?Boolean

Does this adapter support using DISTINCT within COUNT? This is true for all adapters except sqlite.

Returns:

  • (Boolean)

238
239
240
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 238

def supports_count_distinct?
  true
end

#supports_ddl_transactions?Boolean

Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL, SQL Server, and others support this. MySQL and others do not.

Returns:

  • (Boolean)

245
246
247
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 245

def supports_ddl_transactions?
  false
end

#supports_explain?Boolean

Does this adapter support explain? As of this writing sqlite3, mysql2, and postgresql are the only ones that do.

Returns:

  • (Boolean)

279
280
281
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 279

def supports_explain?
  false
end

#supports_extensions?Boolean

Does this adapter support database extensions? As of this writing only postgresql does.

Returns:

  • (Boolean)

290
291
292
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 290

def supports_extensions?
  false
end

#supports_index_sort_order?Boolean

Does this adapter support index sort order?

Returns:

  • (Boolean)

268
269
270
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 268

def supports_index_sort_order?
  false
end

#supports_migrations?Boolean

Does this adapter support migrations? Backend specific, as the abstract adapter always returns false.

Returns:

  • (Boolean)

225
226
227
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 225

def supports_migrations?
  false
end

#supports_partial_index?Boolean

Does this adapter support partial indices?

Returns:

  • (Boolean)

273
274
275
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 273

def supports_partial_index?
  false
end

#supports_primary_key?Boolean

Can this adapter determine the primary key for tables not attached to an Active Record class, such as join tables? Backend specific, as the abstract adapter always returns false.

Returns:

  • (Boolean)

232
233
234
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 232

def supports_primary_key?
  false
end

#supports_savepoints?Boolean

Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite < 3.6.8 does not.

Returns:

  • (Boolean)

255
256
257
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 255

def supports_savepoints?
  false
end

#supports_transaction_isolation?Boolean

Does this adapter support setting the isolation level for a transaction?

Returns:

  • (Boolean)

284
285
286
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 284

def supports_transaction_isolation?
  false
end

#unprepared_statementObject


210
211
212
213
214
215
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 210

def unprepared_statement
  old, @visitor = @visitor, unprepared_visitor
  yield
ensure
  @visitor = old
end

#unprepared_visitorObject


206
207
208
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 206

def unprepared_visitor
  self.class::BindSubstitution.new self
end

#valid_type?(type) ⇒ Boolean

Returns:

  • (Boolean)

102
103
104
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 102

def valid_type?(type)
  true
end

#verify!(*ignored) ⇒ Object

Checks whether the connection to the database is still active (i.e. not stale). This is done under the hood by calling active?. If the connection is no longer active, then this method will reconnect to the database.


370
371
372
# File 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb', line 370

def verify!(*ignored)
  reconnect! unless active?
end