torque-postgresql 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4fac19ef8680f477df0f79502331ddda06266658a54c8128321d68145a9f18b
4
- data.tar.gz: 0e93ec49f80d40ec9ce9b7fcc5ef0eff65a882cad79a63e5429657ad9c66691b
3
+ metadata.gz: dc0fe29b7ec2c1478b6718efaddbb7ba2be2c6fd18dc56dc5e52ca52575811dd
4
+ data.tar.gz: b1f7c28054bb9ed68ebc2506ca71cb0d4c42563102438f39202d638278d45ee9
5
5
  SHA512:
6
- metadata.gz: 4a9abd492b544296c29e0949e1ad0ad4852a1ed0c48379551e5ffbbaad7018579cad994ac2a841231603bdddd8da4b448d7771a9086312289f818124d842d6a6
7
- data.tar.gz: 8019255d20eff471ed177078e1bd6042a0a9b95752d32578bdb8ce86afdf9cffbefa8ed181caab0143f0dbbf80cfc39c99fd005cfc2b28089687b26a635268ef
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[join_primary_key.to_s]
49
- # active_record and foreign_key are associated with the source Class
50
- source_type = active_record.columns_hash[join_foreign_key.to_s]
51
-
52
- # If both are attributes but the left side is not an array, and the
53
- # right side is, use the ANY operation
54
- any_operation = arel_array_to_any(klass_attr, source_attr, klass_type, source_type)
55
- return klass_attr.eq(any_operation) if any_operation
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
- # Decide if should apply a cast to ensure same type comparision
61
- should_cast = klass_type.type.eql?(:integer) && source_type.type.eql?(:integer)
62
- should_cast &= !klass_type.sql_type.eql?(source_type.sql_type)
63
- should_cast |= !(klass_attr.is_a?(AREL_ATTR) && source_attr.is_a?(AREL_ATTR))
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)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Torque
4
4
  module PostgreSQL
5
- VERSION = '3.0.0'
5
+ VERSION = '3.0.1'
6
6
  end
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -39,6 +39,7 @@ RSpec.configure do |config|
39
39
 
40
40
  # Handles acton before rspec initialize
41
41
  config.before(:suite) do
42
+ ActiveSupport::Deprecation.silenced = true
42
43
  DatabaseCleaner.clean_with(:truncation)
43
44
  end
44
45
 
@@ -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
@@ -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.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-04 00:00:00.000000000 Z
11
+ date: 2022-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails