blob: e9c512f94bb427899d0be471cc7363f7987ad262 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::PostgresqlAdapter::TypeMapCache do
let(:db_config) { ActiveRecord::Base.configurations.configs_for(env_name: 'test', name: 'primary').configuration_hash }
let(:adapter_class) { ActiveRecord::ConnectionAdapters::PostgreSQLAdapter }
before do
adapter_class.type_map_cache.clear
end
describe '#initialize_type_map' do
it 'caches loading of types in memory' do
recorder_without_cache = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection.disconnect! }
expect(recorder_without_cache.log).to include(a_string_matching(/FROM pg_type/)).twice
recorder_with_cache = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection.disconnect! }
expect(recorder_with_cache.count).to be < recorder_without_cache.count
# There's still one pg_type query left here because `#add_pg_decoders` executes another pg_type query
# in https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L912.
# This query is much cheaper because it only returns very few records.
expect(recorder_with_cache.log).to include(a_string_matching(/FROM pg_type/)).once
end
it 'only reuses the cache if the connection parameters are exactly the same' do
initialize_connection.disconnect!
other_config = db_config.dup
other_config[:connect_timeout] = db_config[:connect_timeout].to_i + 10
recorder = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection(other_config).disconnect! }
expect(recorder.log).to include(a_string_matching(/FROM pg_type/)).twice
end
end
describe '#reload_type_map' do
it 'clears the cache and executes the type map query again' do
initialize_connection.disconnect!
connection = initialize_connection
recorder = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { connection.reload_type_map }
expect(recorder.log).to include(a_string_matching(/FROM pg_type/)).once
end
end
# Based on https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L36-L41
def initialize_connection(config = db_config)
conn_params = config.symbolize_keys.compact
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
conn_params.slice!(*valid_conn_param_keys)
adapter_class.new(
adapter_class.new_client(conn_params),
ActiveRecord::Base.logger,
conn_params,
config
)
end
end
|