torque-postgresql 2.4.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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