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 +5 -5
- data/Rakefile +5 -2
- data/lib/torque/postgresql/attributes.rb +0 -16
- data/lib/torque/postgresql/attributes/builder.rb +2 -2
- data/lib/torque/postgresql/attributes/builder/enum.rb +103 -66
- data/lib/torque/postgresql/attributes/builder/period.rb +1 -1
- data/lib/torque/postgresql/attributes/enum.rb +6 -1
- data/lib/torque/postgresql/attributes/enum_set.rb +6 -3
- data/lib/torque/postgresql/auxiliary_statement.rb +20 -6
- data/lib/torque/postgresql/config.rb +10 -0
- data/lib/torque/postgresql/reflection/abstract_reflection.rb +27 -4
- data/lib/torque/postgresql/relation/auxiliary_statement.rb +7 -7
- data/lib/torque/postgresql/schema_cache.rb +19 -11
- data/lib/torque/postgresql/schema_dumper.rb +16 -16
- data/lib/torque/postgresql/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 91a42a9a04ba195e57f4b87af2931a6ecf82e9d58a4acec84b95350404ee4977
|
4
|
+
data.tar.gz: e4fce1b312a40bf6e98a1f8bee8351795a45a5afddf25ce0f7765cd6c01d89ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 '
|
18
|
-
task :
|
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,
|
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
|
-
|
44
|
-
scope = base %
|
44
|
+
key = val.downcase.tr('- ', '__')
|
45
|
+
scope = base % key
|
45
46
|
ask = scope + '?'
|
46
47
|
bang = scope + '!'
|
47
|
-
[
|
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}
|
65
|
+
dangerous?("#{attributes}_keys", true)
|
60
66
|
dangerous?("#{attributes}_texts", true)
|
67
|
+
dangerous?("#{attributes}_options", true)
|
61
68
|
dangerous?("#{attribute}_text")
|
62
69
|
|
63
|
-
|
64
|
-
|
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
|
-
@
|
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.
|
83
|
-
klass.
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
#
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
#
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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.
|
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.
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
210
|
-
args
|
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
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
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
|
58
|
-
|
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[
|
26
|
-
coder[
|
27
|
-
coder[
|
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[
|
33
|
-
@inheritance_dependencies = coder[
|
34
|
-
@inheritance_associations = coder[
|
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,
|
105
|
-
|
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 =
|
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 @
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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}"
|
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.
|
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:
|
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
|
-
|
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
|