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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edca09028c07d1ab0d4ab816bfc93a36390ac574545fef7d820006e4fd0ed38c
4
- data.tar.gz: 5e2c2d6f609d1fa6830c9fb417069a6098b85e97cb01690e9c0c744ad019740f
3
+ metadata.gz: 1424d19f9ffa5b1ae51ec9fc827910e8ac97551d990d0d3d1050a056da2896f8
4
+ data.tar.gz: 47c097cae34a96dc068bf57f8f04c6094d2cf58c7c2f089e70bcbe8e4d8ac03f
5
5
  SHA512:
6
- metadata.gz: 23ec1e5f6bd14d59786574957add4c4bf8631f7f9bb429aa8429b7eb14aa719ba7f347cb88422ff78acb66fe92ed648e9c92c7b8d5f8f786986fc0832d693197
7
- data.tar.gz: 442e212d6c9c0e5b2035bc10afae91303124ebc1eaaae6f805032ac66d98c3ff7aa2142fab775d4ae2b3e67e551f95c6ad29a5d79c6aa4a9520efd601b7c0e56
6
+ metadata.gz: 14f4a17a7b1961c8257ce9b7bdcc86f2365b58655411a3dfa550c4b3e206cf777fc43d35a21207ed0cf6cea5d3343e6b9a6583817fa2d871ea0fe278b55a565d
7
+ data.tar.gz: 6ec72d1363066eda7fbea68cc7e41ae51f5c3318b719464c8e62763485a7a5984c17f5ff38f85bf500a946a458a048b9812af25f9077fa7b4ccc675da59e428c
data/Appraisals CHANGED
@@ -1,6 +1,5 @@
1
1
  %w(7.2 8.0 8.1).each do |version|
2
2
  appraise "rails-#{version.gsub(/\./, "-")}" do
3
3
  gem "rails", "~> #{version}.0"
4
- gem "sqlite3", "~> 1.4"
5
4
  end
6
5
  end
@@ -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 = ActiveRecord::Base.uncached do
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 = ActiveRecord::Base.uncached do
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 = ActiveRecord::Base.uncached do
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 = ActiveRecord::Base.uncached do
55
+ result = uncached do
56
56
  select_all(sanitized_sql, "Value SQL Load", binds)
57
57
  end
58
58
  values = result.cast_values()
@@ -1,3 +1,3 @@
1
1
  module RelationToStruct
2
- VERSION = "1.11.0"
2
+ VERSION = "1.11.1"
3
3
  end
@@ -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.4"
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.0
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: 2025-10-26 00:00:00.000000000 Z
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.4'
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.4'
68
+ version: '2.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement