aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2008-10-05 22:16:26 +0100
committerPratik Naik <pratiknaik@gmail.com>2008-10-05 22:16:26 +0100
commita2932784bb71e72a78c32819ebd7ed2bed551e3e (patch)
tree99bfd589a48153e33f19ae72baa6e98f5708a9b8 /activerecord/lib/active_record/connection_adapters
parent4df45d86097efbeabceecfe53d8ea2da9ccbb107 (diff)
downloadrails-a2932784bb71e72a78c32819ebd7ed2bed551e3e.tar.gz
rails-a2932784bb71e72a78c32819ebd7ed2bed551e3e.tar.bz2
rails-a2932784bb71e72a78c32819ebd7ed2bed551e3e.zip
Merge docrails
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb74
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb10
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb49
4 files changed, 117 insertions, 24 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index b7d7384548..432c341e6c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -11,6 +11,21 @@ module ActiveRecord
# Connection pool base class for managing ActiveRecord database
# connections.
#
+ # == Introduction
+ #
+ # A connection pool synchronizes thread access to a limited number of
+ # database connections. The basic idea is that each thread checks out a
+ # database connection from the pool, uses that connection, and checks the
+ # connection back in. ConnectionPool is completely thread-safe, and will
+ # ensure that a connection cannot be used by two threads at the same time,
+ # as long as ConnectionPool's contract is correctly followed. It will also
+ # handle cases in which there are more threads than connections: if all
+ # connections have been checked out, and a thread tries to checkout a
+ # connection anyway, then ConnectionPool will wait until some other thread
+ # has checked in a connection.
+ #
+ # == Obtaining (checking out) a connection
+ #
# Connections can be obtained and used from a connection pool in several
# ways:
#
@@ -28,6 +43,11 @@ module ActiveRecord
# obtains a connection, yields it as the sole argument to the block,
# and returns it to the pool after the block completes.
#
+ # Connections in the pool are actually AbstractAdapter objects (or objects
+ # compatible with AbstractAdapter's interface).
+ #
+ # == Options
+ #
# There are two connection-pooling-related options that you can add to
# your database connection configuration:
#
@@ -37,6 +57,12 @@ module ActiveRecord
class ConnectionPool
attr_reader :spec
+ # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
+ # object which describes database connection information (e.g. adapter,
+ # host name, username, password, etc), as well as the maximum size for
+ # this ConnectionPool.
+ #
+ # The default ConnectionPool maximum size is 5.
def initialize(spec)
@spec = spec
# The cache of reserved connections mapped to threads
@@ -87,7 +113,7 @@ module ActiveRecord
!@connections.empty?
end
- # Disconnect all connections in the pool.
+ # Disconnects all connections in the pool, and clears the pool.
def disconnect!
@reserved_connections.each do |name,conn|
checkin conn
@@ -128,7 +154,22 @@ module ActiveRecord
end
end
- # Check-out a database connection from the pool.
+ # Check-out a database connection from the pool, indicating that you want
+ # to use it. You should call #checkin when you no longer need this.
+ #
+ # This is done by either returning an existing connection, or by creating
+ # a new connection. If the maximum number of connections for this pool has
+ # already been reached, but the pool is empty (i.e. they're all being used),
+ # then this method will wait until a thread has checked in a connection.
+ # The wait time is bounded however: if no connection can be checked out
+ # within the timeout specified for this pool, then a ConnectionTimeoutError
+ # exception will be raised.
+ #
+ # Returns: an AbstractAdapter object.
+ #
+ # Raises:
+ # - ConnectionTimeoutError: no connection can be obtained from the pool
+ # within the timeout period.
def checkout
# Checkout an available connection
@connection_mutex.synchronize do
@@ -153,7 +194,11 @@ module ActiveRecord
end
end
- # Check-in a database connection back into the pool.
+ # Check-in a database connection back into the pool, indicating that you
+ # no longer need this connection.
+ #
+ # +conn+: an AbstractAdapter object, which was obtained by earlier by
+ # calling +checkout+ on this pool.
def checkin(conn)
@connection_mutex.synchronize do
conn.run_callbacks :checkin
@@ -207,6 +252,29 @@ module ActiveRecord
end
end
+ # ConnectionHandler is a collection of ConnectionPool objects. It is used
+ # for keeping separate connection pools for ActiveRecord models that connect
+ # to different databases.
+ #
+ # For example, suppose that you have 5 models, with the following hierarchy:
+ #
+ # |
+ # +-- Book
+ # | |
+ # | +-- ScaryBook
+ # | +-- GoodBook
+ # +-- Author
+ # +-- BankAccount
+ #
+ # Suppose that Book is to connect to a separate database (i.e. one other
+ # than the default database). Then Book, ScaryBook and GoodBook will all use
+ # the same connection pool. Likewise, Author and BankAccount will use the
+ # same connection pool. However, the connection pool used by Author/BankAccount
+ # is not the same as the one used by Book/ScaryBook/GoodBook.
+ #
+ # Normally there is only a single ConnectionHandler instance, accessible via
+ # ActiveRecord::Base.connection_handler. ActiveRecord models use this to
+ # determine that connection pool that they should use.
class ConnectionHandler
def initialize(pools = {})
@connection_pools = pools
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 8fc89de22b..10dc1a81f3 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -98,8 +98,14 @@ module ActiveRecord
add_limit_offset!(sql, options) if options
end
- # Appends +LIMIT+ and +OFFSET+ options to an SQL statement.
+ # Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
+ # fragment that has the same semantics as LIMIT and OFFSET.
+ #
+ # +options+ must be a Hash which contains a +:limit+ option (required)
+ # and an +:offset+ option (optional).
+ #
# This method *modifies* the +sql+ parameter.
+ #
# ===== Examples
# add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
# generates
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index bececf82a0..c29c1562b4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -31,19 +31,25 @@ module ActiveRecord
# See the concrete implementation for details on the expected parameter values.
def columns(table_name, name = nil) end
- # Creates a new table
+ # Creates a new table with the name +table_name+. +table_name+ may either
+ # be a String or a Symbol.
+ #
# There are two ways to work with +create_table+. You can use the block
# form or the regular form, like this:
#
# === Block form
- # # create_table() yields a TableDefinition instance
+ # # create_table() passes a TableDefinition object to the block.
+ # # This form will not only create the table, but also columns for the
+ # # table.
# create_table(:suppliers) do |t|
# t.column :name, :string, :limit => 60
# # Other fields here
# end
#
# === Regular form
+ # # Creates a table called 'suppliers' with no columns.
# create_table(:suppliers)
+ # # Add a column to 'suppliers'.
# add_column(:suppliers, :name, :string, {:limit => 60})
#
# The +options+ hash can include the following keys:
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 7c37916367..c5183357a1 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -13,15 +13,19 @@ require 'active_record/connection_adapters/abstract/query_cache'
module ActiveRecord
module ConnectionAdapters # :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.
- # You can use this interface directly by borrowing the database connection from the Base with
- # Base.connection.
+ # ActiveRecord::Base.connection returns an AbstractAdapter object, which
+ # you can use.
#
- # Most of the methods in the adapter are useful during migrations. Most
- # notably, SchemaStatements#create_table, SchemaStatements#drop_table,
- # SchemaStatements#add_index, SchemaStatements#remove_index,
- # SchemaStatements#add_column, SchemaStatements#change_column and
- # SchemaStatements#remove_column are very useful.
+ # Most of the methods in the adapter are useful during migrations. Most
+ # notably, the instance methods provided by SchemaStatement are very useful.
class AbstractAdapter
include Quoting, DatabaseStatements, SchemaStatements
include QueryCache
@@ -91,26 +95,31 @@ module ActiveRecord
# CONNECTION MANAGEMENT ====================================
- # Is this connection active and ready to perform queries?
+ # 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.
def active?
@active != false
end
- # Close this connection and open a new one in its place.
+ # Disconnects from the database if already connected, and establishes a
+ # new connection with the database.
def reconnect!
@active = true
end
- # Close this connection
+ # Disconnects from the database if already connected. Otherwise, this
+ # method does nothing.
def disconnect!
@active = false
end
# 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 method simply executes a
- # ROLLBACK and swallows any exceptions which is probably not enough to
- # ensure the connection is clean.
+ # database-dependent operation.
+ #
+ # The default implementation does nothing; the implementation should be
+ # overridden by concrete adapters.
def reset!
# this should be overridden by concrete adapters
end
@@ -121,15 +130,19 @@ module ActiveRecord
false
end
- # Verify this connection by calling <tt>active?</tt> and reconnecting if
- # the connection is no longer active.
+ # 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.
def verify!(*ignored)
reconnect! unless active?
end
- # Provides access to the underlying database connection. Useful for
- # when you need to call a proprietary method such as postgresql's lo_*
- # methods
+ # 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.
def raw_connection
@connection
end