Permalink
Browse files

adding a statement pool for mysql and sqlite3

  • Loading branch information...
tenderlove committed Sep 6, 2011
1 parent 699b83a commit b37112ff2e9b165e1081440dcff9869c24e74acb
@@ -2,6 +2,7 @@
require 'active_support/core_ext/kernel/requires'
require 'active_support/core_ext/object/blank'
require 'set'
+require 'active_record/connection_adapters/statement_pool'
gem 'mysql', '~> 2.8.1'
require 'mysql'
@@ -184,11 +185,39 @@ class MysqlAdapter < AbstractAdapter
:boolean => { :name => "tinyint", :limit => 1 }
}
+ class StatementPool < ConnectionAdapters::StatementPool
+ def initialize(connection, max = 1000)
+ super
+ @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 delete(key); @cache.delete(key); end
+
+ def []=(sql, key)
+ while @max <= @cache.size
+ @cache.shift.last[:stmt].close
+ end
+ @cache[sql] = key
+ end
+
+ def clear
+ @cache.values.each do |hash|
+ hash[:stmt].close
+ end
+ @cache.clear
+ end
+ end
+
def initialize(connection, logger, connection_options, config)
super(connection, logger)
@connection_options, @config = connection_options, config
@quoted_column_names, @quoted_table_names = {}, {}
@statements = {}
+ @statements = StatementPool.new(@connection)
@client_encoding = nil
connect
end
@@ -334,9 +363,6 @@ def select_rows(sql, name = nil)
# Clears the prepared statements cache.
def clear_cache!
- @statements.values.each do |cache|
- cache[:stmt].close
- end
@statements.clear
end
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_support/core_ext/kernel/requires'
+require 'active_record/connection_adapters/statement_pool'
require 'active_support/core_ext/string/encoding'
module ActiveRecord
@@ -49,9 +50,40 @@ def <=>(version_string)
end
end
+ class StatementPool < ConnectionAdapters::StatementPool
+ def initialize(connection, max = 1000)
+ super
+ @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 []=(sql, key)
+ while @max <= @cache.size
+ dealloc(@cache.shift.last[:stmt])
+ end
+ @cache[sql] = key
+ end
+
+ def clear
+ @cache.values.each do |hash|
+ dealloc hash[:stmt]
+ end
+ @cache.clear
+ end
+
+ private
+ def dealloc(stmt)
+ stmt.close unless stmt.closed?
+ end
+ end
+
def initialize(connection, logger, config)
super(connection, logger)
- @statements = {}
+ @statements = StatementPool.new(@connection)
@config = config
end
@@ -108,7 +140,6 @@ def disconnect!
# Clears the prepared statements cache.
def clear_cache!
- @statements.values.each { |hash| hash[:stmt].close }
@statements.clear
end
@@ -0,0 +1,40 @@
+module ActiveRecord
+ module ConnectionAdapters
+ class StatementPool
+ include Enumerable
+
+ def initialize(connection, max = 1000)
+ @connection = connection
+ @max = max
+ end
+
+ def each
+ raise NotImplementedError
+ end
+
+ def key?(key)
+ raise NotImplementedError
+ end
+
+ def [](key)
+ raise NotImplementedError
+ end
+
+ def length
+ raise NotImplementedError
+ end
+
+ def []=(sql, key)
+ raise NotImplementedError
+ end
+
+ def clear
+ raise NotImplementedError
+ end
+
+ def delete(key)
+ raise NotImplementedError
+ end
+ end
+ end
+end

0 comments on commit b37112f

Please sign in to comment.