Skip to content

Commit 5f3cf42

Browse files
committed
connection pool can cache column, table, and primary key information
1 parent 78d23ed commit 5f3cf42

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ module ConnectionAdapters
5858
# before giving up and raising a timeout error (default 5 seconds).
5959
class ConnectionPool
6060
attr_reader :spec, :connections
61+
attr_reader :columns, :columns_hash, :primary_keys
6162

6263
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
6364
# object which describes database connection information (e.g. adapter,
@@ -81,6 +82,39 @@ def initialize(spec)
8182

8283
@connections = []
8384
@checked_out = []
85+
86+
@columns = Hash.new do |h, table_name|
87+
h[table_name] = with_connection do |conn|
88+
conn.columns(table_name, "#{table_name} Columns")
89+
end
90+
end
91+
92+
@columns_hash = Hash.new do |h, table_name|
93+
h[table_name] = Hash[columns[table_name].map { |col|
94+
[col.name, col]
95+
}]
96+
end
97+
98+
@primary_keys = Hash.new do |h, table_name|
99+
h[table_name] = with_connection do |conn|
100+
if conn.table_exists?(table_name)
101+
conn.primary_key(table_name)
102+
else
103+
'id'
104+
end
105+
end
106+
end
107+
end
108+
109+
# Clears out internal caches:
110+
#
111+
# * columns
112+
# * columns_hash
113+
# * primary_keys
114+
def clear_cache!
115+
@columns.clear
116+
@columns_hash.clear
117+
@primary_keys.clear
84118
end
85119

86120
# Retrieve the connection associated with the current thread, or call

activerecord/test/cases/connection_pool_test.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,41 @@
33
module ActiveRecord
44
module ConnectionAdapters
55
class ConnectionPoolTest < ActiveRecord::TestCase
6+
def setup
7+
# Keep a duplicate pool so we do not bother others
8+
@pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
9+
end
10+
11+
def test_pool_caches_columns
12+
columns = @pool.columns['posts']
13+
assert_equal columns, @pool.columns['posts']
14+
end
15+
16+
def test_pool_caches_columns_hash
17+
columns_hash = @pool.columns_hash['posts']
18+
assert_equal columns_hash, @pool.columns_hash['posts']
19+
end
20+
21+
def test_clearing_cache
22+
@pool.columns['posts']
23+
@pool.columns_hash['posts']
24+
@pool.primary_keys['posts']
25+
26+
@pool.clear_cache!
27+
28+
assert_equal 0, @pool.columns.size
29+
assert_equal 0, @pool.columns_hash.size
30+
assert_equal 0, @pool.primary_keys.size
31+
end
32+
33+
def test_primary_key
34+
assert_equal 'id', @pool.primary_keys['posts']
35+
end
36+
37+
def test_primary_key_for_non_existent_table
38+
assert_equal 'id', @pool.primary_keys['omgponies']
39+
end
40+
641
def test_clear_stale_cached_connections!
742
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
843

0 commit comments

Comments
 (0)