require'benchmark'require'date'require'bigdecimal'require'bigdecimal/util'# TODO: Autoload these filesrequire'active_record/connection_adapters/abstract/schema_definitions'require'active_record/connection_adapters/abstract/schema_statements'require'active_record/connection_adapters/abstract/database_statements'require'active_record/connection_adapters/abstract/quoting'require'active_record/connection_adapters/abstract/connection_pool'require'active_record/connection_adapters/abstract/connection_specification'require'active_record/connection_adapters/abstract/query_cache'require'active_record/connection_adapters/abstract/database_limits'moduleActiveRecordmoduleConnectionAdapters# :nodoc:# ActiveRecord 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.classAbstractAdapterincludeQuoting,DatabaseStatements,SchemaStatementsincludeDatabaseLimitsincludeQueryCacheincludeActiveSupport::Callbacksdefine_callbacks:checkout,:checkin@@row_even=truedefinitialize(connection,logger=nil)#:nodoc:@connection,@logger=connection,logger@runtime=0@last_verification=0@query_cache_enabled=falseend# Returns the human-readable name of the adapter. Use mixed case - one# can always use downcase if needed.defadapter_name'Abstract'end# Does this adapter support migrations? Backend specific, as the# abstract adapter always returns +false+.defsupports_migrations?falseend# Can this adapter determine the primary key for tables not attached# to an ActiveRecord class, such as join tables? Backend specific, as# the abstract adapter always returns +false+.defsupports_primary_key?falseend# Does this adapter support using DISTINCT within COUNT? This is +true+# for all adapters except sqlite.defsupports_count_distinct?trueend# 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.defsupports_ddl_transactions?falseend# Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite# does not.defsupports_savepoints?falseend# 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.defprefetch_primary_key?(table_name=nil)falseenddefreset_runtime#:nodoc:rt,@runtime=@runtime,0rtend# QUOTING ==================================================# Override to return the quoted table name. Defaults to column quoting.defquote_table_name(name)quote_column_name(name)end# REFERENTIAL INTEGRITY ====================================# Override to turn off referential integrity while executing <tt>&block</tt>.defdisable_referential_integrity(&block)yieldend# CONNECTION MANAGEMENT ====================================# 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.defactive?@active!=falseend# Disconnects from the database if already connected, and establishes a# new connection with the database.defreconnect!@active=trueend# Disconnects from the database if already connected. Otherwise, this# method does nothing.defdisconnect!@active=falseend# 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.defreset!# this should be overridden by concrete adaptersend# Returns true if its safe to reload the connection between requests for development mode.defrequires_reloading?trueend# Checks whether the connection to the database is still active (i.e. not stale).# This is done under the hood by calling <tt>active?</tt>. If the connection# is no longer active, then this method will reconnect to the database.defverify!(*ignored)reconnect!unlessactive?end# 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.defraw_connection@connectionenddefopen_transactions@open_transactions||=0enddefincrement_open_transactions@open_transactions||=0@open_transactions+=1enddefdecrement_open_transactions@open_transactions-=1enddeftransaction_joinable=(joinable)@transaction_joinable=joinableenddefcreate_savepointenddefrollback_to_savepointenddefrelease_savepointenddefcurrent_savepoint_name"active_record_#{open_transactions}"enddeflog_info(sql,name,ms)if@logger&&@logger.debug?name='%s (%.1fms)'%[name||'SQL',ms]@logger.debug(format_log_entry(name,sql.squeeze(' ')))endendprotecteddeflog(sql,name)ifblock_given?result=nilms=Benchmark.ms{result=yield}@runtime+=mslog_info(sql,name,ms)resultelselog_info(sql,name,0)nilendrescueSystemExit,SignalException,NoMemoryError=>e# Don't re-wrap these exceptions. They are probably not being caused by invalid# sql, but rather some external stimulus beyond the responsibilty of this code.# Additionaly, wrapping these exceptions with StatementInvalid would lead to# meaningful loss of data, such as losing SystemExit#status.raiseerescueException=>e# Log message and raise exception.# Set last_verification to 0, so that connection gets verified# upon reentering the request loop@last_verification=0message="#{e.class.name}: #{e.message}: #{sql}"log_info(message,name,0)raiseActiveRecord::StatementInvalid,messageenddefformat_log_entry(message,dump=nil)ifActiveRecord::Base.colorize_loggingif@@row_even@@row_even=falsemessage_color,dump_color="4;36;1","0;1"else@@row_even=truemessage_color,dump_color="4;35;1","0"endlog_entry=" \e[#{message_color}m#{message}\e[0m "log_entry<<"\e[#{dump_color}m%#{String===dump?'s':'p'}\e[0m"%dumpifdumplog_entryelse"%s %s"%[message,dump]endendendendend