torque-postgresql 2.2.1 → 3.0.0

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/torque/postgresql/adapter/database_statements.rb +12 -1
  3. data/lib/torque/postgresql/adapter/oid/enum_set.rb +1 -1
  4. data/lib/torque/postgresql/adapter/oid.rb +0 -3
  5. data/lib/torque/postgresql/adapter/quoting.rb +14 -19
  6. data/lib/torque/postgresql/adapter/schema_creation.rb +1 -2
  7. data/lib/torque/postgresql/adapter/schema_definitions.rb +0 -37
  8. data/lib/torque/postgresql/adapter/schema_dumper.rb +0 -40
  9. data/lib/torque/postgresql/adapter/schema_statements.rb +0 -15
  10. data/lib/torque/postgresql/adapter.rb +0 -9
  11. data/lib/torque/postgresql/associations/belongs_to_many_association.rb +5 -3
  12. data/lib/torque/postgresql/associations/{association.rb → foreign_association.rb} +1 -4
  13. data/lib/torque/postgresql/associations/preloader/association.rb +53 -26
  14. data/lib/torque/postgresql/associations/preloader/loader_query.rb +36 -0
  15. data/lib/torque/postgresql/associations/preloader.rb +1 -0
  16. data/lib/torque/postgresql/associations.rb +6 -1
  17. data/lib/torque/postgresql/attributes/builder/period.rb +6 -2
  18. data/lib/torque/postgresql/config.rb +2 -11
  19. data/lib/torque/postgresql/reflection/abstract_reflection.rb +5 -7
  20. data/lib/torque/postgresql/relation.rb +10 -12
  21. data/lib/torque/postgresql/schema_cache.rb +2 -1
  22. data/lib/torque/postgresql/version.rb +1 -1
  23. data/lib/torque-postgresql.rb +0 -1
  24. data/spec/models/question_select.rb +2 -0
  25. data/spec/schema.rb +147 -147
  26. data/spec/spec_helper.rb +7 -6
  27. data/spec/tests/arel_spec.rb +29 -7
  28. data/spec/tests/belongs_to_many_spec.rb +14 -0
  29. data/spec/tests/enum_set_spec.rb +7 -5
  30. data/spec/tests/enum_spec.rb +1 -84
  31. data/spec/tests/interval_spec.rb +2 -1
  32. metadata +49 -57
  33. data/lib/torque/range.rb +0 -20
  34. data/spec/tests/range_spec.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcb69118c9cca1afe5ef21a9ed9b4cf98e9036108b739707a1e7f65058aaaf84
4
- data.tar.gz: d7ca85705f802c0d15c0aabca99a9ec17b8403e60e912724b609d8b93cd7bd86
3
+ metadata.gz: d4fac19ef8680f477df0f79502331ddda06266658a54c8128321d68145a9f18b
4
+ data.tar.gz: 0e93ec49f80d40ec9ce9b7fcc5ef0eff65a882cad79a63e5429657ad9c66691b
5
5
  SHA512:
6
- metadata.gz: 0a48ed549030276f9a3e4c845454eb89cf97b8d0bf3d00cd5431abd85a7317f6031e4f997e86ae3657012ca9d4578598d612a14c531247575f1d0496bc629f6e
7
- data.tar.gz: 50a1817ef37c0c8d98a71b92500a73b420f5dc27cf9d19afc6aeb8492e3d4582b69ee9ada91b281699987cc4bb33a9d1df584219073d432299ebad53a4a29513
6
+ metadata.gz: 4a9abd492b544296c29e0949e1ad0ad4852a1ed0c48379551e5ffbbaad7018579cad994ac2a841231603bdddd8da4b448d7771a9086312289f818124d842d6a6
7
+ data.tar.gz: 8019255d20eff471ed177078e1bd6042a0a9b95752d32578bdb8ce86afdf9cffbefa8ed181caab0143f0dbbf80cfc39c99fd005cfc2b28089687b26a635268ef
@@ -34,6 +34,15 @@ module Torque
34
34
  execute("SET SESSION IntervalStyle TO 'iso_8601'", 'SCHEMA')
35
35
  end
36
36
 
37
+ # Since enums create new types, type map needs to be rebooted to include
38
+ # the new ones, both normal and array one
39
+ def create_enum(name, *)
40
+ super
41
+
42
+ oid = query_value("SELECT #{quote(name)}::regtype::oid", "SCHEMA").to_i
43
+ load_additional_types([oid])
44
+ end
45
+
37
46
  # Change some of the types being mapped
38
47
  def initialize_type_map(m = type_map)
39
48
  super
@@ -54,7 +63,7 @@ module Torque
54
63
 
55
64
  # Add the composite types to be loaded too.
56
65
  def torque_load_additional_types(oids = nil)
57
- filter = "AND a.typelem::integer IN (%s)" % oids.join(", ") if oids
66
+ filter = ("AND a.typelem::integer IN (%s)" % oids.join(', ')) if oids
58
67
 
59
68
  query = <<-SQL
60
69
  SELECT a.typelem AS oid, t.typname, t.typelem,
@@ -132,7 +141,9 @@ module Torque
132
141
  # Get the list of columns, and their definition, but only from the
133
142
  # actual table, does not include columns that comes from inherited table
134
143
  def column_definitions(table_name) # :nodoc:
144
+ # Only affects inheritance
135
145
  local_condition = 'AND a.attislocal IS TRUE' if @_dump_mode
146
+
136
147
  query(<<-SQL, 'SCHEMA')
137
148
  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
138
149
  pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
@@ -14,7 +14,7 @@ module Torque
14
14
  end
15
15
 
16
16
  def type
17
- :enum_set
17
+ :enum
18
18
  end
19
19
 
20
20
  def deserialize(value)
@@ -19,9 +19,6 @@ module Torque
19
19
  ActiveRecord::Type.register(:enum_set, OID::EnumSet, adapter: :postgresql)
20
20
  ActiveRecord::Type.register(:line, OID::Line, adapter: :postgresql)
21
21
  ActiveRecord::Type.register(:segment, OID::Segment, adapter: :postgresql)
22
-
23
- ActiveRecord::Type.register(:interval, OID::Interval, adapter: :postgresql) \
24
- unless PostgreSQL::AR610
25
22
  end
26
23
  end
27
24
  end
@@ -6,6 +6,8 @@ module Torque
6
6
  module Quoting
7
7
 
8
8
  Name = ActiveRecord::ConnectionAdapters::PostgreSQL::Name
9
+ Column = ActiveRecord::ConnectionAdapters::PostgreSQL::Column
10
+ ColumnDefinition = ActiveRecord::ConnectionAdapters::ColumnDefinition
9
11
 
10
12
  # Quotes type names for use in SQL queries.
11
13
  def quote_type_name(string, schema = nil)
@@ -20,26 +22,19 @@ module Torque
20
22
  end
21
23
 
22
24
  def quote_default_expression(value, column)
23
- if column.options.try(:[], :array) && value.class <= Array
24
- quote(value) + '::' + column.sql_type
25
- else
26
- super
27
- end
25
+ return super unless value.class <= Array || value.class <= Set
26
+
27
+ type =
28
+ if column.is_a?(ColumnDefinition) && column.options.try(:[], :array)
29
+ # This is the general way
30
+ lookup_cast_type(column.sql_type)
31
+ elsif column.is_a?(Column) && column.array?
32
+ # When using +change_column_default+
33
+ lookup_cast_type_from_column(column)
34
+ end
35
+
36
+ type.nil? ? super : quote(type.serialize(value.to_a))
28
37
  end
29
-
30
- private
31
-
32
- def _quote(value)
33
- return super unless value.is_a?(Array)
34
-
35
- values = value.map(&method(:quote))
36
- "ARRAY[#{values.join(','.freeze)}]"
37
- end
38
-
39
- def _type_cast(value)
40
- return super unless value.is_a?(Array)
41
- value.map(&method(:quote)).join(','.freeze)
42
- end
43
38
  end
44
39
  end
45
40
  end
@@ -33,8 +33,7 @@ module Torque
33
33
  create_sql << "(#{statements.join(', ')})" \
34
34
  if statements.present? || o.inherits.present?
35
35
 
36
- options = PostgreSQL::AR610 ? o : table_options(o)
37
- add_table_options!(create_sql, options)
36
+ add_table_options!(create_sql, o)
38
37
 
39
38
  if o.inherits.present?
40
39
  tables = o.inherits.map(&method(:quote_table_name))
@@ -3,35 +3,7 @@
3
3
  module Torque
4
4
  module PostgreSQL
5
5
  module Adapter
6
- module ColumnMethods
7
-
8
- # Creates a column with an interval type, allowing span of times and
9
- # dates to be stored without having to store a seconds-based integer
10
- # or any sort of other approach
11
- def interval(*args, **options)
12
- args.each { |name| column(name, :interval, **options) }
13
- end
14
-
15
- # Creates a column with an enum type, needing to specify the subtype,
16
- # which is basically the name of the type defined prior creating the
17
- # column
18
- def enum(*args, **options)
19
- subtype = options.delete(:subtype)
20
- args.each { |name| column(name, (subtype || name), **options) }
21
- end
22
-
23
- # Creates a column with an enum array type, needing to specify the
24
- # subtype, which is basically the name of the type defined prior
25
- # creating the column
26
- def enum_set(*args, **options)
27
- super(*args, **options.merge(array: true))
28
- end
29
-
30
- end
31
-
32
6
  module TableDefinition
33
- include ColumnMethods
34
-
35
7
  attr_reader :inherits
36
8
 
37
9
  def initialize(*args, **options)
@@ -42,16 +14,7 @@ module Torque
42
14
  end
43
15
  end
44
16
 
45
- ActiveRecord::ConnectionAdapters::PostgreSQL::Table.include ColumnMethods
46
17
  ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition.include TableDefinition
47
-
48
- if ActiveRecord::ConnectionAdapters::PostgreSQL.const_defined?('ColumnDefinition')
49
- module ColumnDefinition
50
- attr_accessor :subtype
51
- end
52
-
53
- ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDefinition.include ColumnDefinition
54
- end
55
18
  end
56
19
  end
57
20
  end
@@ -12,33 +12,13 @@ module Torque
12
12
  stream
13
13
  end
14
14
 
15
- def extensions(stream) # :nodoc:
16
- super
17
- user_defined_types(stream)
18
- end
19
-
20
15
  # Translate +:enum_set+ into +:enum+
21
16
  def schema_type(column)
22
17
  column.type == :enum_set ? :enum : super
23
18
  end
24
19
 
25
- # Adds +:subtype+ option to the default set
26
- def prepare_column_options(column)
27
- spec = super
28
-
29
- if subtype = schema_subtype(column)
30
- spec[:subtype] = subtype
31
- end
32
-
33
- spec
34
- end
35
-
36
20
  private
37
21
 
38
- def schema_subtype(column)
39
- column.sql_type.to_sym.inspect if column.type == :enum || column.type == :enum_set
40
- end
41
-
42
22
  def tables(stream) # :nodoc:
43
23
  inherited_tables = @connection.inherited_tables
44
24
  sorted_tables = @connection.tables.sort - @connection.views
@@ -83,26 +63,6 @@ module Torque
83
63
  functions(stream) if defined?(::Fx::SchemaDumper::Function)
84
64
  triggers(stream) if defined?(::Fx::SchemaDumper::Trigger)
85
65
  end
86
-
87
- # Dump user defined types like enum
88
- def user_defined_types(stream)
89
- types = @connection.user_defined_types('e')
90
- return unless types.any?
91
-
92
- stream.puts " # These are user-defined types used on this database"
93
- types.sort_by(&:first).each { |(name, type)| send(type.to_sym, name, stream) }
94
- stream.puts
95
- rescue => e
96
- stream.puts "# Could not dump user-defined types because of following #{e.class}"
97
- stream.puts "# #{e.message}"
98
- stream.puts
99
- end
100
-
101
- # Dump enum custom type
102
- def enum(name, stream)
103
- values = @connection.enum_values(name).map { |v| "\"#{v}\"" }
104
- stream.puts " create_enum \"#{name}\", [#{values.join(', ')}], force: :cascade"
105
- end
106
66
  end
107
67
 
108
68
  ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper.prepend SchemaDumper
@@ -25,21 +25,6 @@ module Torque
25
25
  SQL
26
26
  end
27
27
 
28
- # Creates a new PostgreSQL enumerator type
29
- #
30
- # Example:
31
- # create_enum 'status', ['foo', 'bar']
32
- # create_enum 'status', ['foo', 'bar'], prefix: true
33
- # create_enum 'status', ['foo', 'bar'], suffix: 'test'
34
- # create_enum 'status', ['foo', 'bar'], force: true
35
- def create_enum(name, values, options = {})
36
- drop_type(name, options) if options[:force]
37
- execute <<-SQL.squish
38
- CREATE TYPE #{quote_type_name(name, options[:schema])} AS ENUM
39
- (#{quote_enum_values(name, values, options).join(', ')})
40
- SQL
41
- end
42
-
43
28
  # Changes the enumerator by adding new values
44
29
  #
45
30
  # Example:
@@ -49,15 +49,6 @@ module Torque
49
49
  end
50
50
  end
51
51
  end
52
-
53
- # Extend the extract default value to support array
54
- def extract_value_from_default(default)
55
- return super unless Torque::PostgreSQL.config.use_extended_defaults
56
- return super unless default&.match(/ARRAY\[(.*?)\](?:::"?([\w. ]+)"?(?:\[\])+)?$/)
57
-
58
- arr = $1.split(/(?!\B\[[^\]]*), ?(?![^\[]*\]\B)/)
59
- DeduplicatableArray.new(arr.map(&method(:extract_value_from_default)))
60
- end
61
52
  end
62
53
 
63
54
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend Adapter
@@ -53,7 +53,8 @@ module Torque
53
53
 
54
54
  def load_target
55
55
  if stale_target? || find_target?
56
- @target = merge_target_lists(find_target, target)
56
+ persisted_records = (find_target || []) + target.extract!(&:persisted?)
57
+ @target = merge_target_lists(persisted_records, target)
57
58
  end
58
59
 
59
60
  loaded!
@@ -227,8 +228,9 @@ module Torque
227
228
  end
228
229
 
229
230
  def invertible_for?(record)
230
- inverse = inverse_reflection_for(record)
231
- inverse && (inverse.has_many? && inverse.connected_through_array?)
231
+ return unless (inverse = inverse_reflection_for(record))
232
+ collection_class = ::ActiveRecord::Associations::HasManyAssociation
233
+ inverse.is_a?(collection_class) && inverse.connected_through_array?
232
234
  end
233
235
 
234
236
  def stale_state
@@ -3,7 +3,7 @@
3
3
  module Torque
4
4
  module PostgreSQL
5
5
  module Associations
6
- module Association
6
+ module ForeignAssociation
7
7
 
8
8
  # There is no problem of adding temporary items on target because
9
9
  # CollectionProxy will handle memory and persisted relationship
@@ -33,9 +33,6 @@ module Torque
33
33
  end
34
34
 
35
35
  end
36
-
37
- ::ActiveRecord::Associations::Association.prepend(Association)
38
- ::ActiveRecord::Associations::HasManyAssociation.prepend(Association)
39
36
  end
40
37
  end
41
38
  end
@@ -11,8 +11,61 @@ module Torque
11
11
  # For reflections connected through an array, make sure to properly
12
12
  # decuple the list of ids and set them as associated with the owner
13
13
  def run
14
+ return self if run?
14
15
  return super unless connected_through_array?
16
+
17
+ @run = true
15
18
  send("run_array_for_#{@reflection.macro}")
19
+ self
20
+ end
21
+
22
+ # Correctly correlate records when they are connected theough an array
23
+ def set_inverse(record)
24
+ return super unless connected_through_array? && @reflection.macro == :has_many
25
+
26
+ # Only the first owner is associated following the same instruction
27
+ # on the original implementation
28
+ convert_key(record[association_key_name])&.each do |key|
29
+ if owners = owners_by_key[key]
30
+ association = owners.first.association(reflection.name)
31
+ association.set_inverse_instance(record)
32
+ end
33
+ end
34
+ end
35
+
36
+ # Requires a slight change when running on has many since the value
37
+ # of the foreign key being an array
38
+ def load_records(raw_records = nil)
39
+ return super unless connected_through_array? && @reflection.macro == :has_many
40
+
41
+ @records_by_owner = {}.compare_by_identity
42
+ raw_records ||= loader_query.records_for([self])
43
+
44
+ @preloaded_records = raw_records.select do |record|
45
+ assignments = false
46
+
47
+ keys = convert_key(record[association_key_name]) || []
48
+ owners_by_key.values_at(*keys).each do |owner|
49
+ entries = (@records_by_owner[owner] ||= [])
50
+
51
+ if reflection.collection? || entries.empty?
52
+ entries << record
53
+ assignments = true
54
+ end
55
+ end
56
+
57
+ assignments
58
+ end
59
+ end
60
+
61
+ # Make sure to change the process when connected through an array
62
+ def owners_by_key
63
+ return super unless connected_through_array?
64
+ @owners_by_key ||= owners.each_with_object({}) do |owner, result|
65
+ Array.wrap(convert_key(owner[owner_key_name])).each do |key|
66
+ (result[key] ||= []) << owner
67
+ end
68
+ end
16
69
  end
17
70
 
18
71
  private
@@ -41,32 +94,6 @@ module Torque
41
94
  end
42
95
  end
43
96
 
44
- if PostgreSQL::AR604
45
- # This is how Rails 6.0.4 and 6.1 now load the records
46
- def load_records
47
- return super unless connected_through_array?
48
-
49
- @records_by_owner = {}.compare_by_identity
50
- raw_records = owner_keys.empty? ? [] : records_for(owner_keys)
51
-
52
- @preloaded_records = raw_records.select do |record|
53
- assignments = false
54
-
55
- ids = convert_key(record[association_key_name])
56
- owners_by_key.values_at(*ids).flat_map do |owner|
57
- entries = (@records_by_owner[owner] ||= [])
58
-
59
- if reflection.collection? || entries.empty?
60
- entries << record
61
- assignments = true
62
- end
63
- end
64
-
65
- assignments
66
- end
67
- end
68
- end
69
-
70
97
  # Build correctly the constraint condition in order to get the
71
98
  # associated ids
72
99
  def records_for(ids, &block)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Torque
4
+ module PostgreSQL
5
+ module Associations
6
+ module Preloader
7
+ module LoaderQuery
8
+ def foreign_column
9
+ @foreign_column ||= scope.columns_hash[association_key_name]
10
+ end
11
+
12
+ def load_records_for_keys(keys, &block)
13
+ condition = query_condition_for(keys)
14
+ scope.where(condition).load(&block)
15
+ end
16
+
17
+ def query_condition_for(keys)
18
+ if connected_through_array?
19
+ value = scope.cast_for_condition(foreign_column, keys.to_a)
20
+ scope.table[association_key_name].overlaps(value)
21
+ else
22
+ { association_key_name => keys }
23
+ end
24
+ end
25
+
26
+ def connected_through_array?
27
+ foreign_column.array?
28
+ end
29
+ end
30
+
31
+ ::ActiveRecord::Associations::Preloader::Association::LoaderQuery
32
+ .prepend(LoaderQuery)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1 +1,2 @@
1
1
  require_relative 'preloader/association'
2
+ require_relative 'preloader/loader_query'
@@ -1,5 +1,10 @@
1
- require_relative 'associations/association'
2
1
  require_relative 'associations/association_scope'
3
2
  require_relative 'associations/belongs_to_many_association'
3
+ require_relative 'associations/foreign_association'
4
+
4
5
  require_relative 'associations/builder'
5
6
  require_relative 'associations/preloader'
7
+
8
+ association_mod = Torque::PostgreSQL::Associations::ForeignAssociation
9
+ ::ActiveRecord::Associations::HasManyAssociation.prepend(association_mod)
10
+ ::ActiveRecord::Associations::BelongsToManyAssociation.prepend(association_mod)
@@ -220,7 +220,7 @@ module Torque
220
220
  @arel_threshold_value ||= begin
221
221
  case threshold
222
222
  when Symbol, String
223
- "arel_attribute('#{threshold}')"
223
+ "arel_table['#{threshold}']"
224
224
  when ActiveSupport::Duration
225
225
  value = "'#{threshold.to_i} seconds'"
226
226
  "::Arel.sql(\"#{value}\").cast(:interval)"
@@ -453,7 +453,11 @@ module Torque
453
453
  attr_value = threshold.present? ? method_names[:real] : attribute
454
454
  default_value = default.inspect
455
455
 
456
- "#{attr_value}.nil? ? #{default_value} : #{attr_value}.include?(value)"
456
+ [
457
+ "return #{default_value} if #{attr_value}.nil?",
458
+ "(#{attr_value}.min.try(:infinite?) || #{attr_value}.min <= value) &&",
459
+ " (#{attr_value}.max.try(:infinite?) || #{attr_value}.max > value)",
460
+ ].join("\n")
457
461
  end
458
462
 
459
463
  def instance_start
@@ -4,10 +4,6 @@ module Torque
4
4
  module PostgreSQL
5
5
  include ActiveSupport::Configurable
6
6
 
7
- # Stores a version check for compatibility purposes
8
- AR604 = (ActiveRecord.gem_version >= Gem::Version.new('6.0.4'))
9
- AR610 = (ActiveRecord.gem_version >= Gem::Version.new('6.1.0'))
10
-
11
7
  # Use the same logger as the Active Record one
12
8
  def self.logger
13
9
  ActiveRecord::Base.logger
@@ -26,11 +22,6 @@ module Torque
26
22
  # same configuration is set to true
27
23
  config.eager_load = false
28
24
 
29
- # This allows default values to have extended values like arrays and casted
30
- # values. Extended defaults are still experimental, so enable and test it
31
- # before using it in prod
32
- config.use_extended_defaults = false
33
-
34
25
  # Set a list of irregular model name when associated with table names
35
26
  config.irregular_models = {}
36
27
  def config.irregular_models=(hash)
@@ -66,11 +57,11 @@ module Torque
66
57
 
67
58
  # The name of the method to be used on any ActiveRecord::Base to
68
59
  # initialize model-based enum features
69
- enum.base_method = :enum
60
+ enum.base_method = :torque_enum
70
61
 
71
62
  # The name of the method to be used on any ActiveRecord::Base to
72
63
  # initialize model-based enum set features
73
- enum.set_method = :enum_set
64
+ enum.set_method = :torque_enum_set
74
65
 
75
66
  # Indicates if bang methods like 'disabled!' should update the record on
76
67
  # database or not
@@ -45,9 +45,9 @@ module Torque
45
45
  return klass_attr.eq(source_attr) unless connected_through_array?
46
46
 
47
47
  # Klass and key are associated with the reflection Class
48
- klass_type = klass.columns_hash[join_keys.key.to_s]
48
+ klass_type = klass.columns_hash[join_primary_key.to_s]
49
49
  # active_record and foreign_key are associated with the source Class
50
- source_type = active_record.columns_hash[join_keys.foreign_key.to_s]
50
+ source_type = active_record.columns_hash[join_foreign_key.to_s]
51
51
 
52
52
  # If both are attributes but the left side is not an array, and the
53
53
  # right side is, use the ANY operation
@@ -70,11 +70,9 @@ module Torque
70
70
  klass_attr.overlaps(source_attr)
71
71
  end
72
72
 
73
- if PostgreSQL::AR610
74
- # TODO: Deprecate this method
75
- def join_keys
76
- OpenStruct.new(key: join_primary_key, foreign_key: join_foreign_key)
77
- end
73
+ # TODO: Deprecate this method
74
+ def join_keys
75
+ OpenStruct.new(key: join_primary_key, foreign_key: join_foreign_key)
78
76
  end
79
77
 
80
78
  private
@@ -19,6 +19,8 @@ module Torque
19
19
  MULTI_VALUE_METHODS = [:distinct_on, :auxiliary_statements, :cast_records, :select_extra]
20
20
  VALUE_METHODS = SINGLE_VALUE_METHODS + MULTI_VALUE_METHODS
21
21
 
22
+ ARColumn = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Column
23
+
22
24
  # :nodoc:
23
25
  def select_extra_values; get_value(:select_extra); end
24
26
  # :nodoc:
@@ -74,6 +76,14 @@ module Torque
74
76
  end
75
77
  end
76
78
 
79
+ # Serialize the given value so it can be used in a condition tha involves
80
+ # the given column
81
+ def cast_for_condition(column, value)
82
+ column = columns_hash[column.to_s] unless column.is_a?(ARColumn)
83
+ caster = connection.lookup_cast_type_from_column(column)
84
+ connection.type_cast(caster.serialize(value))
85
+ end
86
+
77
87
  private
78
88
 
79
89
  def build_arel(*)
@@ -140,18 +150,6 @@ module Torque
140
150
  ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES += %i[cast_records itself_only
141
151
  distinct_on auxiliary_statements]
142
152
 
143
- unless AR610
144
- Relation::SINGLE_VALUE_METHODS.each do |value|
145
- ActiveRecord::QueryMethods::DEFAULT_VALUES[value] = nil \
146
- if ActiveRecord::QueryMethods::DEFAULT_VALUES[value].nil?
147
- end
148
-
149
- Relation::MULTI_VALUE_METHODS.each do |value|
150
- ActiveRecord::QueryMethods::DEFAULT_VALUES[value] ||= \
151
- ActiveRecord::QueryMethods::FROZEN_EMPTY_ARRAY
152
- end
153
- end
154
-
155
153
  $VERBOSE = warn_level
156
154
  end
157
155
  end
@@ -109,6 +109,7 @@ module Torque
109
109
 
110
110
  # Try to find a model based on a given table
111
111
  def lookup_model(table_name, scoped_class = '')
112
+ # byebug if table_name == 'activities'
112
113
  scoped_class = scoped_class.name if scoped_class.is_a?(Class)
113
114
  return @data_sources_model_names[table_name] \
114
115
  if @data_sources_model_names.key?(table_name)
@@ -123,7 +124,7 @@ module Torque
123
124
 
124
125
  # Test all the possible names against all the possible scopes
125
126
  until scopes.size == 0
126
- scope = scopes.join.safe_constantize
127
+ scope = scopes.join.chomp('::').safe_constantize
127
128
  model = find_model(max_name, table_name, scope) unless scope.nil?
128
129
  return @data_sources_model_names[table_name] = model unless model.nil?
129
130
  scopes.pop
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Torque
4
4
  module PostgreSQL
5
- VERSION = '2.2.1'
5
+ VERSION = '3.0.0'
6
6
  end
7
7
  end
@@ -1,2 +1 @@
1
1
  require 'torque/postgresql'
2
- require 'torque/range'
@@ -1,2 +1,4 @@
1
+ require_relative 'question'
2
+
1
3
  class QuestionSelect < Question
2
4
  end