torque-postgresql 2.4.4 → 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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +0 -17
  3. data/lib/torque/postgresql/adapter/database_statements.rb +32 -74
  4. data/lib/torque/postgresql/adapter/oid/enum_set.rb +1 -1
  5. data/lib/torque/postgresql/adapter/oid.rb +0 -3
  6. data/lib/torque/postgresql/adapter/quoting.rb +12 -20
  7. data/lib/torque/postgresql/adapter/schema_creation.rb +1 -2
  8. data/lib/torque/postgresql/adapter/schema_definitions.rb +0 -37
  9. data/lib/torque/postgresql/adapter/schema_dumper.rb +2 -60
  10. data/lib/torque/postgresql/adapter/schema_statements.rb +2 -74
  11. data/lib/torque/postgresql/adapter.rb +2 -11
  12. data/lib/torque/postgresql/associations/belongs_to_many_association.rb +7 -6
  13. data/lib/torque/postgresql/associations/{association.rb → foreign_association.rb} +1 -4
  14. data/lib/torque/postgresql/associations/preloader/association.rb +53 -26
  15. data/lib/torque/postgresql/associations/preloader/loader_query.rb +36 -0
  16. data/lib/torque/postgresql/associations/preloader.rb +1 -0
  17. data/lib/torque/postgresql/associations.rb +6 -1
  18. data/lib/torque/postgresql/attributes/builder/period.rb +6 -2
  19. data/lib/torque/postgresql/auxiliary_statement/settings.rb +22 -75
  20. data/lib/torque/postgresql/auxiliary_statement.rb +40 -39
  21. data/lib/torque/postgresql/base.rb +13 -33
  22. data/lib/torque/postgresql/config.rb +3 -30
  23. data/lib/torque/postgresql/inheritance.rb +1 -3
  24. data/lib/torque/postgresql/migration/command_recorder.rb +2 -12
  25. data/lib/torque/postgresql/railtie.rb +1 -5
  26. data/lib/torque/postgresql/reflection/abstract_reflection.rb +44 -20
  27. data/lib/torque/postgresql/reflection/belongs_to_many_reflection.rb +2 -2
  28. data/lib/torque/postgresql/relation/auxiliary_statement.rb +15 -28
  29. data/lib/torque/postgresql/relation.rb +10 -12
  30. data/lib/torque/postgresql/schema_cache.rb +2 -7
  31. data/lib/torque/postgresql/version.rb +1 -1
  32. data/lib/torque/postgresql.rb +1 -2
  33. data/lib/torque-postgresql.rb +0 -1
  34. data/spec/schema.rb +14 -30
  35. data/spec/spec_helper.rb +1 -2
  36. data/spec/tests/arel_spec.rb +2 -4
  37. data/spec/tests/auxiliary_statement_spec.rb +35 -374
  38. data/spec/tests/belongs_to_many_spec.rb +2 -99
  39. data/spec/tests/distinct_on_spec.rb +1 -1
  40. data/spec/tests/enum_set_spec.rb +10 -10
  41. data/spec/tests/enum_spec.rb +0 -90
  42. data/spec/tests/has_many_spec.rb +0 -46
  43. data/spec/tests/relation_spec.rb +1 -1
  44. data/spec/tests/table_inheritance_spec.rb +15 -11
  45. metadata +11 -37
  46. data/lib/torque/postgresql/auxiliary_statement/recursive.rb +0 -149
  47. data/lib/torque/postgresql/table_name.rb +0 -41
  48. data/lib/torque/range.rb +0 -22
  49. data/spec/models/category.rb +0 -2
  50. data/spec/models/internal/user.rb +0 -5
  51. data/spec/tests/range_spec.rb +0 -36
  52. data/spec/tests/schema_spec.rb +0 -134
@@ -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,9 +4,9 @@ module Torque
4
4
  module PostgreSQL
5
5
  class AuxiliaryStatement
6
6
  class Settings < Collector.new(:attributes, :join, :join_type, :query, :requires,
7
- :polymorphic, :through, :union_all, :connect)
7
+ :polymorphic, :through)
8
8
 
9
- attr_reader :base, :source, :depth, :path
9
+ attr_reader :base, :source
10
10
  alias_method :select, :attributes
11
11
  alias_method :cte, :source
12
12
 
@@ -14,10 +14,9 @@ module Torque
14
14
  delegate :table, :table_name, to: :@source
15
15
  delegate :sql, to: ::Arel
16
16
 
17
- def initialize(base, source, recursive = false)
17
+ def initialize(base, source)
18
18
  @base = base
19
19
  @source = source
20
- @recursive = recursive
21
20
  end
22
21
 
23
22
  def base_name
@@ -28,39 +27,6 @@ module Torque
28
27
  @base.arel_table
29
28
  end
30
29
 
31
-
32
- def recursive?
33
- @recursive
34
- end
35
-
36
- def depth?
37
- defined?(@depth)
38
- end
39
-
40
- def path?
41
- defined?(@path)
42
- end
43
-
44
- # Add an attribute to the result showing the depth of each iteration
45
- def with_depth(name = 'depth', start: 0, as: nil)
46
- @depth = [name.to_s, start, as&.to_s] if recursive?
47
- end
48
-
49
- # Add an attribute to the result showing the path of each record
50
- def with_path(name = 'path', source: nil, as: nil)
51
- @path = [name.to_s, source&.to_s, as&.to_s] if recursive?
52
- end
53
-
54
- # Set recursive operation to use union all
55
- def union_all!
56
- @union_all = true if recursive?
57
- end
58
-
59
- # Add both depth and path to the result
60
- def with_depth_and_path
61
- with_depth && with_path
62
- end
63
-
64
30
  # Get the arel version of the table set on the query
65
31
  def query_table
66
32
  raise StandardError, 'The query is not defined yet' if query.nil?
@@ -75,55 +41,36 @@ module Torque
75
41
 
76
42
  alias column col
77
43
 
78
- # There are three ways of setting the query:
44
+ # There are two ways of setting the query:
79
45
  # - A simple relation based on a Model
80
46
  # - A Arel-based select manager
81
- # - A string or a proc
47
+ # - A string or a proc that requires the table name as first argument
82
48
  def query(value = nil, command = nil)
83
49
  return @query if value.nil?
50
+ return @query = value if relation_query?(value)
84
51
 
85
- @query = sanitize_query(value, command)
86
- end
87
-
88
- # Same as query, but for the second part of the union for recursive cte
89
- def sub_query(value = nil, command = nil)
90
- return unless recursive?
91
- return @sub_query if value.nil?
52
+ if value.is_a?(::Arel::SelectManager)
53
+ @query = value
54
+ @query_table = value.source.left.name
55
+ return
56
+ end
92
57
 
93
- @sub_query = sanitize_query(value, command)
94
- end
58
+ valid_type = command.respond_to?(:call) || command.is_a?(String)
95
59
 
96
- # Assume `parent_` as the other part if provided a Symbol or String
97
- def connect(value = nil)
98
- return @connect if value.nil?
60
+ raise ArgumentError, <<-MSG.squish if command.nil?
61
+ To use proc or string as query, you need to provide the table name
62
+ as the first argument
63
+ MSG
99
64
 
100
- value = [value.to_sym, :"parent_#{value}"] \
101
- if value.is_a?(String) || value.is_a?(Symbol)
102
- value = value.to_a.first if value.is_a?(Hash)
65
+ raise ArgumentError, <<-MSG.squish unless valid_type
66
+ Only relation, string and proc are valid object types for query,
67
+ #{command.inspect} given.
68
+ MSG
103
69
 
104
- @connect = value
70
+ @query = command
71
+ @query_table = ::Arel::Table.new(value)
105
72
  end
106
73
 
107
- alias connect= connect
108
-
109
- private
110
-
111
- # Get the query and table from the params
112
- def sanitize_query(value, command = nil)
113
- return value if relation_query?(value)
114
- return value if value.is_a?(::Arel::SelectManager)
115
-
116
- command = value if command.nil? # For compatibility purposes
117
- valid_type = command.respond_to?(:call) || command.is_a?(String)
118
-
119
- raise ArgumentError, <<-MSG.squish unless valid_type
120
- Only relation, string and proc are valid object types for query,
121
- #{command.inspect} given.
122
- MSG
123
-
124
- command
125
- end
126
-
127
74
  end
128
75
  end
129
76
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'auxiliary_statement/settings'
4
- require_relative 'auxiliary_statement/recursive'
5
4
 
6
5
  module Torque
7
6
  module PostgreSQL
@@ -9,20 +8,17 @@ module Torque
9
8
  TABLE_COLUMN_AS_STRING = /\A(?:"?(\w+)"?\.)?"?(\w+)"?\z/.freeze
10
9
 
11
10
  class << self
12
- attr_reader :config, :table_name
11
+ attr_reader :config
13
12
 
14
13
  # Find or create the class that will handle statement
15
14
  def lookup(name, base)
16
15
  const = name.to_s.camelize << '_' << self.name.demodulize
17
16
  return base.const_get(const, false) if base.const_defined?(const, false)
18
-
19
- base.const_set(const, Class.new(self)).tap do |klass|
20
- klass.instance_variable_set(:@table_name, name.to_s)
21
- end
17
+ base.const_set(const, Class.new(AuxiliaryStatement))
22
18
  end
23
19
 
24
20
  # Create a new instance of an auxiliary statement
25
- def instantiate(statement, base, **options)
21
+ def instantiate(statement, base, options = nil)
26
22
  klass = while base < ActiveRecord::Base
27
23
  list = base.auxiliary_statements_list
28
24
  break list[statement] if list.present? && list.key?(statement)
@@ -30,15 +26,15 @@ module Torque
30
26
  base = base.superclass
31
27
  end
32
28
 
33
- return klass.new(**options) unless klass.nil?
29
+ return klass.new(options) unless klass.nil?
34
30
  raise ArgumentError, <<-MSG.squish
35
31
  There's no '#{statement}' auxiliary statement defined for #{base.class.name}.
36
32
  MSG
37
33
  end
38
34
 
39
35
  # Fast access to statement build
40
- def build(statement, base, bound_attributes = [], join_sources = [], **options)
41
- klass = instantiate(statement, base, **options)
36
+ def build(statement, base, options = nil, bound_attributes = [], join_sources = [])
37
+ klass = instantiate(statement, base, options)
42
38
  result = klass.build(base)
43
39
 
44
40
  bound_attributes.concat(klass.bound_attributes)
@@ -60,7 +56,7 @@ module Torque
60
56
  # A way to create auxiliary statements outside of models configurations,
61
57
  # being able to use on extensions
62
58
  def create(table_or_settings, &block)
63
- klass = Class.new(self)
59
+ klass = Class.new(AuxiliaryStatement)
64
60
 
65
61
  if block_given?
66
62
  klass.instance_variable_set(:@table_name, table_or_settings)
@@ -93,8 +89,7 @@ module Torque
93
89
  def configure(base, instance)
94
90
  return @config unless @config.respond_to?(:call)
95
91
 
96
- recursive = self < AuxiliaryStatement::Recursive
97
- settings = Settings.new(base, instance, recursive)
92
+ settings = Settings.new(base, instance)
98
93
  settings.instance_exec(settings, &@config)
99
94
  settings
100
95
  end
@@ -103,6 +98,11 @@ module Torque
103
98
  def table
104
99
  @table ||= ::Arel::Table.new(table_name)
105
100
  end
101
+
102
+ # Get the name of the table of the configurated statement
103
+ def table_name
104
+ @table_name ||= self.name.demodulize.split('_').first.underscore
105
+ end
106
106
  end
107
107
 
108
108
  delegate :config, :table, :table_name, :relation, :configure, :relation_query?,
@@ -111,14 +111,15 @@ module Torque
111
111
  attr_reader :bound_attributes, :join_sources
112
112
 
113
113
  # Start a new auxiliary statement giving extra options
114
- def initialize(*, **options)
114
+ def initialize(*args)
115
+ options = args.extract_options!
115
116
  args_key = Torque::PostgreSQL.config.auxiliary_statement.send_arguments_key
116
117
 
117
118
  @join = options.fetch(:join, {})
118
119
  @args = options.fetch(args_key, {})
119
120
  @where = options.fetch(:where, {})
120
121
  @select = options.fetch(:select, {})
121
- @join_type = options[:join_type]
122
+ @join_type = options.fetch(:join_type, nil)
122
123
 
123
124
  @bound_attributes = []
124
125
  @join_sources = []
@@ -130,7 +131,7 @@ module Torque
130
131
  @join_sources.clear
131
132
 
132
133
  # Prepare all the data for the statement
133
- prepare(base, configure(base, self))
134
+ prepare(base)
134
135
 
135
136
  # Add the join condition to the list
136
137
  @join_sources << build_join(base)
@@ -141,7 +142,8 @@ module Torque
141
142
 
142
143
  private
143
144
  # Setup the statement using the class configuration
144
- def prepare(base, settings)
145
+ def prepare(base)
146
+ settings = configure(base, self)
145
147
  requires = Array.wrap(settings.requires).flatten.compact
146
148
  @dependencies = ensure_dependencies(requires, base).flatten.compact
147
149
 
@@ -149,13 +151,14 @@ module Torque
149
151
  @query = settings.query
150
152
 
151
153
  # Call a proc to get the real query
152
- if @query.respond_to?(:call)
154
+ if @query.methods.include?(:call)
153
155
  call_args = @query.try(:arity) === 0 ? [] : [OpenStruct.new(@args)]
154
156
  @query = @query.call(*call_args)
155
157
  @args = []
156
158
  end
157
159
 
158
- # Merge select attributes provided on the instance creation
160
+ # Manually set the query table when it's not an relation query
161
+ @query_table = settings.query_table unless relation_query?(@query)
159
162
  @select = settings.attributes.merge(@select) if settings.attributes.present?
160
163
 
161
164
  # Merge join settings
@@ -165,7 +168,7 @@ module Torque
165
168
  @association = settings.through.to_s
166
169
  elsif relation_query?(@query)
167
170
  @association = base.reflections.find do |name, reflection|
168
- break name if @query.klass.eql?(reflection.klass)
171
+ break name if @query.klass.eql? reflection.klass
169
172
  end
170
173
  end
171
174
  end
@@ -231,6 +234,15 @@ module Torque
231
234
  as a query object on #{self.class.name}.
232
235
  MSG
233
236
 
237
+ # Expose join columns
238
+ if relation_query?(@query)
239
+ query_table = @query.arel_table
240
+ conditions.children.each do |item|
241
+ @query.select_values += [query_table[item.left.name]] \
242
+ if item.left.relation.eql?(table)
243
+ end
244
+ end
245
+
234
246
  # Build the join based on the join type
235
247
  arel_join.new(table, table.create_on(conditions))
236
248
  end
@@ -251,31 +263,21 @@ module Torque
251
263
 
252
264
  # Mount the list of selected attributes
253
265
  def expose_columns(base, query_table = nil)
254
- # Add the columns necessary for the join
255
- list = @join_sources.each_with_object(@select) do |join, hash|
256
- join.right.expr.children.each do |item|
257
- hash[item.left.name] = nil if item.left.relation.eql?(table)
258
- end
259
- end
260
-
261
266
  # Add select columns to the query and get exposed columns
262
- list.map do |left, right|
263
- base.select_extra_values += [table[right.to_s]] unless right.nil?
264
- next unless query_table
265
-
266
- col = project(left, query_table)
267
- right.nil? ? col : col.as(right.to_s)
268
- end.compact
267
+ @select.map do |left, right|
268
+ base.select_extra_values += [table[right.to_s]]
269
+ project(left, query_table).as(right.to_s) if query_table
270
+ end
269
271
  end
270
272
 
271
273
  # Ensure that all the dependencies are loaded in the base relation
272
274
  def ensure_dependencies(list, base)
273
275
  with_options = list.extract_options!.to_a
274
- (list + with_options).map do |name, options|
275
- dependent_klass = base.model.auxiliary_statements_list[name]
276
+ (list + with_options).map do |dependent, options|
277
+ dependent_klass = base.model.auxiliary_statements_list[dependent]
276
278
 
277
279
  raise ArgumentError, <<-MSG.squish if dependent_klass.nil?
278
- The '#{name}' auxiliary statement dependency can't found on
280
+ The '#{dependent}' auxiliary statement dependency can't found on
279
281
  #{self.class.name}.
280
282
  MSG
281
283
 
@@ -283,8 +285,7 @@ module Torque
283
285
  cte.is_a?(dependent_klass)
284
286
  end
285
287
 
286
- options ||= {}
287
- AuxiliaryStatement.build(name, base, bound_attributes, join_sources, **options)
288
+ AuxiliaryStatement.build(dependent, base, options, bound_attributes, join_sources)
288
289
  end
289
290
  end
290
291
 
@@ -5,27 +5,15 @@ module Torque
5
5
  module Base
6
6
  extend ActiveSupport::Concern
7
7
 
8
- ##
9
- # :singleton-method: schema
10
- # :call-seq: schema
11
- #
12
- # The schema to which the table belongs to.
13
-
14
8
  included do
15
9
  mattr_accessor :belongs_to_many_required_by_default, instance_accessor: false
16
- class_attribute :schema, instance_writer: false
17
10
  end
18
11
 
19
12
  module ClassMethods
20
13
  delegate :distinct_on, :with, :itself_only, :cast_records, to: :all
21
14
 
22
- # Make sure that table name is an instance of TableName class
23
- def reset_table_name
24
- self.table_name = TableName.new(self, super)
25
- end
26
-
27
- # Whenever the base model is inherited, add a list of auxiliary
28
- # statements like the one that loads inherited records' relname
15
+ # Wenever it's inherited, add a new list of auxiliary statements
16
+ # It also adds an auxiliary statement to load inherited records' relname
29
17
  def inherited(subclass)
30
18
  super
31
19
 
@@ -36,11 +24,6 @@ module Torque
36
24
 
37
25
  # Define helper methods to return the class of the given records
38
26
  subclass.auxiliary_statement record_class do |cte|
39
- ActiveSupport::Deprecation.warn(<<~MSG.squish)
40
- Inheritance does not use this auxiliary statement and it can be removed.
41
- You can replace it with `model.select_extra_values << 'tableoid::regclass'`.
42
- MSG
43
-
44
27
  pg_class = ::Arel::Table.new('pg_class')
45
28
  arel_query = ::Arel::SelectManager.new(pg_class)
46
29
  arel_query.project(pg_class['oid'], pg_class['relname'].as(record_class.to_s))
@@ -53,11 +36,18 @@ module Torque
53
36
  # Define the dynamic attribute that returns the same information as
54
37
  # the one provided by the auxiliary statement
55
38
  subclass.dynamic_attribute(record_class) do
56
- klass = self.class
57
- next klass.table_name unless klass.physically_inheritances?
39
+ next self.class.table_name unless self.class.physically_inheritances?
40
+
41
+ pg_class = ::Arel::Table.new('pg_class')
42
+ source = ::Arel::Table.new(subclass.table_name, as: 'source')
43
+ quoted_id = ::Arel::Nodes::Quoted.new(id)
58
44
 
59
- query = klass.unscoped.where(subclass.primary_key => id)
60
- query.pluck(klass.arel_table['tableoid'].cast('regclass')).first
45
+ query = ::Arel::SelectManager.new(pg_class)
46
+ query.join(source).on(pg_class['oid'].eq(source['tableoid']))
47
+ query.where(source[subclass.primary_key].eq(quoted_id))
48
+ query.project(pg_class['relname'])
49
+
50
+ self.class.connection.select_value(query)
61
51
  end
62
52
  end
63
53
 
@@ -309,16 +299,6 @@ module Torque
309
299
  klass.configurator(block)
310
300
  end
311
301
  alias cte auxiliary_statement
312
-
313
- # Creates a new recursive auxiliary statement (CTE) under the base
314
- # Very similar to the regular auxiliary statement, but with two-part
315
- # query where one is executed first and the second recursively
316
- def recursive_auxiliary_statement(table, &block)
317
- klass = AuxiliaryStatement::Recursive.lookup(table, self)
318
- auxiliary_statements_list[table.to_sym] = klass
319
- klass.configurator(block)
320
- end
321
- alias recursive_cte recursive_auxiliary_statement
322
302
  end
323
303
  end
324
304
 
@@ -4,11 +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
- AR615 = (ActiveRecord.gem_version >= Gem::Version.new('6.1.5'))
11
-
12
7
  # Use the same logger as the Active Record one
13
8
  def self.logger
14
9
  ActiveRecord::Base.logger
@@ -27,11 +22,6 @@ module Torque
27
22
  # same configuration is set to true
28
23
  config.eager_load = false
29
24
 
30
- # This allows default values to have extended values like arrays and casted
31
- # values. Extended defaults are still experimental, so enable and test it
32
- # before using it in prod
33
- config.use_extended_defaults = false
34
-
35
25
  # Set a list of irregular model name when associated with table names
36
26
  config.irregular_models = {}
37
27
  def config.irregular_models=(hash)
@@ -40,19 +30,6 @@ module Torque
40
30
  end.to_h
41
31
  end
42
32
 
43
- # Configure multiple schemas
44
- config.nested(:schemas) do |schemas|
45
-
46
- # Defines a list of LIKE-based schemas to not consider for a multiple
47
- # schema database
48
- schemas.blacklist = %w[information_schema pg_%]
49
-
50
- # Defines a list of LIKE-based schemas to consider for a multiple schema
51
- # database
52
- schemas.whitelist = %w[public]
53
-
54
- end
55
-
56
33
  # Configure associations features
57
34
  config.nested(:associations) do |assoc|
58
35
 
@@ -69,14 +46,10 @@ module Torque
69
46
  # arguments to format string or send on a proc
70
47
  cte.send_arguments_key = :args
71
48
 
72
- # Estipulate a class name (which may contain namespace) that exposes the
49
+ # Estipulate a class name (which may contain namespace) that expose the
73
50
  # auxiliary statement in order to perform detached CTEs
74
51
  cte.exposed_class = 'TorqueCTE'
75
52
 
76
- # Estipulate a class name (which may contain namespace) that exposes the
77
- # recursive auxiliary statement in order to perform detached CTEs
78
- cte.exposed_recursive_class = 'TorqueRecursiveCTE'
79
-
80
53
  end
81
54
 
82
55
  # Configure ENUM features
@@ -84,11 +57,11 @@ module Torque
84
57
 
85
58
  # The name of the method to be used on any ActiveRecord::Base to
86
59
  # initialize model-based enum features
87
- enum.base_method = :enum
60
+ enum.base_method = :torque_enum
88
61
 
89
62
  # The name of the method to be used on any ActiveRecord::Base to
90
63
  # initialize model-based enum set features
91
- enum.set_method = :enum_set
64
+ enum.set_method = :torque_enum_set
92
65
 
93
66
  # Indicates if bang methods like 'disabled!' should update the record on
94
67
  # database or not
@@ -55,9 +55,7 @@ module Torque
55
55
 
56
56
  # Check if the model's table depends on any inheritance
57
57
  def physically_inherited?
58
- return @physically_inherited if defined?(@physically_inherited)
59
-
60
- @physically_inherited = connection.schema_cache.dependencies(
58
+ @physically_inherited ||= connection.schema_cache.dependencies(
61
59
  defined?(@table_name) ? @table_name : decorated_table_name,
62
60
  ).present?
63
61
  rescue ActiveRecord::ConnectionNotEstablished