Skip to content

Commit

Permalink
Schema Cache: cache table indexes
Browse files Browse the repository at this point in the history
Useful to not query for indexes when an application uses schema cache.

Ref #35546
  • Loading branch information
kaspth committed Mar 9, 2019
1 parent f6ad0d8 commit 7737c3b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
26 changes: 18 additions & 8 deletions activerecord/lib/active_record/connection_adapters/schema_cache.rb
Expand Up @@ -13,6 +13,7 @@ def initialize(conn)
@columns_hash = {}
@primary_keys = {}
@data_sources = {}
@indexes = {}
end

def initialize_dup(other)
Expand All @@ -21,22 +22,25 @@ def initialize_dup(other)
@columns_hash = @columns_hash.dup
@primary_keys = @primary_keys.dup
@data_sources = @data_sources.dup
@indexes = @indexes.dup
end

def encode_with(coder)
coder["columns"] = @columns
coder["columns"] = @columns
coder["columns_hash"] = @columns_hash
coder["primary_keys"] = @primary_keys
coder["data_sources"] = @data_sources
coder["version"] = connection.migration_context.current_version
coder["indexes"] = @indexes
coder["version"] = connection.migration_context.current_version
end

def init_with(coder)
@columns = coder["columns"]
@columns = coder["columns"]
@columns_hash = coder["columns_hash"]
@primary_keys = coder["primary_keys"]
@data_sources = coder["data_sources"]
@version = coder["version"]
@indexes = coder["indexes"]
@version = coder["version"]
end

def primary_keys(table_name)
Expand All @@ -57,6 +61,7 @@ def add(table_name)
primary_keys(table_name)
columns(table_name)
columns_hash(table_name)
indexes(table_name)
end
end

Expand All @@ -82,17 +87,22 @@ def columns_hash?(table_name)
@columns_hash.key?(table_name)
end

def indexes(table_name)
@indexes[table_name] ||= connection.indexes(table_name)
end

# Clears out internal caches
def clear!
@columns.clear
@columns_hash.clear
@primary_keys.clear
@data_sources.clear
@indexes.clear
@version = nil
end

def size
[@columns, @columns_hash, @primary_keys, @data_sources].map(&:size).inject :+
[@columns, @columns_hash, @primary_keys, @data_sources, @indexes].map(&:size).inject :+
end

# Clear out internal caches for the data source +name+.
Expand All @@ -101,20 +111,20 @@ def clear_data_source_cache!(name)
@columns_hash.delete name
@primary_keys.delete name
@data_sources.delete name
@indexes.delete name
end

def marshal_dump
# if we get current version during initialization, it happens stack over flow.
@version = connection.migration_context.current_version
[@version, @columns, @columns_hash, @primary_keys, @data_sources]
[@version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes]
end

def marshal_load(array)
@version, @columns, @columns_hash, @primary_keys, @data_sources = array
@version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes = array
end

private

def prepare_data_sources
connection.data_sources.each { |source| @data_sources[source] = true }
end
Expand Down
15 changes: 14 additions & 1 deletion activerecord/test/cases/connection_adapters/schema_cache_test.rb
Expand Up @@ -19,13 +19,15 @@ def test_yaml_dump_and_load
@cache.columns_hash("posts")
@cache.data_sources("posts")
@cache.primary_keys("posts")
@cache.indexes("posts")

new_cache = YAML.load(YAML.dump(@cache))
assert_no_queries do
assert_equal 12, new_cache.columns("posts").size
assert_equal 12, new_cache.columns_hash("posts").size
assert new_cache.data_sources("posts")
assert_equal "id", new_cache.primary_keys("posts")
assert_equal 1, new_cache.indexes("posts").size
end
end

Expand All @@ -39,6 +41,10 @@ def test_yaml_loads_5_1_dump
assert cache.data_sources("posts")
assert_equal "id", cache.primary_keys("posts")
end

assert_queries 1 do
assert_equal 1, cache.indexes("posts")
end
end

def test_primary_key_for_non_existent_table
Expand All @@ -55,11 +61,17 @@ def test_caches_columns_hash
assert_equal columns_hash, @cache.columns_hash("posts")
end

def test_caches_indexes
indexes = @cache.indexes("posts")
assert_equal indexes, @cache.indexes("posts")
end

def test_clearing
@cache.columns("posts")
@cache.columns_hash("posts")
@cache.data_sources("posts")
@cache.primary_keys("posts")
@cache.indexes("posts")

@cache.clear!

Expand All @@ -71,6 +83,7 @@ def test_dump_and_load
@cache.columns_hash("posts")
@cache.data_sources("posts")
@cache.primary_keys("posts")
@cache.indexes("posts")

@cache = Marshal.load(Marshal.dump(@cache))

Expand All @@ -79,6 +92,7 @@ def test_dump_and_load
assert_equal 12, @cache.columns_hash("posts").size
assert @cache.data_sources("posts")
assert_equal "id", @cache.primary_keys("posts")
assert_equal 1, @cache.indexes("posts").size
end
end

Expand Down Expand Up @@ -108,7 +122,6 @@ def test_clear_data_source_cache
end

private

def schema_dump_path
"test/assets/schema_dump_5_1.yml"
end
Expand Down

0 comments on commit 7737c3b

Please sign in to comment.