torque-postgresql 1.1.0 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- 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