diff options
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/schema_cache.rb')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/schema_cache.rb | 92 |
1 files changed, 51 insertions, 41 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb index b14b37ce89..aad1f9a7ef 100644 --- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb @@ -1,71 +1,81 @@ module ActiveRecord module ConnectionAdapters class SchemaCache - attr_reader :columns, :columns_hash, :primary_keys, :tables - attr_reader :column_defaults - attr_reader :connection + attr_reader :columns, :columns_hash, :primary_keys, :tables, :version + attr_accessor :connection def initialize(conn) @connection = conn - @tables = {} - @columns = Hash.new do |h, table_name| - h[table_name] = - # Fetch a list of columns - conn.columns(table_name, "#{table_name} Columns").tap do |cs| - # set primary key information - cs.each do |column| - column.primary = column.name == primary_keys[table_name] - end - end - end - - @columns_hash = Hash.new do |h, table_name| - h[table_name] = Hash[columns[table_name].map { |col| - [col.name, col] - }] - end - - @column_defaults = Hash.new do |h, table_name| - h[table_name] = Hash[columns[table_name].map { |col| - [col.name, col.default] - }] - end - - @primary_keys = Hash.new do |h, table_name| - h[table_name] = table_exists?(table_name) ? - conn.primary_key(table_name) : 'id' - end + @columns = {} + @columns_hash = {} + @primary_keys = {} + @tables = {} + prepare_default_proc end # A cached lookup for table existence. def table_exists?(name) return @tables[name] if @tables.key? name - connection.tables.each { |table| @tables[table] = true } - @tables[name] = connection.table_exists?(name) if !@tables.key?(name) + @tables[name] = connection.table_exists?(name) + end - @tables[name] + # Add internal cache for table with +table_name+. + def add(table_name) + if table_exists?(table_name) + @primary_keys[table_name] + @columns[table_name] + @columns_hash[table_name] + end end - # Clears out internal caches: - # - # * columns - # * columns_hash - # * tables + # Clears out internal caches def clear! @columns.clear @columns_hash.clear - @column_defaults.clear + @primary_keys.clear @tables.clear + @version = nil end # Clear out internal caches for table with +table_name+. def clear_table_cache!(table_name) @columns.delete table_name @columns_hash.delete table_name - @column_defaults.delete table_name @primary_keys.delete table_name + @tables.delete table_name + end + + def marshal_dump + # if we get current version during initialization, it happens stack over flow. + @version = ActiveRecord::Migrator.current_version + [@version] + [:@columns, :@columns_hash, :@primary_keys, :@tables].map do |val| + self.instance_variable_get(val).inject({}) { |h, v| h[v[0]] = v[1]; h } + end + end + + def marshal_load(array) + @version, @columns, @columns_hash, @primary_keys, @tables = array + prepare_default_proc + end + + private + + def prepare_default_proc + @columns.default_proc = Proc.new do |h, table_name| + h[table_name] = connection.columns(table_name) + end + + @columns_hash.default_proc = Proc.new do |h, table_name| + h[table_name] = Hash[columns[table_name].map { |col| + [col.name, col] + }] + end + + @primary_keys.default_proc = Proc.new do |h, table_name| + h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil + end end end end |