-
Notifications
You must be signed in to change notification settings - Fork 21.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TypeMap (PG): Store Typemap in Schema Cache and use another cache cla…
…ss to keep it in memory
- Loading branch information
Showing
10 changed files
with
280 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
activerecord/lib/active_record/connection_adapters/postgresql/schema_cache.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# frozen_string_literal: true | ||
|
||
module ActiveRecord | ||
module ConnectionAdapters | ||
module PostgreSQL | ||
class SchemaCache < ActiveRecord::ConnectionAdapters::SchemaCache | ||
attr_accessor :additional_type_records, :known_coder_type_records | ||
|
||
def initialize(conn) | ||
super(conn) | ||
|
||
@additional_type_records = PostgreSQL::TypeMapCache.instance.additional_type_records || [] | ||
@known_coder_type_records = PostgreSQL::TypeMapCache.instance.known_coder_type_records || [] | ||
end | ||
|
||
def encode_with(coder) | ||
super | ||
|
||
coder["additional_type_records"] = @additional_type_records | ||
coder["known_coder_type_records"] = @known_coder_type_records | ||
end | ||
|
||
def init_with(coder) | ||
@additional_type_records = coder["additional_type_records"] | ||
@known_coder_type_records = coder["known_coder_type_records"] | ||
|
||
super | ||
end | ||
|
||
def marshal_dump | ||
reset_version! | ||
|
||
[@version, @columns, {}, @primary_keys, @data_sources, @indexes, database_version, @known_coder_type_records, @additional_type_records] | ||
end | ||
|
||
def marshal_load(array) | ||
@version, @columns, _columns_hash, @primary_keys, @data_sources, @indexes, @database_version, @known_coder_type_records, @additional_type_records = array | ||
@indexes ||= {} | ||
|
||
derive_columns_hash_and_deduplicate_values | ||
end | ||
end | ||
end | ||
end | ||
end |
34 changes: 34 additions & 0 deletions
34
activerecord/lib/active_record/connection_adapters/postgresql/type_map_cache.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# frozen_string_literal: true | ||
|
||
module ActiveRecord | ||
# :stopdoc: | ||
module ConnectionAdapters | ||
module PostgreSQL | ||
class TypeMapCache | ||
include Singleton | ||
|
||
attr_accessor :additional_type_records | ||
attr_accessor :known_coder_type_records | ||
|
||
def initialize | ||
@additional_type_records = [] | ||
@known_coder_type_records = [] | ||
end | ||
|
||
class << self | ||
def init(schema_cache) | ||
return if schema_cache.nil? || !schema_cache.is_a?(PostgreSQL::SchemaCache) | ||
|
||
self.instance.known_coder_type_records = schema_cache.known_coder_type_records | ||
self.instance.additional_type_records = schema_cache.additional_type_records | ||
end | ||
|
||
def clear | ||
self.instance.additional_type_records = [] | ||
self.instance.known_coder_type_records = [] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
activerecord/test/cases/connection_adapters/postgresql/schema_cache_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# frozen_string_literal: true | ||
|
||
require "cases/helper" | ||
|
||
module ActiveRecord | ||
module ConnectionAdapters | ||
module PostgreSQL | ||
class SchemaCacheTest < ActiveRecord::TestCase | ||
if current_adapter?(:PostgreSQLAdapter) | ||
def setup | ||
@connection = ActiveRecord::Base.connection | ||
end | ||
|
||
def test_type_map_existence_in_schema_cache | ||
assert_not(@connection.schema_cache.additional_type_records.empty?) | ||
assert_not(@connection.schema_cache.known_coder_type_records.empty?) | ||
end | ||
|
||
def test_type_map_queries_when_initialize_connection | ||
db_config = ActiveRecord::Base.configurations.configs_for( | ||
env_name: "arunit", | ||
name: "primary" | ||
) | ||
|
||
assert_no_sql("SELECT t.oid, t.typname") do | ||
ActiveRecord::Base.postgresql_connection(db_config.configuration_hash) | ||
end | ||
end | ||
|
||
def test_type_map_cache_with_lazy_load_option | ||
PostgreSQL::TypeMapCache.clear | ||
tempfile = Tempfile.new(["schema_cache-", ".yml"]) | ||
|
||
original_config = ActiveRecord::Base.connection_db_config | ||
new_config = original_config.configuration_hash.merge(schema_cache_path: tempfile.path) | ||
|
||
ActiveRecord::Base.establish_connection(new_config) | ||
|
||
assert_not_empty(PostgreSQL::TypeMapCache.instance.additional_type_records) | ||
assert_not_empty(PostgreSQL::TypeMapCache.instance.known_coder_type_records) | ||
|
||
assert_not_empty(ActiveRecord::Base.connection.schema_cache.instance_variable_get(:@known_coder_type_records)) | ||
assert_not_empty(ActiveRecord::Base.connection.schema_cache.instance_variable_get(:@additional_type_records)) | ||
|
||
cache = PostgreSQL::SchemaCache.new(ActiveRecord::Base.connection) | ||
|
||
cache.dump_to(tempfile.path) | ||
ActiveRecord::Base.connection.schema_cache = cache | ||
|
||
assert(File.exist?(tempfile)) | ||
|
||
ActiveRecord.lazily_load_schema_cache = true | ||
|
||
PostgreSQL::TypeMapCache.clear | ||
|
||
assert_sql(/SELECT t.oid, t.typname/) do | ||
ActiveRecord::Base.establish_connection(new_config) | ||
end | ||
end | ||
|
||
def test_type_map_queries_with_custom_types | ||
cache = SchemaCache.new(@connection) | ||
tempfile = Tempfile.new(["schema_cache-", ".yml"]) | ||
|
||
assert_no_sql("SELECT t.oid, t.typname") do | ||
cache.dump_to(tempfile.path) | ||
end | ||
|
||
cache = SchemaCache.load_from(tempfile.path) | ||
cache.connection = @connection | ||
|
||
assert_sql(/SELECT t.oid, t.typname, t.typelem/) do | ||
@connection.execute("CREATE TYPE account_status AS ENUM ('new', 'open', 'closed');") | ||
@connection.execute("ALTER TABLE accounts ADD status account_status NOT NULL DEFAULT 'new';") | ||
cache.dump_to(tempfile.path) | ||
end | ||
ensure | ||
@connection.execute("DELETE FROM accounts; ALTER TABLE accounts DROP COLUMN status;DROP TYPE IF EXISTS account_status;") | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
40 changes: 40 additions & 0 deletions
40
activerecord/test/cases/connection_adapters/postgresql/type_map_cache_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# frozen_string_literal: true | ||
|
||
require "cases/helper" | ||
|
||
module ActiveRecord | ||
module ConnectionAdapters | ||
module PostgreSQL | ||
class TypeMapCacheTest < ActiveRecord::TestCase | ||
if current_adapter?(:PostgreSQLAdapter) | ||
def setup | ||
@connection = ActiveRecord::Base.connection | ||
@type_map_cache = TypeMapCache.instance | ||
end | ||
|
||
def test_type_map_cache_init_with_schema_cache | ||
assert(@type_map_cache.additional_type_records.empty?) | ||
assert(@type_map_cache.known_coder_type_records.empty?) | ||
|
||
TypeMapCache.init(@connection.schema_cache) | ||
|
||
assert_not(@type_map_cache.additional_type_records.empty?) | ||
assert_not(@type_map_cache.known_coder_type_records.empty?) | ||
end | ||
|
||
def test_type_map_cache_clear | ||
TypeMapCache.init(@connection.schema_cache) | ||
|
||
assert_not(@type_map_cache.additional_type_records.empty?) | ||
assert_not(@type_map_cache.known_coder_type_records.empty?) | ||
|
||
TypeMapCache.clear | ||
|
||
assert(@type_map_cache.additional_type_records.empty?) | ||
assert(@type_map_cache.known_coder_type_records.empty?) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.