aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-09-06 16:47:34 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-09-06 16:47:34 -0700
commit54b7e783ef202d022a57dcdd54f7edf021c1df78 (patch)
treeb422ab3d93685c806f3b1405ffdf410c9d5b8dd4 /activerecord/lib
parenta4fa6eab396e703eb70b70ed708220a6405f2899 (diff)
downloadrails-54b7e783ef202d022a57dcdd54f7edf021c1df78.tar.gz
rails-54b7e783ef202d022a57dcdd54f7edf021c1df78.tar.bz2
rails-54b7e783ef202d022a57dcdd54f7edf021c1df78.zip
Database adapters use a statement pool.
Database adapters use a statement pool for limiting the number of open prepared statments on the database. The limit defaults to 1000, but can be adjusted in your database config by changing 'statement_limit'.
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb46
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb5
3 files changed, 46 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 8ecb3cefde..73e3afe1d5 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -120,7 +120,8 @@ module ActiveRecord
def initialize(connection, logger, connection_options, config)
super
- @statements = StatementPool.new(@connection)
+ @statements = StatementPool.new(@connection,
+ config.fetch(:statement_limit) { 1000 })
@client_encoding = nil
connect
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index ba4a6c7a78..a09bf9c73f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_support/core_ext/object/blank'
+require 'active_record/connection_adapters/statement_pool'
# Make sure we're using pg high enough for PGResult#values
gem 'pg', '~> 0.11'
@@ -246,6 +247,43 @@ module ActiveRecord
true
end
+ class StatementPool < ConnectionAdapters::StatementPool
+ def initialize(connection, max)
+ super
+ @counter = 0
+ @cache = {}
+ end
+
+ def each(&block); @cache.each(&block); end
+ def key?(key); @cache.key?(key); end
+ def [](key); @cache[key]; end
+ def length; @cache.length; end
+
+ def next_key
+ "a#{@counter + 1}"
+ end
+
+ def []=(sql, key)
+ while @max <= @cache.size
+ dealloc(@cache.shift.last)
+ end
+ @counter += 1
+ @cache[sql] = key
+ end
+
+ def clear
+ @cache.each_value do |stmt_key|
+ dealloc stmt_key
+ end
+ @cache.clear
+ end
+
+ private
+ def dealloc(key)
+ @connection.query "DEALLOCATE #{key}"
+ end
+ end
+
# Initializes and connects a PostgreSQL adapter.
def initialize(connection, logger, connection_parameters, config)
super(connection, logger)
@@ -254,9 +292,10 @@ module ActiveRecord
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
@local_tz = nil
@table_alias_length = nil
- @statements = {}
connect
+ @statements = StatementPool.new @connection,
+ config.fetch(:statement_limit) { 1000 }
if postgresql_version < 80200
raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
@@ -271,9 +310,6 @@ module ActiveRecord
# Clears the prepared statements cache.
def clear_cache!
- @statements.each_value do |value|
- @connection.query "DEALLOCATE #{value}"
- end
@statements.clear
end
@@ -996,7 +1032,7 @@ module ActiveRecord
def exec_cache(sql, binds)
unless @statements.key? sql
- nextkey = "a#{@statements.length + 1}"
+ nextkey = @statements.next_key
@connection.prepare nextkey, sql
@statements[sql] = nextkey
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index a4e21b714b..7c7e762c19 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -50,7 +50,7 @@ module ActiveRecord
end
class StatementPool < ConnectionAdapters::StatementPool
- def initialize(connection, max = 1000)
+ def initialize(connection, max)
super
@cache = {}
end
@@ -82,7 +82,8 @@ module ActiveRecord
def initialize(connection, logger, config)
super(connection, logger)
- @statements = StatementPool.new(@connection)
+ @statements = StatementPool.new(@connection,
+ config.fetch(:statement_limit) { 1000 })
@config = config
end