4 require 'bigdecimal/util'
6 require 'active_record/connection_adapters/abstract/schema_definitions'
7 require 'active_record/connection_adapters/abstract/schema_statements'
8 require 'active_record/connection_adapters/abstract/database_statements'
9 require 'active_record/connection_adapters/abstract/quoting'
10 require 'active_record/connection_adapters/abstract/connection_pool'
11 require 'active_record/connection_adapters/abstract/connection_specification'
12 require 'active_record/connection_adapters/abstract/query_cache'
15 module ConnectionAdapters
# :nodoc:
16 # ActiveRecord supports multiple database systems. AbstractAdapter and
17 # related classes form the abstraction layer which makes this possible.
18 # An AbstractAdapter represents a connection to a database, and provides an
19 # abstract interface for database-specific functionality such as establishing
20 # a connection, escaping values, building the right SQL fragments for ':offset'
21 # and ':limit' options, etc.
23 # All the concrete database adapters follow the interface laid down in this class.
24 # ActiveRecord::Base.connection returns an AbstractAdapter object, which
27 # Most of the methods in the adapter are useful during migrations. Most
28 # notably, the instance methods provided by SchemaStatement are very useful.
30 include Quoting
, DatabaseStatements
, SchemaStatements
32 include ActiveSupport
::Callbacks
33 define_callbacks
:checkout, :checkin
37 def initialize(connection
, logger
= nil) #:nodoc:
38 @connection, @logger = connection
, logger
40 @last_verification = 0
41 @query_cache_enabled = false
44 # Returns the human-readable name of the adapter. Use mixed case - one
45 # can always use downcase if needed.
50 # Does this adapter support migrations? Backend specific, as the
51 # abstract adapter always returns +false+.
52 def supports_migrations
?
56 # Does this adapter support using DISTINCT within COUNT? This is +true+
57 # for all adapters except sqlite.
58 def supports_count_distinct
?
62 # Does this adapter support DDL rollbacks in transactions? That is, would
63 # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
64 # SQL Server, and others support this. MySQL and others do not.
65 def supports_ddl_transactions
?
69 # Should primary key values be selected from their corresponding
70 # sequence before the insert statement? If true, next_sequence_value
71 # is called before each insert to set the record's primary key.
72 # This is false for all adapters but Firebird.
73 def prefetch_primary_key
?(table_name
= nil)
77 def reset_runtime
#:nodoc:
78 rt
, @runtime = @runtime, 0
82 # QUOTING ==================================================
84 # Override to return the quoted table name. Defaults to column quoting.
85 def quote_table_name(name
)
86 quote_column_name(name
)
89 # REFERENTIAL INTEGRITY ====================================
91 # Override to turn off referential integrity while executing <tt>&block</tt>.
92 def disable_referential_integrity(&block
)
96 # CONNECTION MANAGEMENT ====================================
98 # Checks whether the connection to the database is still active. This includes
99 # checking whether the database is actually capable of responding, i.e. whether
100 # the connection isn't stale.
105 # Disconnects from the database if already connected, and establishes a
106 # new connection with the database.
111 # Disconnects from the database if already connected. Otherwise, this
112 # method does nothing.
117 # Reset the state of this connection, directing the DBMS to clear
118 # transactions and other connection-related server-side state. Usually a
119 # database-dependent operation.
121 # The default implementation does nothing; the implementation should be
122 # overridden by concrete adapters.
124 # this should be overridden by concrete adapters
127 # Returns true if its safe to reload the connection between requests for development mode.
128 def requires_reloading
?
132 # Checks whether the connection to the database is still active (i.e. not stale).
133 # This is done under the hood by calling <tt>active?</tt>. If the connection
134 # is no longer active, then this method will reconnect to the database.
135 def verify
!(*ignored
)
136 reconnect
! unless active
?
139 # Provides access to the underlying database driver for this adapter. For
140 # example, this method returns a Mysql object in case of MysqlAdapter,
141 # and a PGconn object in case of PostgreSQLAdapter.
143 # This is useful for when you need to call a proprietary method such as
144 # PostgreSQL's lo_* methods.
149 def open_transactions
150 @open_transactions ||= 0
153 def increment_open_transactions
154 @open_transactions ||= 0
155 @open_transactions += 1
158 def decrement_open_transactions
159 @open_transactions -= 1
162 def log_info(sql
, name
, seconds
)
163 if @logger && @logger.debug
?
164 name
= "#{name.nil? ? "SQL
" : name} (#{sprintf("%.1f
", seconds * 1000)}ms)"
165 @logger.debug(format_log_entry(name
, sql
.squeeze(' ')))
173 seconds
= Benchmark
.realtime
{ result
= yield }
175 log_info(sql
, name
, seconds
)
178 log_info(sql
, name
, 0)
181 rescue Exception
=> e
182 # Log message and raise exception.
183 # Set last_verification to 0, so that connection gets verified
184 # upon reentering the request loop
185 @last_verification = 0
186 message
= "#{e.class.name}: #{e.message}: #{sql}"
187 log_info(message
, name
, 0)
188 raise ActiveRecord
::StatementInvalid, message
191 def format_log_entry(message
, dump
= nil)
192 if ActiveRecord
::Base.colorize_logging
195 message_color
, dump_color
= "4;36;1", "0;1"
198 message_color
, dump_color
= "4;35;1", "0"
201 log_entry
= " \e[#{message_color}m#{message}\e[0m "
202 log_entry
<< "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump
if dump
205 "%s %s" % [message
, dump
]