torque-postgresql 1.1.0 → 1.1.5

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
- SHA1:
3
- metadata.gz: a161d5be06adc9e93a5888b4b16b1a07b6f4a613
4
- data.tar.gz: 51c1aae61c09bfa681e02daeb523551da9ef1139
2
+ SHA256:
3
+ metadata.gz: 91a42a9a04ba195e57f4b87af2931a6ecf82e9d58a4acec84b95350404ee4977
4
+ data.tar.gz: e4fce1b312a40bf6e98a1f8bee8351795a45a5afddf25ce0f7765cd6c01d89ec
5
5
  SHA512:
6
- metadata.gz: 99892a8ca40bf830e81accb0d4f15d87fbcb44697b95b4f9854a81b2e5d733c80c1a23f7312009407741ea11e7a6cb4d29acae8b03284226d618fadfbaa6a9da
7
- data.tar.gz: 53e5888be0f1c89d2e30c85acc2ad350e34ad5efe6b6d899315a4cd18affe9366978d5cfd7e4ddad7843c0856ca11f7243f106d5d4ad2f538a86e2c11d5551ce
6
+ metadata.gz: 56a370889f5ffbb09a2c414bd1a9c4311d4d415675fd8ac7f00a09ffb4b2aa4b70998b475f6ab494ad06f0e0b9783ddea599268f04d0c5d3184b9e1d0d644d44
7
+ data.tar.gz: 7341f28b3805af398868be6a4095c9dcf4b9e7d6be28a0ce4e2af0340004490e2e75b9eb6e7e63f9d6ac0bba1caf5fdb7154cd5b8d7928c6c093f748cda96d71
data/Rakefile CHANGED
@@ -14,13 +14,16 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- desc 'Prints a schema dump of the test database'
18
- task :dump do |t|
17
+ desc 'Initialize the local environment'
18
+ task :environment do |t|
19
19
  lib = File.expand_path('../lib', __FILE__)
20
20
  spec = File.expand_path('../spec', __FILE__)
21
21
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
22
22
  $LOAD_PATH.unshift(spec) unless $LOAD_PATH.include?(spec)
23
+ end
23
24
 
25
+ desc 'Prints a schema dump of the test database'
26
+ task dump: :environment do |t|
24
27
  require 'byebug'
25
28
  require 'spec_helper'
26
29
  ActiveRecord::SchemaDumper.dump
@@ -4,19 +4,3 @@ require_relative 'attributes/builder'
4
4
  require_relative 'attributes/enum'
5
5
  require_relative 'attributes/enum_set'
6
6
  require_relative 'attributes/period'
7
-
8
- module Torque
9
- module PostgreSQL
10
- module Attributes
11
- extend ActiveSupport::Concern
12
-
13
- # Configure enum_save_on_bang behavior
14
- included do
15
- class_attribute :enum_save_on_bang, instance_accessor: true
16
- self.enum_save_on_bang = Torque::PostgreSQL.config.enum.save_on_bang
17
- end
18
- end
19
-
20
- ActiveRecord::Base.include Attributes
21
- end
22
- end
@@ -5,14 +5,14 @@ module Torque
5
5
  module PostgreSQL
6
6
  module Attributes
7
7
  module Builder
8
- def self.include_on(klass, method_name, builder_klass, &block)
8
+ def self.include_on(klass, method_name, builder_klass, **extra, &block)
9
9
  klass.define_singleton_method(method_name) do |*args, **options|
10
10
  return unless connection.table_exists?(table_name)
11
11
 
12
12
  args.each do |attribute|
13
13
  begin
14
14
  # Generate methods on self class
15
- builder = builder_klass.new(self, attribute, options)
15
+ builder = builder_klass.new(self, attribute, extra.merge(options))
16
16
  builder.conflicting?
17
17
  builder.build
18
18
 
@@ -5,7 +5,8 @@ module Torque
5
5
  class Enum
6
6
  VALID_TYPES = %i[enum enum_set].freeze
7
7
 
8
- attr_accessor :klass, :attribute, :subtype, :options, :values, :enum_module
8
+ attr_accessor :klass, :attribute, :subtype, :options, :values,
9
+ :klass_module, :instance_module
9
10
 
10
11
  # Start a new builder of methods for enum values on ActiveRecord::Base
11
12
  def initialize(klass, attribute, options)
@@ -40,15 +41,20 @@ module Torque
40
41
 
41
42
  @values_methods = begin
42
43
  values.map do |val|
43
- val = val.tr('-', '_')
44
- scope = base % val
44
+ key = val.downcase.tr('- ', '__')
45
+ scope = base % key
45
46
  ask = scope + '?'
46
47
  bang = scope + '!'
47
- [val, [scope, ask, bang]]
48
+ [key, [scope, ask, bang, val]]
48
49
  end.to_h
49
50
  end
50
51
  end
51
52
 
53
+ # Check if it's building the methods for sets
54
+ def set_features?
55
+ options[:set_features].present?
56
+ end
57
+
52
58
  # Check if any of the methods that will be created get in conflict
53
59
  # with the base class methods
54
60
  def conflicting?
@@ -56,12 +62,20 @@ module Torque
56
62
  attributes = attribute.pluralize
57
63
 
58
64
  dangerous?(attributes, true)
59
- dangerous?("#{attributes}_options", true)
65
+ dangerous?("#{attributes}_keys", true)
60
66
  dangerous?("#{attributes}_texts", true)
67
+ dangerous?("#{attributes}_options", true)
61
68
  dangerous?("#{attribute}_text")
62
69
 
63
- values_methods.each do |attr, list|
64
- list.map(&method(:dangerous?))
70
+ if set_features?
71
+ dangerous?("has_#{attributes}", true)
72
+ dangerous?("has_any_#{attributes}", true)
73
+ end
74
+
75
+ values_methods.each do |attr, (scope, ask, bang, *)|
76
+ dangerous?(scope, true)
77
+ dangerous?(bang)
78
+ dangerous?(ask)
65
79
  end
66
80
  rescue Interrupt => err
67
81
  raise ArgumentError, <<-MSG.squish
@@ -73,14 +87,16 @@ module Torque
73
87
 
74
88
  # Create all methods needed
75
89
  def build
76
- @enum_module = Module.new
90
+ @klass_module = Module.new
91
+ @instance_module = Module.new
77
92
 
78
93
  plural
79
94
  stringify
80
95
  all_values
96
+ set_scopes if set_features?
81
97
 
82
- klass.include enum_module
83
- klass.extend enum_module::ClassMethods
98
+ klass.extend klass_module
99
+ klass.include instance_module
84
100
  end
85
101
 
86
102
  private
@@ -96,78 +112,99 @@ module Torque
96
112
  raise Interrupt, method_name.to_s
97
113
  end
98
114
  end
115
+ rescue Interrupt => e
116
+ raise e if Torque::PostgreSQL.config.enum.raise_conflicting
117
+ type = class_method ? 'class method' : 'instance method'
118
+ indicator = class_method ? '.' : '#'
119
+
120
+ Torque::PostgreSQL.logger.info(<<~MSG.squish)
121
+ Creating #{class_method} :#{method_name} for enum.
122
+ Overwriting existing method #{klass.name}#{indicator}#{method_name}.
123
+ MSG
99
124
  end
100
125
 
101
126
  # Create the method that allow access to the list of values
102
127
  def plural
103
- attr = attribute
104
- enum_klass = subtype.klass
105
-
106
- # TODO: Rewrite these as string
107
- enum_module.const_set('ClassMethods', Module.new)
108
- enum_module::ClassMethods.module_eval do
109
- # def self.statuses() statuses end
110
- define_method(attr.pluralize) do
111
- enum_klass.values
112
- end
113
-
114
- # def self.statuses_texts() members.map(&:text) end
115
- define_method(attr.pluralize + '_texts') do
116
- enum_klass.members.map do |member|
117
- member.text(attr, self)
118
- end
119
- end
128
+ enum_klass = subtype.klass.name
129
+ klass_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
130
+ def #{attribute.pluralize} # def roles
131
+ ::#{enum_klass}.values # Enum::Roles.values
132
+ end # end
133
+
134
+ def #{attribute.pluralize}_keys # def roles_keys
135
+ ::#{enum_klass}.keys # Enum::Roles.keys
136
+ end # end
137
+
138
+ def #{attribute.pluralize}_texts # def roles_texts
139
+ ::#{enum_klass}.members.map do |member| # Enum::Roles.members do |member|
140
+ member.text('#{attribute}', self) # member.text('role', self)
141
+ end # end
142
+ end # end
143
+
144
+ def #{attribute.pluralize}_options # def roles_options
145
+ #{attribute.pluralize}_texts.zip(::#{enum_klass}.values) # roles_texts.zip(Enum::Roles.values)
146
+ end # end
147
+ RUBY
148
+ end
120
149
 
121
- # def self.statuses_options() statuses_texts.zip(statuses) end
122
- define_method(attr.pluralize + '_options') do
123
- public_send(attr.pluralize + '_texts').zip(enum_klass.values)
124
- end
125
- end
150
+ # Create additional methods when the enum is a set, which needs
151
+ # better ways to check if values are present or not
152
+ def set_scopes
153
+ cast_type = subtype.name.chomp('[]')
154
+ klass_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
155
+ def has_#{attribute.pluralize}(*values) # def has_roles(*values)
156
+ attr = arel_attribute('#{attribute}') # attr = arel_attribute('role')
157
+ where(attr.contains(::Arel.array(values, cast: '#{cast_type}'))) # where(attr.contains(::Arel.array(values, cast: 'roles')))
158
+ end # end
159
+
160
+ def has_any_#{attribute.pluralize}(*values) # def has_roles(*values)
161
+ attr = arel_attribute('#{attribute}') # attr = arel_attribute('role')
162
+ where(attr.overlaps(::Arel.array(values, cast: '#{cast_type}'))) # where(attr.overlaps(::Arel.array(values, cast: 'roles')))
163
+ end # end
164
+ RUBY
126
165
  end
127
166
 
128
167
  # Create the method that turn the attribute value into text using
129
168
  # the model scope
130
169
  def stringify
131
- attr = attribute
132
-
133
- # TODO: Rewrite these as string
134
- enum_module.module_eval do
135
- # def status_text() status.text('status', self) end
136
- define_method("#{attr}_text") { send(attr)&.text(attr, self) }
137
- end
170
+ instance_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
171
+ def #{attribute}_text # def role_text
172
+ #{attribute}.text('#{attribute}', self) # role.text('role', self)
173
+ end # end
174
+ RUBY
138
175
  end
139
176
 
140
177
  # Create all the methods that represent actions related to the
141
178
  # attribute value
142
179
  def all_values
143
- attr = attribute
144
- vals = values_methods
145
-
146
- enum_klass = subtype.klass
147
- model_klass = klass
148
-
149
- # TODO: Rewrite these as string
150
- enum_module.module_eval do
151
- vals.each do |val, list|
152
- # scope :disabled, -> { where(status: 'disabled') }
153
- model_klass.scope list[0], -> do
154
- where(enum_klass.scope(arel_table[attr], val))
155
- end
156
-
157
- # def disabled? status.disabled? end
158
- define_method(list[1]) { send(attr).public_send("#{val}?") }
159
-
160
- # def disabled!
161
- # changed = send(attr).public_send("#{val}!")
162
- # save! if changed && enum_save_on_bang
163
- # true
164
- define_method(list[2]) do
165
- changed = send(attr).public_send("#{val}!")
166
- return save! if changed && enum_save_on_bang
167
- true
168
- end
169
- end
180
+ klass_content = ''
181
+ instance_content = ''
182
+ enum_klass = subtype.klass.name
183
+
184
+ values_methods.each do |key, (scope, ask, bang, val)|
185
+ klass_content += <<-RUBY
186
+ def #{scope} # def admin
187
+ attr = arel_attribute('#{attribute}') # attr = arel_attribute('role')
188
+ where(::#{enum_klass}.scope(attr, '#{val}')) # where(Enum::Roles.scope(attr, 'admin'))
189
+ end # end
190
+ RUBY
191
+
192
+ instance_content += <<-RUBY
193
+ def #{ask} # def admin?
194
+ #{attribute}.#{key}? # role.admin?
195
+ end # end
196
+
197
+ def #{bang} # admin!
198
+ self.#{attribute} = '#{val}' # self.role = 'admin'
199
+ return unless #{attribute}_changed? # return unless role_changed?
200
+ return save! if Torque::PostgreSQL.config.enum.save_on_bang
201
+ true # true
202
+ end # end
203
+ RUBY
170
204
  end
205
+
206
+ klass_module.module_eval(klass_content)
207
+ instance_module.module_eval(instance_content)
171
208
  end
172
209
  end
173
210
  end
@@ -164,7 +164,7 @@ module Torque
164
164
  method_content = define_string_method(method_name, method_content, args)
165
165
 
166
166
  source_module = send("#{type}_module")
167
- source_module.class_eval(method_content)
167
+ source_module.module_eval(method_content)
168
168
  end
169
169
 
170
170
  private
@@ -51,9 +51,14 @@ module Torque
51
51
  end
52
52
  end
53
53
 
54
+ # List of valus as symbols
55
+ def keys
56
+ values.map(&:to_sym)
57
+ end
58
+
54
59
  # Different from values, it returns the list of items already casted
55
60
  def members
56
- values.dup.map(&method(:new))
61
+ values.map(&method(:new))
57
62
  end
58
63
 
59
64
  # Get the list of the values translated by I18n
@@ -10,7 +10,7 @@ module Torque
10
10
  include Enumerable
11
11
 
12
12
  delegate :each, to: :members
13
- delegate :values, :members, :texts, :to_options, :valid?, :size,
13
+ delegate :values, :keys, :members, :texts, :to_options, :valid?, :size,
14
14
  :length, :connection_specification_name, to: :enum_source
15
15
 
16
16
  # Find or create the class that will handle the value
@@ -28,7 +28,10 @@ module Torque
28
28
  # Provide a method on the given class to setup which enum sets will be
29
29
  # manually initialized
30
30
  def include_on(klass, method_name = nil)
31
- Enum.include_on(klass, method_name || Torque::PostgreSQL.config.enum.set_method)
31
+ method_name ||= Torque::PostgreSQL.config.enum.set_method
32
+ Builder.include_on(klass, method_name, Builder::Enum, set_features: true) do |builder|
33
+ defined_enums[builder.attribute.to_sym] = builder.subtype
34
+ end
32
35
  end
33
36
 
34
37
  # The original Enum implementation, for individual values
@@ -73,7 +76,7 @@ module Torque
73
76
 
74
77
  # Build an active record scope for a given atribute agains a value
75
78
  def scope(attribute, value)
76
- attribute.contains(Array.wrap(value))
79
+ attribute.contains(::Arel.array(value, cast: enum_source.type_name))
77
80
  end
78
81
 
79
82
  private
@@ -31,11 +31,12 @@ module Torque
31
31
  end
32
32
 
33
33
  # Fast access to statement build
34
- def build(statement, base, options = nil, bound_attributes = [])
34
+ def build(statement, base, options = nil, bound_attributes = [], join_sources = [])
35
35
  klass = instantiate(statement, base, options)
36
36
  result = klass.build(base)
37
37
 
38
38
  bound_attributes.concat(klass.bound_attributes)
39
+ join_sources.concat(klass.join_sources)
39
40
  result
40
41
  end
41
42
 
@@ -105,7 +106,7 @@ module Torque
105
106
  delegate :config, :table, :table_name, :relation, :configure, :relation_query?,
106
107
  to: :class
107
108
 
108
- attr_reader :bound_attributes
109
+ attr_reader :bound_attributes, :join_sources
109
110
 
110
111
  # Start a new auxiliary statement giving extra options
111
112
  def initialize(*args)
@@ -117,15 +118,21 @@ module Torque
117
118
  @where = options.fetch(:where, {})
118
119
  @select = options.fetch(:select, {})
119
120
  @join_type = options.fetch(:join_type, nil)
121
+
120
122
  @bound_attributes = []
123
+ @join_sources = []
121
124
  end
122
125
 
123
126
  # Build the statement on the given arel and return the WITH statement
124
127
  def build(base)
128
+ @bound_attributes.clear
129
+ @join_sources.clear
130
+
131
+ # Prepare all the data for the statement
125
132
  prepare(base)
126
133
 
127
134
  # Add the join condition to the list
128
- base.joins_values += [build_join(base)]
135
+ @join_sources << build_join(base)
129
136
 
130
137
  # Return the statement with its dependencies
131
138
  [@dependencies, ::Arel::Nodes::As.new(table, build_query(base))]
@@ -205,9 +212,16 @@ module Torque
205
212
  end
206
213
 
207
214
  # Add the scopes defined by the reflection
215
+ # Possibilities:
216
+ # table
217
+ # table, foreign_klass
218
+ # table, foreign_table, foreign_klass
208
219
  if association.respond_to?(:join_scope)
209
- args = [@query.arel_table]
210
- args << base if association.method(:join_scope).arity.eql?(2)
220
+ arity = association.method(:join_scope).arity
221
+ args = [@query.arel_table, foreign_table, base]
222
+ args.delete_at(1) if arity <= 2 # Delete foreign_table
223
+ args.delete_at(1) if arity <= 1 # Delete base (foreign_klass)
224
+
211
225
  @query.merge(association.join_scope(*args))
212
226
  end
213
227
 
@@ -281,7 +295,7 @@ module Torque
281
295
  cte.is_a?(dependent_klass)
282
296
  end
283
297
 
284
- AuxiliaryStatement.build(dependent, base, options, bound_attributes)
298
+ AuxiliaryStatement.build(dependent, base, options, bound_attributes, join_sources)
285
299
  end
286
300
  end
287
301
 
@@ -4,6 +4,12 @@ module Torque
4
4
 
5
5
  # Stores a version check for compatibility purposes
6
6
  AR521 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.1'))
7
+ AR523 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.3'))
8
+
9
+ # Use the same logger as the Active Record one
10
+ def self.logger
11
+ ActiveRecord::Base.logger
12
+ end
7
13
 
8
14
  # Allow nested configurations
9
15
  # :TODO: Rely on +inheritable_copy+ to make nested configurations
@@ -63,6 +69,10 @@ module Torque
63
69
  # database or not
64
70
  enum.save_on_bang = true
65
71
 
72
+ # Indicates if it should raise errors when a generated method would
73
+ # conflict with an existing one
74
+ enum.raise_conflicting = false
75
+
66
76
  # Specify the namespace of each enum type of value
67
77
  enum.namespace = ::Object.const_set('Enum', Module.new)
68
78
 
@@ -17,12 +17,28 @@ module Torque
17
17
  method(:join_keys).arity.eql?(0) ? join_keys : join_keys(klass)
18
18
  end
19
19
 
20
+ # Fix for rails 5.2.3 where the join_scope method is the one now
21
+ # responsible for building the join condition
22
+ if Torque::PostgreSQL::AR523
23
+ def join_scope(table, foreign_table, foreign_klass)
24
+ return super unless connected_through_array?
25
+
26
+ predicate_builder = predicate_builder(table)
27
+ scope_chain_items = join_scopes(table, predicate_builder)
28
+ klass_scope = klass_join_scope(table, predicate_builder)
29
+
30
+ klass_scope.where!(build_id_constraint_between(table, foreign_table))
31
+ klass_scope.where!(type => foreign_klass.polymorphic_name) if type
32
+ klass_scope.where!(klass.send(:type_condition, table)) \
33
+ if klass.finder_needs_type_condition?
34
+
35
+ scope_chain_items.inject(klass_scope, &:merge!)
36
+ end
37
+ end
38
+
20
39
  # Manually build the join constraint
21
40
  def build_join_constraint(table, foreign_table)
22
- klass_attr = table[torque_join_keys.key.to_s]
23
- source_attr = foreign_table[torque_join_keys.foreign_key.to_s]
24
-
25
- result = build_id_constraint(klass_attr, source_attr)
41
+ result = build_id_constraint_between(table, foreign_table)
26
42
  result = table.create_and([result, klass.send(:type_condition, table)]) \
27
43
  if klass.finder_needs_type_condition?
28
44
 
@@ -61,6 +77,13 @@ module Torque
61
77
 
62
78
  private
63
79
 
80
+ def build_id_constraint_between(table, foreign_table)
81
+ klass_attr = table[torque_join_keys.key.to_s]
82
+ source_attr = foreign_table[torque_join_keys.foreign_key.to_s]
83
+
84
+ build_id_constraint(klass_attr, source_attr)
85
+ end
86
+
64
87
  # Prepare a value for an array constraint overlap condition
65
88
  def cast_constraint_to_array(type, value, should_cast)
66
89
  base_ready = type.try(:array) && value.is_a?(AREL_ATTR)
@@ -47,16 +47,16 @@ module Torque
47
47
 
48
48
  # Hook arel build to add the distinct on clause
49
49
  def build_arel(*)
50
- subqueries = build_auxiliary_statements
51
- return super if subqueries.nil?
52
- super.with(subqueries)
50
+ arel = super
51
+ subqueries = build_auxiliary_statements(arel)
52
+ subqueries.nil? ? arel : arel.with(subqueries)
53
53
  end
54
54
 
55
55
  # Build all necessary data for auxiliary statements
56
- def build_auxiliary_statements
57
- return unless self.auxiliary_statements_values.present?
58
- self.auxiliary_statements_values.map do |klass|
59
- klass.build(self)
56
+ def build_auxiliary_statements(arel)
57
+ return unless auxiliary_statements_values.present?
58
+ auxiliary_statements_values.map do |klass|
59
+ klass.build(self).tap { arel.join_sources.concat(klass.join_sources) }
60
60
  end
61
61
  end
62
62
 
@@ -11,6 +11,7 @@ module Torque
11
11
  @data_sources_model_names = {}
12
12
  @inheritance_dependencies = {}
13
13
  @inheritance_associations = {}
14
+ @inheritance_loaded = false
14
15
  end
15
16
 
16
17
  def initialize_dup(*) # :nodoc:
@@ -22,16 +23,16 @@ module Torque
22
23
 
23
24
  def encode_with(coder) # :nodoc:
24
25
  super
25
- coder["data_sources_model_names"] = @data_sources_model_names
26
- coder["inheritance_dependencies"] = @inheritance_dependencies
27
- coder["inheritance_associations"] = @inheritance_associations
26
+ coder['data_sources_model_names'] = @data_sources_model_names
27
+ coder['inheritance_dependencies'] = @inheritance_dependencies
28
+ coder['inheritance_associations'] = @inheritance_associations
28
29
  end
29
30
 
30
31
  def init_with(coder) # :nodoc:
31
32
  super
32
- @data_sources_model_names = coder["data_sources_model_names"]
33
- @inheritance_dependencies = coder["inheritance_dependencies"]
34
- @inheritance_associations = coder["inheritance_associations"]
33
+ @data_sources_model_names = coder['data_sources_model_names']
34
+ @inheritance_dependencies = coder['inheritance_dependencies']
35
+ @inheritance_associations = coder['inheritance_associations']
35
36
  end
36
37
 
37
38
  def add(table_name, *) # :nodoc:
@@ -41,6 +42,7 @@ module Torque
41
42
  if @data_sources.key?(table_name)
42
43
  @inheritance_dependencies.clear
43
44
  @inheritance_associations.clear
45
+ @inheritance_loaded = false
44
46
  end
45
47
  end
46
48
 
@@ -49,6 +51,7 @@ module Torque
49
51
  @data_sources_model_names.clear
50
52
  @inheritance_dependencies.clear
51
53
  @inheritance_associations.clear
54
+ @inheritance_loaded = false
52
55
  end
53
56
 
54
57
  def size # :nodoc:
@@ -71,10 +74,12 @@ module Torque
71
74
  @inheritance_dependencies,
72
75
  @inheritance_associations,
73
76
  @data_sources_model_names,
77
+ @inheritance_loaded,
74
78
  ]
75
79
  end
76
80
 
77
81
  def marshal_load(array) # :nodoc:
82
+ @inheritance_loaded = array.pop
78
83
  @data_sources_model_names = array.pop
79
84
  @inheritance_associations = array.pop
80
85
  @inheritance_dependencies = array.pop
@@ -101,13 +106,13 @@ module Torque
101
106
  end
102
107
 
103
108
  # Try to find a model based on a given table
104
- def lookup_model(table_name, scopred_class = '')
105
- scopred_class = scopred_class.name if scopred_class.is_a?(Class)
109
+ def lookup_model(table_name, scoped_class = '')
110
+ scoped_class = scoped_class.name if scoped_class.is_a?(Class)
106
111
  return @data_sources_model_names[table_name] \
107
112
  if @data_sources_model_names.key?(table_name)
108
113
 
109
114
  # Get all the possible scopes
110
- scopes = scopred_class.scan(/(?:::)?[A-Z][a-z]+/)
115
+ scopes = scoped_class.scan(/(?:::)?[A-Z][a-z]+/)
111
116
  scopes.unshift('Object::')
112
117
 
113
118
  # Consider the maximum namespaced possible model name
@@ -164,14 +169,17 @@ module Torque
164
169
  # Reload information about tables inheritance and dependencies, uses a
165
170
  # cache to not perform additional checkes
166
171
  def reload_inheritance_data!
167
- return if @inheritance_dependencies.present?
172
+ return if @inheritance_loaded
168
173
  @inheritance_dependencies = connection.inherited_tables
169
174
  @inheritance_associations = generate_associations
175
+ @inheritance_loaded = true
170
176
  end
171
177
 
172
178
  # Calculates the inverted dependency (association), where even indirect
173
179
  # inheritance comes up in the list
174
180
  def generate_associations
181
+ return {} if @inheritance_dependencies.empty?
182
+
175
183
  result = Hash.new{ |h, k| h[k] = [] }
176
184
  masters = @inheritance_dependencies.values.flatten.uniq
177
185
 
@@ -200,7 +208,7 @@ module Torque
200
208
  super
201
209
  @data_sources_model_names = Torque::PostgreSQL.config
202
210
  .irregular_models.slice(*@data_sources.keys).map do |table_name, model_name|
203
- [table_name, model_name.constantize]
211
+ [table_name, (model_name.is_a?(Class) ? model_name : model_name.constantize)]
204
212
  end.to_h
205
213
  end
206
214
 
@@ -31,21 +31,21 @@ module Torque
31
31
  if inherited_tables.present?
32
32
  stream.puts " # These are tables that has inheritance"
33
33
  inherited_tables.each do |table_name, inherits|
34
- unless ignored?(table_name)
35
- sub_stream = StringIO.new
36
- table(table_name, sub_stream)
37
-
38
- # Add the inherits setting
39
- sub_stream.rewind
40
- inherits.map!(&:to_sym)
41
- inherits = inherits.first if inherits.size === 1
42
- inherits = ", inherits: #{inherits.inspect} do |t|"
43
- table_dump = sub_stream.read.gsub(/ do \|t\|$/, inherits)
44
-
45
- # Ensure bodyless definitions
46
- table_dump.gsub!(/do \|t\|\n end/, '')
47
- stream.print table_dump
48
- end
34
+ next if ignored?(table_name)
35
+
36
+ sub_stream = StringIO.new
37
+ table(table_name, sub_stream)
38
+
39
+ # Add the inherits setting
40
+ sub_stream.rewind
41
+ inherits.map!(&:to_sym)
42
+ inherits = inherits.first if inherits.size === 1
43
+ inherits = ", inherits: #{inherits.inspect} do |t|"
44
+ table_dump = sub_stream.read.gsub(/ do \|t\|$/, inherits)
45
+
46
+ # Ensure bodyless definitions
47
+ table_dump.gsub!(/do \|t\|\n end/, '')
48
+ stream.print table_dump
49
49
  end
50
50
  end
51
51
 
@@ -63,7 +63,7 @@ module Torque
63
63
  return unless types.any?
64
64
 
65
65
  stream.puts " # These are user-defined types used on this database"
66
- types.each { |name, type| send(type.to_sym, name, stream) }
66
+ types.sort_by(&:first).each { |name, type| send(type.to_sym, name, stream) }
67
67
  stream.puts
68
68
  rescue => e
69
69
  stream.puts "# Could not dump user-defined types because of following #{e.class}"
@@ -1,5 +1,5 @@
1
1
  module Torque
2
2
  module PostgreSQL
3
- VERSION = '1.1.0'
3
+ VERSION = '1.1.5'
4
4
  end
5
5
  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: 1.1.0
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-03 00:00:00.000000000 Z
11
+ date: 2020-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -260,8 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
260
260
  - !ruby/object:Gem::Version
261
261
  version: 1.8.11
262
262
  requirements: []
263
- rubyforge_project:
264
- rubygems_version: 2.6.14
263
+ rubygems_version: 3.1.4
265
264
  signing_key:
266
265
  specification_version: 4
267
266
  summary: ActiveRecord extension to access PostgreSQL advanced resources