relation_to_struct 1.11.0 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Appraisals +0 -1
- data/lib/relation_to_struct/active_record_connection_adapter_extension.rb +4 -4
- data/lib/relation_to_struct/version.rb +1 -1
- data/relation_to_struct.gemspec +1 -1
- data/spec/active_record_base_spec.rb +63 -0
- data/spec/active_record_connection_adapter_spec.rb +64 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1424d19f9ffa5b1ae51ec9fc827910e8ac97551d990d0d3d1050a056da2896f8
|
|
4
|
+
data.tar.gz: 47c097cae34a96dc068bf57f8f04c6094d2cf58c7c2f089e70bcbe8e4d8ac03f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 14f4a17a7b1961c8257ce9b7bdcc86f2365b58655411a3dfa550c4b3e206cf777fc43d35a21207ed0cf6cea5d3343e6b9a6583817fa2d871ea0fe278b55a565d
|
|
7
|
+
data.tar.gz: 6ec72d1363066eda7fbea68cc7e41ae51f5c3318b719464c8e62763485a7a5984c17f5ff38f85bf500a946a458a048b9812af25f9077fa7b4ccc675da59e428c
|
data/Appraisals
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module RelationToStruct::ActiveRecordConnectionAdapterExtension
|
|
2
2
|
def structs_from_sql(struct_class, sql, binds=[])
|
|
3
3
|
sanitized_sql = ActiveRecord::Base.sanitize_sql(sql)
|
|
4
|
-
result =
|
|
4
|
+
result = uncached do
|
|
5
5
|
select_all(sanitized_sql, "Structs SQL Load", binds)
|
|
6
6
|
end
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ module RelationToStruct::ActiveRecordConnectionAdapterExtension
|
|
|
26
26
|
|
|
27
27
|
def pluck_from_sql(sql, binds=[])
|
|
28
28
|
sanitized_sql = ActiveRecord::Base.sanitize_sql(sql)
|
|
29
|
-
result =
|
|
29
|
+
result = uncached do
|
|
30
30
|
select_all(sanitized_sql, "Pluck SQL Load", binds)
|
|
31
31
|
end
|
|
32
32
|
result.cast_values()
|
|
@@ -34,7 +34,7 @@ module RelationToStruct::ActiveRecordConnectionAdapterExtension
|
|
|
34
34
|
|
|
35
35
|
def value_from_sql(sql, binds=[])
|
|
36
36
|
sanitized_sql = ActiveRecord::Base.sanitize_sql(sql)
|
|
37
|
-
result =
|
|
37
|
+
result = uncached do
|
|
38
38
|
select_all(sanitized_sql, "Value SQL Load", binds)
|
|
39
39
|
end
|
|
40
40
|
raise ArgumentError, 'Expected exactly one column to be selected' unless result.columns.size == 1
|
|
@@ -52,7 +52,7 @@ module RelationToStruct::ActiveRecordConnectionAdapterExtension
|
|
|
52
52
|
|
|
53
53
|
def tuple_from_sql(sql, binds=[])
|
|
54
54
|
sanitized_sql = ActiveRecord::Base.sanitize_sql(sql)
|
|
55
|
-
result =
|
|
55
|
+
result = uncached do
|
|
56
56
|
select_all(sanitized_sql, "Value SQL Load", binds)
|
|
57
57
|
end
|
|
58
58
|
values = result.cast_values()
|
data/relation_to_struct.gemspec
CHANGED
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.add_development_dependency "appraisal", ">= 2.5"
|
|
22
22
|
spec.add_development_dependency "bundler", ">= 1.7"
|
|
23
23
|
spec.add_development_dependency "rake", ">= 10.0"
|
|
24
|
-
spec.add_development_dependency "sqlite3", ">= 1
|
|
24
|
+
spec.add_development_dependency "sqlite3", ">= 2.1"
|
|
25
25
|
spec.add_development_dependency "rspec", ">= 3.2"
|
|
26
26
|
spec.add_development_dependency "pry-byebug"
|
|
27
27
|
spec.add_development_dependency "pg"
|
|
@@ -6,6 +6,69 @@ describe ActiveRecord::Base do
|
|
|
6
6
|
EconomicSchool.delete_all
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
# A secondary connection pool simulates a sharded connection — one that belongs
|
|
10
|
+
# to a different pool than ActiveRecord::Base. The old implementation used
|
|
11
|
+
# ActiveRecord::Base.uncached, which only disables the cache on ActiveRecord::Base's
|
|
12
|
+
# pool and has no effect on secondary pools.
|
|
13
|
+
describe "with a subclass using a secondary connection pool" do
|
|
14
|
+
let(:secondary_class) do
|
|
15
|
+
klass = Class.new(ActiveRecord::Base) { self.abstract_class = true }
|
|
16
|
+
stub_const("SecondaryTestConnection", klass)
|
|
17
|
+
klass.establish_connection(ActiveRecord::Base.connection_db_config)
|
|
18
|
+
klass
|
|
19
|
+
end
|
|
20
|
+
after(:each) { secondary_class.remove_connection if secondary_class.connected? }
|
|
21
|
+
|
|
22
|
+
it 'pluck_from_sql bypasses the cache on a subclass using a different pool than ActiveRecord::Base' do
|
|
23
|
+
sql = "SELECT random()"
|
|
24
|
+
value_1 = value_2 = nil
|
|
25
|
+
|
|
26
|
+
secondary_class.cache do
|
|
27
|
+
value_1 = secondary_class.pluck_from_sql(sql)
|
|
28
|
+
value_2 = secondary_class.pluck_from_sql(sql)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
expect(value_1).not_to eq(value_2)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'value_from_sql bypasses the cache on a subclass using a different pool than ActiveRecord::Base' do
|
|
35
|
+
sql = "SELECT random()"
|
|
36
|
+
value_1 = value_2 = nil
|
|
37
|
+
|
|
38
|
+
secondary_class.cache do
|
|
39
|
+
value_1 = secondary_class.value_from_sql(sql)
|
|
40
|
+
value_2 = secondary_class.value_from_sql(sql)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
expect(value_1).not_to eq(value_2)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'tuple_from_sql bypasses the cache on a subclass using a different pool than ActiveRecord::Base' do
|
|
47
|
+
sql = "SELECT random()"
|
|
48
|
+
value_1 = value_2 = nil
|
|
49
|
+
|
|
50
|
+
secondary_class.cache do
|
|
51
|
+
value_1 = secondary_class.tuple_from_sql(sql)
|
|
52
|
+
value_2 = secondary_class.tuple_from_sql(sql)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
expect(value_1).not_to eq(value_2)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'structs_from_sql bypasses the cache on a subclass using a different pool than ActiveRecord::Base' do
|
|
59
|
+
test_struct = Struct.new(:r)
|
|
60
|
+
sql = "SELECT random() AS r"
|
|
61
|
+
value_1 = value_2 = nil
|
|
62
|
+
|
|
63
|
+
secondary_class.cache do
|
|
64
|
+
value_1 = secondary_class.structs_from_sql(test_struct, sql)
|
|
65
|
+
value_2 = secondary_class.structs_from_sql(test_struct, sql)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
expect(value_1).not_to eq(value_2)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
9
72
|
describe "#pluck_from_sql" do
|
|
10
73
|
it 'allows plucking with SQL directly' do
|
|
11
74
|
sql = "SELECT 1 * 23"
|
|
@@ -8,6 +8,70 @@ describe ActiveRecord::ConnectionAdapters::AbstractAdapter do
|
|
|
8
8
|
|
|
9
9
|
let(:connection) { ActiveRecord::Base.connection }
|
|
10
10
|
|
|
11
|
+
# A secondary connection pool simulates a sharded connection — one that belongs
|
|
12
|
+
# to a different pool than ActiveRecord::Base. The old implementation used
|
|
13
|
+
# ActiveRecord::Base.uncached, which only disables the cache on ActiveRecord::Base's
|
|
14
|
+
# pool and has no effect on secondary pools.
|
|
15
|
+
describe "with a secondary connection pool" do
|
|
16
|
+
let(:secondary_class) do
|
|
17
|
+
klass = Class.new(ActiveRecord::Base) { self.abstract_class = true }
|
|
18
|
+
stub_const("SecondaryTestConnection", klass)
|
|
19
|
+
klass.establish_connection(ActiveRecord::Base.connection_db_config)
|
|
20
|
+
klass
|
|
21
|
+
end
|
|
22
|
+
let(:secondary_connection) { secondary_class.connection }
|
|
23
|
+
after(:each) { secondary_class.remove_connection if secondary_class.connected? }
|
|
24
|
+
|
|
25
|
+
it 'pluck_from_sql bypasses the cache on a connection belonging to a different pool than ActiveRecord::Base' do
|
|
26
|
+
sql = "SELECT random()"
|
|
27
|
+
value_1 = value_2 = nil
|
|
28
|
+
|
|
29
|
+
secondary_class.cache do
|
|
30
|
+
value_1 = secondary_connection.pluck_from_sql(sql)
|
|
31
|
+
value_2 = secondary_connection.pluck_from_sql(sql)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
expect(value_1).not_to eq(value_2)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'value_from_sql bypasses the cache on a connection belonging to a different pool than ActiveRecord::Base' do
|
|
38
|
+
sql = "SELECT random()"
|
|
39
|
+
value_1 = value_2 = nil
|
|
40
|
+
|
|
41
|
+
secondary_class.cache do
|
|
42
|
+
value_1 = secondary_connection.value_from_sql(sql)
|
|
43
|
+
value_2 = secondary_connection.value_from_sql(sql)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
expect(value_1).not_to eq(value_2)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'tuple_from_sql bypasses the cache on a connection belonging to a different pool than ActiveRecord::Base' do
|
|
50
|
+
sql = "SELECT random()"
|
|
51
|
+
value_1 = value_2 = nil
|
|
52
|
+
|
|
53
|
+
secondary_class.cache do
|
|
54
|
+
value_1 = secondary_connection.tuple_from_sql(sql)
|
|
55
|
+
value_2 = secondary_connection.tuple_from_sql(sql)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
expect(value_1).not_to eq(value_2)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'structs_from_sql bypasses the cache on a connection belonging to a different pool than ActiveRecord::Base' do
|
|
62
|
+
test_struct = Struct.new(:r)
|
|
63
|
+
sql = "SELECT random() AS r"
|
|
64
|
+
value_1 = value_2 = nil
|
|
65
|
+
|
|
66
|
+
secondary_class.cache do
|
|
67
|
+
value_1 = secondary_connection.structs_from_sql(test_struct, sql)
|
|
68
|
+
value_2 = secondary_connection.structs_from_sql(test_struct, sql)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
expect(value_1).not_to eq(value_2)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
11
75
|
describe "#pluck_from_sql" do
|
|
12
76
|
it 'allows plucking with SQL directly' do
|
|
13
77
|
sql = "SELECT 1 * 23"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relation_to_struct
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.11.
|
|
4
|
+
version: 1.11.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Coleman
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-04-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: appraisal
|
|
@@ -58,14 +58,14 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1
|
|
61
|
+
version: '2.1'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1
|
|
68
|
+
version: '2.1'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rspec
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|