torque-postgresql 1.1.7 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/torque/postgresql.rb +0 -2
- data/lib/torque/postgresql/adapter.rb +7 -1
- data/lib/torque/postgresql/adapter/database_statements.rb +6 -15
- data/lib/torque/postgresql/adapter/oid.rb +3 -1
- data/lib/torque/postgresql/adapter/oid/box.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/circle.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/enum.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/enum_set.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/interval.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/line.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/range.rb +2 -0
- data/lib/torque/postgresql/adapter/oid/segment.rb +2 -0
- data/lib/torque/postgresql/adapter/quoting.rb +2 -0
- data/lib/torque/postgresql/adapter/schema_creation.rb +20 -23
- data/lib/torque/postgresql/adapter/schema_definitions.rb +9 -21
- data/lib/torque/postgresql/adapter/schema_dumper.rb +76 -11
- data/lib/torque/postgresql/adapter/schema_statements.rb +4 -12
- data/lib/torque/postgresql/arel/infix_operation.rb +5 -1
- data/lib/torque/postgresql/arel/join_source.rb +2 -0
- data/lib/torque/postgresql/arel/nodes.rb +2 -0
- data/lib/torque/postgresql/arel/operations.rb +2 -0
- data/lib/torque/postgresql/arel/select_manager.rb +2 -0
- data/lib/torque/postgresql/arel/visitors.rb +6 -3
- data/lib/torque/postgresql/associations.rb +0 -3
- data/lib/torque/postgresql/associations/association.rb +5 -1
- data/lib/torque/postgresql/associations/association_scope.rb +20 -60
- data/lib/torque/postgresql/associations/belongs_to_many_association.rb +5 -1
- data/lib/torque/postgresql/associations/builder/belongs_to_many.rb +2 -0
- data/lib/torque/postgresql/associations/builder/has_many.rb +2 -0
- data/lib/torque/postgresql/associations/preloader.rb +0 -32
- data/lib/torque/postgresql/associations/preloader/association.rb +42 -10
- data/lib/torque/postgresql/attributes/builder.rb +2 -0
- data/lib/torque/postgresql/attributes/builder/enum.rb +5 -3
- data/lib/torque/postgresql/attributes/builder/period.rb +6 -4
- data/lib/torque/postgresql/attributes/enum.rb +5 -10
- data/lib/torque/postgresql/attributes/enum_set.rb +2 -0
- data/lib/torque/postgresql/attributes/lazy.rb +3 -1
- data/lib/torque/postgresql/attributes/period.rb +2 -0
- data/lib/torque/postgresql/autosave_association.rb +9 -3
- data/lib/torque/postgresql/auxiliary_statement.rb +3 -13
- data/lib/torque/postgresql/auxiliary_statement/settings.rb +2 -0
- data/lib/torque/postgresql/base.rb +2 -0
- data/lib/torque/postgresql/coder.rb +6 -5
- data/lib/torque/postgresql/collector.rb +2 -0
- data/lib/torque/postgresql/config.rb +3 -4
- data/lib/torque/postgresql/geometry_builder.rb +2 -0
- data/lib/torque/postgresql/i18n.rb +2 -0
- data/lib/torque/postgresql/inheritance.rb +15 -17
- data/lib/torque/postgresql/migration/command_recorder.rb +2 -0
- data/lib/torque/postgresql/railtie.rb +2 -0
- data/lib/torque/postgresql/reflection.rb +2 -0
- data/lib/torque/postgresql/reflection/abstract_reflection.rb +28 -26
- data/lib/torque/postgresql/reflection/association_reflection.rb +2 -0
- data/lib/torque/postgresql/reflection/belongs_to_many_reflection.rb +6 -26
- data/lib/torque/postgresql/reflection/has_many_reflection.rb +2 -0
- data/lib/torque/postgresql/reflection/runtime_reflection.rb +2 -0
- data/lib/torque/postgresql/reflection/through_reflection.rb +2 -0
- data/lib/torque/postgresql/relation.rb +10 -11
- data/lib/torque/postgresql/relation/auxiliary_statement.rb +7 -8
- data/lib/torque/postgresql/relation/distinct_on.rb +3 -1
- data/lib/torque/postgresql/relation/inheritance.rb +2 -0
- data/lib/torque/postgresql/relation/merger.rb +2 -0
- data/lib/torque/postgresql/schema_cache.rb +2 -0
- data/lib/torque/postgresql/version.rb +3 -1
- data/spec/en.yml +19 -0
- data/spec/factories/authors.rb +6 -0
- data/spec/factories/comments.rb +13 -0
- data/spec/factories/posts.rb +6 -0
- data/spec/factories/tags.rb +5 -0
- data/spec/factories/texts.rb +5 -0
- data/spec/factories/users.rb +6 -0
- data/spec/factories/videos.rb +5 -0
- data/spec/mocks/cache_query.rb +16 -0
- data/spec/mocks/create_table.rb +35 -0
- data/spec/models/activity.rb +3 -0
- data/spec/models/activity_book.rb +4 -0
- data/spec/models/activity_post.rb +7 -0
- data/spec/models/activity_post/sample.rb +4 -0
- data/spec/models/author.rb +4 -0
- data/spec/models/author_journalist.rb +4 -0
- data/spec/models/comment.rb +3 -0
- data/spec/models/course.rb +2 -0
- data/spec/models/geometry.rb +2 -0
- data/spec/models/guest_comment.rb +4 -0
- data/spec/models/post.rb +6 -0
- data/spec/models/tag.rb +2 -0
- data/spec/models/text.rb +2 -0
- data/spec/models/time_keeper.rb +2 -0
- data/spec/models/user.rb +8 -0
- data/spec/models/video.rb +2 -0
- data/spec/schema.rb +141 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/tests/arel_spec.rb +74 -0
- data/spec/tests/auxiliary_statement_spec.rb +593 -0
- data/spec/tests/belongs_to_many_spec.rb +246 -0
- data/spec/tests/coder_spec.rb +367 -0
- data/spec/tests/collector_spec.rb +59 -0
- data/spec/tests/distinct_on_spec.rb +65 -0
- data/spec/tests/enum_set_spec.rb +306 -0
- data/spec/tests/enum_spec.rb +628 -0
- data/spec/tests/geometric_builder_spec.rb +221 -0
- data/spec/tests/has_many_spec.rb +400 -0
- data/spec/tests/interval_spec.rb +167 -0
- data/spec/tests/lazy_spec.rb +24 -0
- data/spec/tests/period_spec.rb +954 -0
- data/spec/tests/quoting_spec.rb +24 -0
- data/spec/tests/range_spec.rb +36 -0
- data/spec/tests/relation_spec.rb +57 -0
- data/spec/tests/table_inheritance_spec.rb +416 -0
- metadata +102 -14
- data/lib/torque/postgresql/associations/join_dependency/join_association.rb +0 -15
- data/lib/torque/postgresql/schema_dumper.rb +0 -91
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
module AutosaveAssociation
|
@@ -8,9 +10,13 @@ module Torque
|
|
8
10
|
save_method = :"autosave_associated_records_for_#{reflection.name}"
|
9
11
|
define_non_cyclic_method(save_method) { save_belongs_to_many_array(reflection) }
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
if PostgreSQL::AR610
|
14
|
+
around_save(:around_save_collection_association)
|
15
|
+
else
|
16
|
+
before_save(:before_save_collection_association)
|
17
|
+
after_save(:after_save_collection_association) if ::ActiveRecord::Base
|
18
|
+
.instance_methods.include?(:after_save_collection_association)
|
19
|
+
end
|
14
20
|
|
15
21
|
before_create(save_method)
|
16
22
|
before_update(save_method)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'auxiliary_statement/settings'
|
2
4
|
|
3
5
|
module Torque
|
@@ -211,19 +213,7 @@ module Torque
|
|
211
213
|
foreign_table = ::Arel::Table.new(association.plural_name)
|
212
214
|
end
|
213
215
|
|
214
|
-
|
215
|
-
# Possibilities:
|
216
|
-
# table
|
217
|
-
# table, foreign_klass
|
218
|
-
# table, foreign_table, foreign_klass
|
219
|
-
if association.respond_to?(:join_scope)
|
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
|
-
|
225
|
-
@query.merge(association.join_scope(*args))
|
226
|
-
end
|
216
|
+
@query.merge(association.join_scope(@query.arel_table, foreign_table, base))
|
227
217
|
|
228
218
|
# Add the join constraints
|
229
219
|
constraint = association.build_join_constraint(table, foreign_table)
|
@@ -1,15 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
module Coder
|
4
6
|
|
5
7
|
# This class represents an Record to be encoded, instead of a literal Array
|
6
|
-
|
7
|
-
end
|
8
|
+
Record = Class.new(Array)
|
8
9
|
|
9
10
|
class << self
|
10
11
|
|
11
12
|
NEED_QUOTE_FOR = /[\\"(){}, \t\n\r\v\f]/m
|
12
|
-
DELIMITER = ','
|
13
|
+
DELIMITER = ','
|
13
14
|
|
14
15
|
# This method replace the +read_array+ method from PG gem
|
15
16
|
# See https://github.com/ged/ruby-pg/blob/master/ext/pg_text_decoder.c#L177
|
@@ -33,7 +34,7 @@ module Torque
|
|
33
34
|
quoted = 0
|
34
35
|
escaped = false
|
35
36
|
result = []
|
36
|
-
part =
|
37
|
+
part = String.new
|
37
38
|
|
38
39
|
# Always start getting the non-collection character, the second char
|
39
40
|
stream.getc if stream.pos == 0
|
@@ -60,7 +61,7 @@ module Torque
|
|
60
61
|
|
61
62
|
escaped = false
|
62
63
|
quoted = 0
|
63
|
-
part =
|
64
|
+
part = String.new
|
64
65
|
|
65
66
|
when c == '"'
|
66
67
|
quoted = 1
|
@@ -1,12 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
include ActiveSupport::Configurable
|
4
6
|
|
5
7
|
# Stores a version check for compatibility purposes
|
6
|
-
|
7
|
-
AR520 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.0'))
|
8
|
-
AR521 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.1'))
|
9
|
-
AR523 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.3'))
|
8
|
+
AR610 = (ActiveRecord.gem_version >= Gem::Version.new('6.1.0'))
|
10
9
|
|
11
10
|
# Use the same logger as the Active Record one
|
12
11
|
def self.logger
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
InheritanceError = Class.new(ArgumentError)
|
@@ -18,14 +20,7 @@ module Torque
|
|
18
20
|
klass.find(self.id)
|
19
21
|
end
|
20
22
|
|
21
|
-
private
|
22
|
-
|
23
|
-
def using_single_table_inheritance?(record) # :nodoc:
|
24
|
-
self.class.physically_inherited? || super
|
25
|
-
end
|
26
|
-
|
27
23
|
module ClassMethods
|
28
|
-
|
29
24
|
delegate :_auto_cast_attribute, :_record_class_attribute, to: ActiveRecord::Relation
|
30
25
|
|
31
26
|
# Get a full list of all attributes from a model and all its dependents
|
@@ -101,9 +96,10 @@ module Torque
|
|
101
96
|
|
102
97
|
# Get the final decorated table, regardless of any special condition
|
103
98
|
def decorated_table_name
|
104
|
-
|
105
|
-
|
106
|
-
contained =
|
99
|
+
parent_class = try(:module_parent) || try(:parent)
|
100
|
+
if parent_class < Base && !parent_class.abstract_class?
|
101
|
+
contained = parent_class.table_name
|
102
|
+
contained = contained.singularize if parent_class.pluralize_table_names
|
107
103
|
contained += "_"
|
108
104
|
end
|
109
105
|
|
@@ -144,17 +140,19 @@ module Torque
|
|
144
140
|
|
145
141
|
private
|
146
142
|
|
147
|
-
def
|
143
|
+
def instantiate_instance_of(klass, attributes, column_types = {}, &block)
|
144
|
+
return super unless klass.physically_inheritances?
|
145
|
+
|
148
146
|
auto_cast = _auto_cast_attribute.to_s
|
149
147
|
record_class = _record_class_attribute.to_s
|
148
|
+
return super unless attributes.key?(record_class) &&
|
149
|
+
attributes.delete(auto_cast) && attributes[record_class] != table_name
|
150
150
|
|
151
|
-
|
152
|
-
|
151
|
+
klass = casted_dependents[attributes[record_class]]
|
152
|
+
raise_unable_to_cast(attributes[record_class]) if klass.nil?
|
153
|
+
filter_attributes_for_cast(attributes, klass)
|
153
154
|
|
154
|
-
klass
|
155
|
-
raise_unable_to_cast(record[record_class]) if klass.nil?
|
156
|
-
filter_attributes_for_cast(record, klass)
|
157
|
-
klass
|
155
|
+
super(klass, attributes, column_types, &block)
|
158
156
|
end
|
159
157
|
|
160
158
|
# Filter the record attributes to be loaded to not included those from
|
@@ -1,39 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
module Reflection
|
4
6
|
module AbstractReflection
|
5
7
|
AREL_ATTR = ::Arel::Attributes::Attribute
|
6
8
|
|
7
|
-
ARR_NO_CAST = 'bigint'
|
8
|
-
ARR_CAST = 'bigint[]'
|
9
|
+
ARR_NO_CAST = 'bigint'
|
10
|
+
ARR_CAST = 'bigint[]'
|
9
11
|
|
10
12
|
# Check if the foreign key actually exists
|
11
13
|
def connected_through_array?
|
12
14
|
false
|
13
15
|
end
|
14
16
|
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
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?
|
17
|
+
# Fix where the join_scope method is the one now responsible for
|
18
|
+
# building the join condition
|
19
|
+
def join_scope(table, foreign_table, foreign_klass)
|
20
|
+
return super unless connected_through_array?
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
predicate_builder = predicate_builder(table)
|
23
|
+
scope_chain_items = join_scopes(table, predicate_builder)
|
24
|
+
klass_scope = klass_join_scope(table, predicate_builder)
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
klass_scope.where!(build_id_constraint_between(table, foreign_table))
|
27
|
+
klass_scope.where!(type => foreign_klass.polymorphic_name) if type
|
28
|
+
klass_scope.where!(klass.send(:type_condition, table)) \
|
29
|
+
if klass.finder_needs_type_condition?
|
34
30
|
|
35
|
-
|
36
|
-
end
|
31
|
+
scope_chain_items.inject(klass_scope, &:merge!)
|
37
32
|
end
|
38
33
|
|
39
34
|
# Manually build the join constraint
|
@@ -50,9 +45,9 @@ module Torque
|
|
50
45
|
return klass_attr.eq(source_attr) unless connected_through_array?
|
51
46
|
|
52
47
|
# Klass and key are associated with the reflection Class
|
53
|
-
klass_type = klass.columns_hash[
|
48
|
+
klass_type = klass.columns_hash[join_keys.key.to_s]
|
54
49
|
# active_record and foreign_key are associated with the source Class
|
55
|
-
source_type = active_record.columns_hash[
|
50
|
+
source_type = active_record.columns_hash[join_keys.foreign_key.to_s]
|
56
51
|
|
57
52
|
# If both are attributes but the left side is not an array, and the
|
58
53
|
# right side is, use the ANY operation
|
@@ -75,11 +70,18 @@ module Torque
|
|
75
70
|
klass_attr.overlaps(source_attr)
|
76
71
|
end
|
77
72
|
|
73
|
+
if PostgreSQL::AR610
|
74
|
+
# TODO: Deprecate this method
|
75
|
+
def join_keys
|
76
|
+
OpenStruct.new(key: join_primary_key, foreign_key: join_foreign_key)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
78
80
|
private
|
79
81
|
|
80
82
|
def build_id_constraint_between(table, foreign_table)
|
81
|
-
klass_attr = table[
|
82
|
-
source_attr = foreign_table[
|
83
|
+
klass_attr = table[join_primary_key]
|
84
|
+
source_attr = foreign_table[join_foreign_key]
|
83
85
|
|
84
86
|
build_id_constraint(klass_attr, source_attr)
|
85
87
|
end
|
@@ -105,6 +107,7 @@ module Torque
|
|
105
107
|
# returns either +nil+ or the inverse association name that it finds.
|
106
108
|
def automatic_inverse_of
|
107
109
|
return super unless connected_through_array?
|
110
|
+
|
108
111
|
if can_find_inverse_of_automatically?(self)
|
109
112
|
inverse_name = options[:as] || active_record.name.demodulize
|
110
113
|
inverse_name = ActiveSupport::Inflector.underscore(inverse_name)
|
@@ -123,7 +126,6 @@ module Torque
|
|
123
126
|
valid_inverse_reflection?(reflection)
|
124
127
|
end
|
125
128
|
end
|
126
|
-
|
127
129
|
end
|
128
130
|
|
129
131
|
::ActiveRecord::Reflection::AbstractReflection.prepend(AbstractReflection)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Torque
|
2
4
|
module PostgreSQL
|
3
5
|
module Reflection
|
@@ -34,38 +36,16 @@ module Torque
|
|
34
36
|
@active_record_primary_key ||= options[:primary_key] || derive_primary_key
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
JoinKeys.new(join_pk, join_fk)
|
40
|
-
end
|
39
|
+
def join_primary_key(*)
|
40
|
+
active_record_primary_key
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
active_record_primary_key
|
46
|
-
end
|
47
|
-
|
48
|
-
def join_foreign_key
|
49
|
-
foreign_key
|
50
|
-
end
|
51
|
-
else
|
52
|
-
def join_id_for(owner)
|
53
|
-
owner[foreign_key]
|
54
|
-
end
|
43
|
+
def join_foreign_key
|
44
|
+
foreign_key
|
55
45
|
end
|
56
46
|
|
57
47
|
private
|
58
48
|
|
59
|
-
unless PostgreSQL::AR520
|
60
|
-
def join_pk(*)
|
61
|
-
active_record_primary_key
|
62
|
-
end
|
63
|
-
|
64
|
-
def join_fk
|
65
|
-
foreign_key
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
49
|
def derive_primary_key
|
70
50
|
klass.primary_key
|
71
51
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'relation/distinct_on'
|
2
4
|
require_relative 'relation/auxiliary_statement'
|
3
5
|
require_relative 'relation/inheritance'
|
@@ -48,15 +50,12 @@ module Torque
|
|
48
50
|
when String
|
49
51
|
::Arel.sql(klass.send(:sanitize_sql, item.to_s))
|
50
52
|
when Symbol
|
51
|
-
base ? base.
|
53
|
+
base ? base.arel_table[item] : klass.arel_table[item]
|
52
54
|
when Array
|
53
55
|
resolve_column(item, base)
|
54
56
|
when Hash
|
55
|
-
raise ArgumentError,
|
56
|
-
item.map
|
57
|
-
other_list = [other_list] unless other_list.kind_of? Enumerable
|
58
|
-
resolve_column(other_list, key)
|
59
|
-
end
|
57
|
+
raise ArgumentError, 'Unsupported Hash for attributes on third level' if base
|
58
|
+
item.map { |key, other_list| resolve_column(other_list, key) }
|
60
59
|
else
|
61
60
|
raise ArgumentError, "Unsupported argument type: #{value} (#{value.class})"
|
62
61
|
end
|
@@ -68,8 +67,8 @@ module Torque
|
|
68
67
|
return unless relation
|
69
68
|
|
70
69
|
table = predicate_builder.send(:table)
|
71
|
-
if table.associated_with?(relation)
|
72
|
-
table.associated_table(relation).send(:klass)
|
70
|
+
if table.associated_with?(relation.to_s)
|
71
|
+
table.associated_table(relation.to_s).send(:klass)
|
73
72
|
else
|
74
73
|
raise ArgumentError, "Relation for #{relation} not found on #{klass}"
|
75
74
|
end
|
@@ -138,10 +137,10 @@ module Torque
|
|
138
137
|
ActiveRecord::Relation::SINGLE_VALUE_METHODS += Relation::SINGLE_VALUE_METHODS
|
139
138
|
ActiveRecord::Relation::MULTI_VALUE_METHODS += Relation::MULTI_VALUE_METHODS
|
140
139
|
ActiveRecord::Relation::VALUE_METHODS += Relation::VALUE_METHODS
|
141
|
-
ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES += [
|
142
|
-
|
140
|
+
ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES += %i[cast_records itself_only
|
141
|
+
distinct_on auxiliary_statements]
|
143
142
|
|
144
|
-
|
143
|
+
unless AR610
|
145
144
|
Relation::SINGLE_VALUE_METHODS.each do |value|
|
146
145
|
ActiveRecord::QueryMethods::DEFAULT_VALUES[value] = nil \
|
147
146
|
if ActiveRecord::QueryMethods::DEFAULT_VALUES[value].nil?
|