torque-postgresql 3.0.0 → 3.0.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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc0fe29b7ec2c1478b6718efaddbb7ba2be2c6fd18dc56dc5e52ca52575811dd
|
4
|
+
data.tar.gz: b1f7c28054bb9ed68ebc2506ca71cb0d4c42563102438f39202d638278d45ee9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a13fa4357d31fed2106ebcef94ff51decb7003e30a1f0a2fe5af83ceb3d18cc7d909fcf1c6f65ea63c7c11eccb1e312d7c85ff66d16125d50bd10b1e1772ab14
|
7
|
+
data.tar.gz: 7f2a2951c337e2326ad0c808423f6017b11086538a8bcd0b40078729e26b02232f7b97c39de96ab70e81c5eac5382ce7f0aff9965e4fbd36571b4b89bcdcbcab
|
@@ -40,34 +40,29 @@ module Torque
|
|
40
40
|
result
|
41
41
|
end
|
42
42
|
|
43
|
-
# Build the id constraint checking if both types are perfect matching
|
43
|
+
# Build the id constraint checking if both types are perfect matching.
|
44
|
+
# The klass attribute (left side) will always be a column attribute
|
44
45
|
def build_id_constraint(klass_attr, source_attr)
|
45
46
|
return klass_attr.eq(source_attr) unless connected_through_array?
|
46
47
|
|
47
48
|
# Klass and key are associated with the reflection Class
|
48
|
-
klass_type = klass.columns_hash[
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
klass_type = klass.columns_hash[join_keys.key.to_s]
|
50
|
+
|
51
|
+
# Apply an ANY operation which checks if the single value on the left
|
52
|
+
# side exists in the array on the right side
|
53
|
+
if source_attr.is_a?(AREL_ATTR)
|
54
|
+
any_value = [klass_attr, source_attr]
|
55
|
+
any_value.reverse! if klass_type.try(:array?)
|
56
|
+
return any_value.shift.eq(::Arel::Nodes::NamedFunction.new('ANY', any_value))
|
57
|
+
end
|
56
58
|
|
57
59
|
# If the left side is not an array, just use the IN condition
|
58
60
|
return klass_attr.in(source_attr) unless klass_type.try(:array)
|
59
61
|
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# Apply necessary transformations to values
|
66
|
-
klass_attr = cast_constraint_to_array(klass_type, klass_attr, should_cast)
|
67
|
-
source_attr = cast_constraint_to_array(source_type, source_attr, should_cast)
|
68
|
-
|
69
|
-
# Return the overlap condition
|
70
|
-
klass_attr.overlaps(source_attr)
|
62
|
+
# Build the overlap condition (array && array) ensuring that the right
|
63
|
+
# side has the same type as the left side
|
64
|
+
source_attr = ::Arel::Nodes.build_quoted(Array.wrap(source_attr))
|
65
|
+
klass_attr.overlaps(source_attr.cast(klass_type.sql_type_metadata.sql_type))
|
71
66
|
end
|
72
67
|
|
73
68
|
# TODO: Deprecate this method
|
@@ -83,24 +78,6 @@ module Torque
|
|
83
78
|
|
84
79
|
build_id_constraint(klass_attr, source_attr)
|
85
80
|
end
|
86
|
-
|
87
|
-
# Prepare a value for an array constraint overlap condition
|
88
|
-
def cast_constraint_to_array(type, value, should_cast)
|
89
|
-
base_ready = type.try(:array) && value.is_a?(AREL_ATTR)
|
90
|
-
return value if base_ready && (type.sql_type.eql?(ARR_NO_CAST) || !should_cast)
|
91
|
-
|
92
|
-
value = ::Arel::Nodes.build_quoted(Array.wrap(value)) unless base_ready
|
93
|
-
value = value.cast(ARR_CAST) if should_cast
|
94
|
-
value
|
95
|
-
end
|
96
|
-
|
97
|
-
# Check if it's possible to turn both attributes into an ANY condition
|
98
|
-
def arel_array_to_any(klass_attr, source_attr, klass_type, source_type)
|
99
|
-
return unless !klass_type.try(:array) && source_type.try(:array) &&
|
100
|
-
klass_attr.is_a?(AREL_ATTR) && source_attr.is_a?(AREL_ATTR)
|
101
|
-
|
102
|
-
::Arel::Nodes::NamedFunction.new('ANY', [source_attr])
|
103
|
-
end
|
104
81
|
end
|
105
82
|
|
106
83
|
::ActiveRecord::Reflection::AbstractReflection.prepend(AbstractReflection)
|
data/spec/spec_helper.rb
CHANGED
@@ -393,4 +393,51 @@ RSpec.describe 'BelongsToMany' do
|
|
393
393
|
end
|
394
394
|
end
|
395
395
|
end
|
396
|
+
|
397
|
+
context 'using uuid' do
|
398
|
+
let(:connection) { ActiveRecord::Base.connection }
|
399
|
+
let(:game) { Class.new(ActiveRecord::Base) }
|
400
|
+
let(:player) { Class.new(ActiveRecord::Base) }
|
401
|
+
let(:other) { player.create }
|
402
|
+
|
403
|
+
# TODO: Set as a shred example
|
404
|
+
before do
|
405
|
+
connection.create_table(:players, id: :uuid) { |t| t.string :name }
|
406
|
+
connection.create_table(:games, id: :uuid) { |t| t.uuid :player_ids, array: true }
|
407
|
+
|
408
|
+
game.table_name = 'games'
|
409
|
+
player.table_name = 'players'
|
410
|
+
game.belongs_to_many :players, anonymous_class: player,
|
411
|
+
inverse_of: false, foreign_key: :player_ids
|
412
|
+
end
|
413
|
+
|
414
|
+
subject { game.create }
|
415
|
+
|
416
|
+
it 'loads associated records' do
|
417
|
+
subject.update(player_ids: [other.id])
|
418
|
+
expect(subject.players.to_sql).to be_eql(<<-SQL.squish)
|
419
|
+
SELECT "players".* FROM "players" WHERE "players"."id" IN ('#{other.id}')
|
420
|
+
SQL
|
421
|
+
|
422
|
+
expect(subject.players.load).to be_a(ActiveRecord::Associations::CollectionProxy)
|
423
|
+
expect(subject.players.to_a).to be_eql([other])
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'can preload records' do
|
427
|
+
records = 5.times.map { player.create }
|
428
|
+
subject.players.concat(records)
|
429
|
+
|
430
|
+
entries = game.all.includes(:players).load
|
431
|
+
|
432
|
+
expect(entries.size).to be_eql(1)
|
433
|
+
expect(entries.first.players).to be_loaded
|
434
|
+
expect(entries.first.players.size).to be_eql(5)
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'can joins records' do
|
438
|
+
query = game.all.joins(:players)
|
439
|
+
expect(query.to_sql).to match(/INNER JOIN "players"/)
|
440
|
+
expect { query.load }.not_to raise_error
|
441
|
+
end
|
442
|
+
end
|
396
443
|
end
|
data/spec/tests/has_many_spec.rb
CHANGED
@@ -411,4 +411,48 @@ RSpec.describe 'HasMany' do
|
|
411
411
|
expect { query.load }.not_to raise_error
|
412
412
|
end
|
413
413
|
end
|
414
|
+
|
415
|
+
context 'using uuid' do
|
416
|
+
let(:connection) { ActiveRecord::Base.connection }
|
417
|
+
let(:game) { Class.new(ActiveRecord::Base) }
|
418
|
+
let(:player) { Class.new(ActiveRecord::Base) }
|
419
|
+
|
420
|
+
# TODO: Set as a shred example
|
421
|
+
before do
|
422
|
+
connection.create_table(:players, id: :uuid) { |t| t.string :name }
|
423
|
+
connection.create_table(:games, id: :uuid) { |t| t.uuid :player_ids, array: true }
|
424
|
+
|
425
|
+
game.table_name = 'games'
|
426
|
+
player.table_name = 'players'
|
427
|
+
player.has_many :games, array: true, anonymous_class: game,
|
428
|
+
inverse_of: false, foreign_key: :player_ids
|
429
|
+
end
|
430
|
+
|
431
|
+
subject { player.create }
|
432
|
+
|
433
|
+
it 'loads associated records' do
|
434
|
+
expect(subject.games.to_sql).to match(Regexp.new(<<-SQL.squish))
|
435
|
+
SELECT "games"\\.\\* FROM "games"
|
436
|
+
WHERE \\(?"games"\\."player_ids" && ARRAY\\['#{subject.id}'\\]::uuid\\[\\]\\)?
|
437
|
+
SQL
|
438
|
+
|
439
|
+
expect(subject.games.load).to be_a(ActiveRecord::Associations::CollectionProxy)
|
440
|
+
expect(subject.games.to_a).to be_eql([])
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'can preload records' do
|
444
|
+
5.times { game.create(player_ids: [subject.id]) }
|
445
|
+
entries = player.all.includes(:games).load
|
446
|
+
|
447
|
+
expect(entries.size).to be_eql(1)
|
448
|
+
expect(entries.first.games).to be_loaded
|
449
|
+
expect(entries.first.games.size).to be_eql(5)
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'can joins records' do
|
453
|
+
query = player.all.joins(:games)
|
454
|
+
expect(query.to_sql).to match(/INNER JOIN "games"/)
|
455
|
+
expect { query.load }.not_to raise_error
|
456
|
+
end
|
457
|
+
end
|
414
458
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: torque-postgresql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|