aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-02-04 10:19:02 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2011-02-04 18:14:59 -0800
commit5f3cf4244de4fd62049d08df4e6bf63c945ab90e (patch)
treedfc201cf5bac0fc261075a95bcd2d9431d67a725 /activerecord
parent78d23edf9a5ba6d4c50cb603c9828fcf5c7fe357 (diff)
downloadrails-5f3cf4244de4fd62049d08df4e6bf63c945ab90e.tar.gz
rails-5f3cf4244de4fd62049d08df4e6bf63c945ab90e.tar.bz2
rails-5f3cf4244de4fd62049d08df4e6bf63c945ab90e.zip
connection pool can cache column, table, and primary key information
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb34
-rw-r--r--activerecord/test/cases/connection_pool_test.rb35
2 files changed, 69 insertions, 0 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 54f70c59f8..bafd79d614 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -58,6 +58,7 @@ module ActiveRecord
# before giving up and raising a timeout error (default 5 seconds).
class ConnectionPool
attr_reader :spec, :connections
+ attr_reader :columns, :columns_hash, :primary_keys
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
# object which describes database connection information (e.g. adapter,
@@ -81,6 +82,39 @@ module ActiveRecord
@connections = []
@checked_out = []
+
+ @columns = Hash.new do |h, table_name|
+ h[table_name] = with_connection do |conn|
+ conn.columns(table_name, "#{table_name} Columns")
+ end
+ end
+
+ @columns_hash = Hash.new do |h, table_name|
+ h[table_name] = Hash[columns[table_name].map { |col|
+ [col.name, col]
+ }]
+ end
+
+ @primary_keys = Hash.new do |h, table_name|
+ h[table_name] = with_connection do |conn|
+ if conn.table_exists?(table_name)
+ conn.primary_key(table_name)
+ else
+ 'id'
+ end
+ end
+ end
+ end
+
+ # Clears out internal caches:
+ #
+ # * columns
+ # * columns_hash
+ # * primary_keys
+ def clear_cache!
+ @columns.clear
+ @columns_hash.clear
+ @primary_keys.clear
end
# Retrieve the connection associated with the current thread, or call
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 2e18117895..27fc3cab49 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -3,6 +3,41 @@ require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class ConnectionPoolTest < ActiveRecord::TestCase
+ def setup
+ # Keep a duplicate pool so we do not bother others
+ @pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
+ end
+
+ def test_pool_caches_columns
+ columns = @pool.columns['posts']
+ assert_equal columns, @pool.columns['posts']
+ end
+
+ def test_pool_caches_columns_hash
+ columns_hash = @pool.columns_hash['posts']
+ assert_equal columns_hash, @pool.columns_hash['posts']
+ end
+
+ def test_clearing_cache
+ @pool.columns['posts']
+ @pool.columns_hash['posts']
+ @pool.primary_keys['posts']
+
+ @pool.clear_cache!
+
+ assert_equal 0, @pool.columns.size
+ assert_equal 0, @pool.columns_hash.size
+ assert_equal 0, @pool.primary_keys.size
+ end
+
+ def test_primary_key
+ assert_equal 'id', @pool.primary_keys['posts']
+ end
+
+ def test_primary_key_for_non_existent_table
+ assert_equal 'id', @pool.primary_keys['omgponies']
+ end
+
def test_clear_stale_cached_connections!
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec