4 require 'bigdecimal/util'
6 # TODO: Autoload these files
7 require 'active_record/connection_adapters/abstract/schema_definitions'
8 require 'active_record/connection_adapters/abstract/schema_statements'
9 require 'active_record/connection_adapters/abstract/database_statements'
10 require 'active_record/connection_adapters/abstract/quoting'
11 require 'active_record/connection_adapters/abstract/connection_pool'
12 require 'active_record/connection_adapters/abstract/connection_specification'
13 require 'active_record/connection_adapters/abstract/query_cache'
16 module ConnectionAdapters
# :nodoc:
17 # ActiveRecord supports multiple database systems. AbstractAdapter and
18 # related classes form the abstraction layer which makes this possible.
19 # An AbstractAdapter represents a connection to a database, and provides an
20 # abstract interface for database-specific functionality such as establishing
21 # a connection, escaping values, building the right SQL fragments for ':offset'
22 # and ':limit' options, etc.
24 # All the concrete database adapters follow the interface laid down in this class.
25 # ActiveRecord::Base.connection returns an AbstractAdapter object, which
28 # Most of the methods in the adapter are useful during migrations. Most
29 # notably, the instance methods provided by SchemaStatement are very useful.
31 include Quoting
, DatabaseStatements
, SchemaStatements
33 include ActiveSupport
::Callbacks
34 define_callbacks
:checkout, :checkin
38 def initialize(connection
, logger
= nil) #:nodoc:
39 @connection, @logger = connection
, logger
41 @last_verification = 0
42 @query_cache_enabled = false
45 # Returns the human-readable name of the adapter. Use mixed case - one
46 # can always use downcase if needed.
51 # Does this adapter support migrations? Backend specific, as the
52 # abstract adapter always returns +false+.
53 def supports_migrations
?
57 # Does this adapter support using DISTINCT within COUNT? This is +true+
58 # for all adapters except sqlite.
59 def supports_count_distinct
?
63 # Does this adapter support DDL rollbacks in transactions? That is, would
64 # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
65 # SQL Server, and others support this. MySQL and others do not.
66 def supports_ddl_transactions
?
70 # Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite
72 def supports_savepoints
?
76 # Should primary key values be selected from their corresponding
77 # sequence before the insert statement? If true, next_sequence_value
78 # is called before each insert to set the record's primary key.
79 # This is false for all adapters but Firebird.
80 def prefetch_primary_key
?(table_name
= nil)
84 def reset_runtime
#:nodoc:
85 rt
, @runtime = @runtime, 0
89 # QUOTING ==================================================
91 # Override to return the quoted table name. Defaults to column quoting.
92 def quote_table_name(name
)
93 quote_column_name(name
)
96 # REFERENTIAL INTEGRITY ====================================
98 # Override to turn off referential integrity while executing <tt>&block</tt>.
99 def disable_referential_integrity(&block
)
103 # CONNECTION MANAGEMENT ====================================
105 # Checks whether the connection to the database is still active. This includes
106 # checking whether the database is actually capable of responding, i.e. whether
107 # the connection isn't stale.
112 # Disconnects from the database if already connected, and establishes a
113 # new connection with the database.
118 # Disconnects from the database if already connected. Otherwise, this
119 # method does nothing.
124 # Reset the state of this connection, directing the DBMS to clear
125 # transactions and other connection-related server-side state. Usually a
126 # database-dependent operation.
128 # The default implementation does nothing; the implementation should be
129 # overridden by concrete adapters.
131 # this should be overridden by concrete adapters
134 # Returns true if its safe to reload the connection between requests for development mode.
135 def requires_reloading
?
139 # Checks whether the connection to the database is still active (i.e. not stale).
140 # This is done under the hood by calling <tt>active?</tt>. If the connection
141 # is no longer active, then this method will reconnect to the database.
142 def verify
!(*ignored
)
143 reconnect
! unless active
?
146 # Provides access to the underlying database driver for this adapter. For
147 # example, this method returns a Mysql object in case of MysqlAdapter,
148 # and a PGconn object in case of PostgreSQLAdapter.
150 # This is useful for when you need to call a proprietary method such as
151 # PostgreSQL's lo_* methods.
156 def open_transactions
157 @open_transactions ||= 0
160 def increment_open_transactions
161 @open_transactions ||= 0
162 @open_transactions += 1
165 def decrement_open_transactions
166 @open_transactions -= 1
169 def transaction_joinable
=(joinable
)
170 @transaction_joinable = joinable
176 def rollback_to_savepoint
179 def release_savepoint
182 def current_savepoint_name
183 "active_record_#{open_transactions}"
186 def log_info(sql
, name
, ms
)
187 if @logger && @logger.debug
?
188 name
= '%s (%.1fms)' % [name
|| 'SQL', ms
]
189 @logger.debug(format_log_entry(name
, sql
.squeeze(' ')))
197 ms
= Benchmark
.ms
{ result
= yield }
199 log_info(sql
, name
, ms
)
202 log_info(sql
, name
, 0)
205 rescue Exception
=> e
206 # Log message and raise exception.
207 # Set last_verification to 0, so that connection gets verified
208 # upon reentering the request loop
209 @last_verification = 0
210 message
= "#{e.class.name}: #{e.message}: #{sql}"
211 log_info(message
, name
, 0)
212 raise ActiveRecord
::StatementInvalid, message
215 def format_log_entry(message
, dump
= nil)
216 if ActiveRecord
::Base.colorize_logging
219 message_color
, dump_color
= "4;36;1", "0;1"
222 message_color
, dump_color
= "4;35;1", "0"
225 log_entry
= " \e[#{message_color}m#{message}\e[0m "
226 log_entry
<< "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump
if dump
229 "%s %s" % [message
, dump
]