torque-postgresql 4.0.1 → 4.1.1
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 +4 -4
- data/Rakefile +52 -0
- data/lib/generators/torque/skill_generator.rb +17 -0
- data/lib/generators/torque/templates/trigger.sql.erb +3 -0
- data/lib/generators/torque/trigger_generator.rb +13 -0
- data/lib/torque/postgresql/adapter/database_statements.rb +98 -7
- data/lib/torque/postgresql/adapter/inheritance_statements.rb +297 -0
- data/lib/torque/postgresql/adapter/oid/array.rb +13 -0
- data/lib/torque/postgresql/adapter/oid/box.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/circle.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/composite.rb +117 -0
- data/lib/torque/postgresql/adapter/oid/enum.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/enum_set.rb +2 -2
- data/lib/torque/postgresql/adapter/oid/interval.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/line.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/lquery.rb +70 -0
- data/lib/torque/postgresql/adapter/oid/ltree.rb +111 -0
- data/lib/torque/postgresql/adapter/oid/segment.rb +1 -1
- data/lib/torque/postgresql/adapter/oid/struct.rb +150 -0
- data/lib/torque/postgresql/adapter/oid/struct_list.rb +52 -0
- data/lib/torque/postgresql/adapter/oid/struct_set.rb +38 -0
- data/lib/torque/postgresql/adapter/oid.rb +13 -0
- data/lib/torque/postgresql/adapter/quoting.rb +11 -2
- data/lib/torque/postgresql/adapter/schema_definitions.rb +51 -0
- data/lib/torque/postgresql/adapter/schema_dumper.rb +27 -0
- data/lib/torque/postgresql/adapter/schema_statements.rb +207 -0
- data/lib/torque/postgresql/adapter.rb +2 -5
- data/lib/torque/postgresql/arel/nodes.rb +114 -1
- data/lib/torque/postgresql/arel/visitors.rb +65 -8
- data/lib/torque/postgresql/associations/join_dependency.rb +55 -0
- data/lib/torque/postgresql/associations.rb +3 -0
- data/lib/torque/postgresql/attributes/base.rb +97 -0
- data/lib/torque/postgresql/attributes/composite.rb +98 -0
- data/lib/torque/postgresql/attributes/enum.rb +13 -7
- data/lib/torque/postgresql/attributes/lquery.rb +120 -0
- data/lib/torque/postgresql/attributes/ltree.rb +121 -0
- data/lib/torque/postgresql/attributes/simple_enum.rb +72 -0
- data/lib/torque/postgresql/attributes/struct.rb +137 -0
- data/lib/torque/postgresql/base.rb +26 -15
- data/lib/torque/postgresql/config.rb +100 -15
- data/lib/torque/postgresql/geometry_builder.rb +4 -10
- data/lib/torque/postgresql/inheritance/expander.rb +66 -0
- data/lib/torque/postgresql/inheritance/record.rb +52 -0
- data/lib/torque/postgresql/inheritance.rb +141 -68
- data/lib/torque/postgresql/migration/command_recorder.rb +76 -0
- data/lib/torque/postgresql/predicate_builder/arel_attribute_handler.rb +1 -1
- data/lib/torque/postgresql/predicate_builder/array_handler.rb +16 -8
- data/lib/torque/postgresql/predicate_builder/composite_handler.rb +122 -0
- data/lib/torque/postgresql/predicate_builder/ltree_handler.rb +112 -0
- data/lib/torque/postgresql/predicate_builder/struct_handler.rb +88 -0
- data/lib/torque/postgresql/predicate_builder.rb +53 -0
- data/lib/torque/postgresql/predicate_table.rb +61 -0
- data/lib/torque/postgresql/railtie.rb +52 -0
- data/lib/torque/postgresql/relation/auxiliary_statement.rb +7 -3
- data/lib/torque/postgresql/relation/buckets.rb +2 -1
- data/lib/torque/postgresql/relation/cross_join.rb +193 -0
- data/lib/torque/postgresql/relation/inheritance.rb +145 -28
- data/lib/torque/postgresql/relation/join_series.rb +1 -0
- data/lib/torque/postgresql/relation/merger.rb +30 -5
- data/lib/torque/postgresql/relation/segments.rb +140 -0
- data/lib/torque/postgresql/relation.rb +32 -12
- data/lib/torque/postgresql/schema_cache.rb +1 -0
- data/lib/torque/postgresql/validations.rb +29 -0
- data/lib/torque/postgresql/version.rb +1 -1
- data/lib/torque/postgresql/versioned_commands/command_migration.rb +24 -1
- data/lib/torque/postgresql/versioned_commands.rb +39 -0
- data/lib/torque/postgresql.rb +4 -0
- data/sig/generators/torque/function_generator.rbs +9 -0
- data/sig/generators/torque/skill_generator.rbs +7 -0
- data/sig/generators/torque/trigger_generator.rbs +9 -0
- data/sig/generators/torque/type_generator.rbs +9 -0
- data/sig/generators/torque/view_generator.rbs +9 -0
- data/sig/manifest.yaml +7 -0
- data/sig/torque/postgresql/adapter/database_statements.rbs +42 -0
- data/sig/torque/postgresql/adapter/inheritance_statements.rbs +36 -0
- data/sig/torque/postgresql/adapter/oid/array.rbs +20 -0
- data/sig/torque/postgresql/adapter/oid/box.rbs +28 -0
- data/sig/torque/postgresql/adapter/oid/circle.rbs +33 -0
- data/sig/torque/postgresql/adapter/oid/composite.rbs +35 -0
- data/sig/torque/postgresql/adapter/oid/enum.rbs +28 -0
- data/sig/torque/postgresql/adapter/oid/enum_set.rbs +19 -0
- data/sig/torque/postgresql/adapter/oid/interval.rbs +20 -0
- data/sig/torque/postgresql/adapter/oid/line.rbs +33 -0
- data/sig/torque/postgresql/adapter/oid/lquery.rbs +21 -0
- data/sig/torque/postgresql/adapter/oid/ltree.rbs +32 -0
- data/sig/torque/postgresql/adapter/oid/range.rbs +28 -0
- data/sig/torque/postgresql/adapter/oid/segment.rbs +38 -0
- data/sig/torque/postgresql/adapter/oid/struct.rbs +41 -0
- data/sig/torque/postgresql/adapter/oid/struct_list.rbs +20 -0
- data/sig/torque/postgresql/adapter/oid/struct_set.rbs +18 -0
- data/sig/torque/postgresql/adapter/oid.rbs +9 -0
- data/sig/torque/postgresql/adapter/quoting.rbs +20 -0
- data/sig/torque/postgresql/adapter/schema_creation.rbs +13 -0
- data/sig/torque/postgresql/adapter/schema_definitions.rbs +55 -0
- data/sig/torque/postgresql/adapter/schema_dumper.rbs +37 -0
- data/sig/torque/postgresql/adapter/schema_overrides.rbs +46 -0
- data/sig/torque/postgresql/adapter/schema_statements.rbs +50 -0
- data/sig/torque/postgresql/adapter.rbs +24 -0
- data/sig/torque/postgresql/arel/infix_operation.rbs +79 -0
- data/sig/torque/postgresql/arel/join_source.rbs +19 -0
- data/sig/torque/postgresql/arel/nodes.rbs +83 -0
- data/sig/torque/postgresql/arel/operations.rbs +28 -0
- data/sig/torque/postgresql/arel/select_manager.rbs +15 -0
- data/sig/torque/postgresql/arel/visitors.rbs +30 -0
- data/sig/torque/postgresql/arel.rbs +6 -0
- data/sig/torque/postgresql/associations/association_scope.rbs +28 -0
- data/sig/torque/postgresql/associations/belongs_to_many_association.rbs +51 -0
- data/sig/torque/postgresql/associations/builder/belongs_to_many.rbs +24 -0
- data/sig/torque/postgresql/associations/builder/has_many.rbs +15 -0
- data/sig/torque/postgresql/associations/builder.rbs +8 -0
- data/sig/torque/postgresql/associations/foreign_association.rbs +16 -0
- data/sig/torque/postgresql/associations/join_dependency.rbs +16 -0
- data/sig/torque/postgresql/associations/preloader/association.rbs +32 -0
- data/sig/torque/postgresql/associations/preloader/loader_query.rbs +20 -0
- data/sig/torque/postgresql/associations/preloader.rbs +8 -0
- data/sig/torque/postgresql/associations.rbs +17 -0
- data/sig/torque/postgresql/attributes/base.rbs +37 -0
- data/sig/torque/postgresql/attributes/builder/enum.rbs +38 -0
- data/sig/torque/postgresql/attributes/builder/full_text_search.rbs +27 -0
- data/sig/torque/postgresql/attributes/builder/period.rbs +106 -0
- data/sig/torque/postgresql/attributes/builder.rbs +19 -0
- data/sig/torque/postgresql/attributes/composite.rbs +28 -0
- data/sig/torque/postgresql/attributes/enum.rbs +69 -0
- data/sig/torque/postgresql/attributes/enum_set.rbs +75 -0
- data/sig/torque/postgresql/attributes/full_text_search.rbs +13 -0
- data/sig/torque/postgresql/attributes/lazy.rbs +17 -0
- data/sig/torque/postgresql/attributes/lquery.rbs +48 -0
- data/sig/torque/postgresql/attributes/ltree.rbs +46 -0
- data/sig/torque/postgresql/attributes/period.rbs +13 -0
- data/sig/torque/postgresql/attributes/simple_enum.rbs +39 -0
- data/sig/torque/postgresql/attributes/struct.rbs +38 -0
- data/sig/torque/postgresql/attributes.rbs +6 -0
- data/sig/torque/postgresql/autosave_association.rbs +16 -0
- data/sig/torque/postgresql/auxiliary_statement/recursive.rbs +22 -0
- data/sig/torque/postgresql/auxiliary_statement/settings.rbs +63 -0
- data/sig/torque/postgresql/auxiliary_statement.rbs +57 -0
- data/sig/torque/postgresql/base.rbs +41 -0
- data/sig/torque/postgresql/collector.rbs +7 -0
- data/sig/torque/postgresql/config.rbs +9 -0
- data/sig/torque/postgresql/function.rbs +21 -0
- data/sig/torque/postgresql/geometry_builder.rbs +20 -0
- data/sig/torque/postgresql/i18n.rbs +15 -0
- data/sig/torque/postgresql/inheritance/expander.rbs +23 -0
- data/sig/torque/postgresql/inheritance/record.rbs +20 -0
- data/sig/torque/postgresql/inheritance.rbs +47 -0
- data/sig/torque/postgresql/insert_all.rbs +22 -0
- data/sig/torque/postgresql/migration/command_recorder.rbs +30 -0
- data/sig/torque/postgresql/migration.rbs +6 -0
- data/sig/torque/postgresql/predicate_builder/arel_attribute_handler.rbs +15 -0
- data/sig/torque/postgresql/predicate_builder/array_handler.rbs +26 -0
- data/sig/torque/postgresql/predicate_builder/composite_handler.rbs +26 -0
- data/sig/torque/postgresql/predicate_builder/enumerator_lazy_handler.rbs +18 -0
- data/sig/torque/postgresql/predicate_builder/ltree_handler.rbs +36 -0
- data/sig/torque/postgresql/predicate_builder/regexp_handler.rbs +16 -0
- data/sig/torque/postgresql/predicate_builder/struct_handler.rbs +24 -0
- data/sig/torque/postgresql/predicate_builder.rbs +23 -0
- data/sig/torque/postgresql/predicate_table.rbs +24 -0
- data/sig/torque/postgresql/railtie.rbs +10 -0
- data/sig/torque/postgresql/reflection/abstract_reflection.rbs +22 -0
- data/sig/torque/postgresql/reflection/association_reflection.rbs +18 -0
- data/sig/torque/postgresql/reflection/belongs_to_many_reflection.rbs +30 -0
- data/sig/torque/postgresql/reflection/has_many_reflection.rbs +14 -0
- data/sig/torque/postgresql/reflection/runtime_reflection.rbs +18 -0
- data/sig/torque/postgresql/reflection/through_reflection.rbs +14 -0
- data/sig/torque/postgresql/reflection.rbs +11 -0
- data/sig/torque/postgresql/relation/auxiliary_statement.rbs +29 -0
- data/sig/torque/postgresql/relation/buckets.rbs +35 -0
- data/sig/torque/postgresql/relation/cross_join.rbs +63 -0
- data/sig/torque/postgresql/relation/distinct_on.rbs +16 -0
- data/sig/torque/postgresql/relation/inheritance.rbs +48 -0
- data/sig/torque/postgresql/relation/join_series.rbs +28 -0
- data/sig/torque/postgresql/relation/merger.rbs +23 -0
- data/sig/torque/postgresql/relation/segments.rbs +27 -0
- data/sig/torque/postgresql/relation.rbs +48 -0
- data/sig/torque/postgresql/schema_cache/bound_schema_reflection.rbs +14 -0
- data/sig/torque/postgresql/schema_cache/inheritance.rbs +12 -0
- data/sig/torque/postgresql/schema_cache/schema_reflection.rbs +14 -0
- data/sig/torque/postgresql/schema_cache.rbs +43 -0
- data/sig/torque/postgresql/table_name.rbs +20 -0
- data/sig/torque/postgresql/validations.rbs +13 -0
- data/sig/torque/postgresql/version.rbs +5 -0
- data/sig/torque/postgresql/versioned_commands/command_migration.rbs +54 -0
- data/sig/torque/postgresql/versioned_commands/generator.rbs +17 -0
- data/sig/torque/postgresql/versioned_commands/migration_context.rbs +30 -0
- data/sig/torque/postgresql/versioned_commands/migrator.rbs +19 -0
- data/sig/torque/postgresql/versioned_commands/schema_table.rbs +23 -0
- data/sig/torque/postgresql/versioned_commands.rbs +25 -0
- data/sig/torque/postgresql.rbs +26 -0
- data/skills/torque-postgresql/SKILL.md +70 -0
- data/spec/fixtures/migrations/20250101000008_create_trigger_audit_users_v1.sql +3 -0
- data/spec/initialize.rb +29 -2
- data/spec/mocks/cache_query.rb +13 -1
- data/spec/models/author.rb +1 -1
- data/spec/models/comment.rb +2 -0
- data/spec/models/place.rb +2 -0
- data/spec/models/profile.rb +31 -0
- data/spec/rbs_helper.rb +8 -0
- data/spec/schema.rb +35 -4
- data/spec/spec_helper.rb +1 -0
- data/spec/tests/arel_spec.rb +3 -3
- data/spec/tests/auxiliary_statement_spec.rb +12 -0
- data/spec/tests/buckets_spec.rb +122 -0
- data/spec/tests/composite_spec.rb +867 -0
- data/spec/tests/cross_join_spec.rb +185 -0
- data/spec/tests/distinct_on_spec.rb +5 -0
- data/spec/tests/enum_set_spec.rb +4 -0
- data/spec/tests/enum_spec.rb +20 -4
- data/spec/tests/geometric_builder_spec.rb +16 -5
- data/spec/tests/has_many_spec.rb +2 -1
- data/spec/tests/interval_spec.rb +6 -0
- data/spec/tests/ltree_spec.rb +886 -0
- data/spec/tests/predicate_builder_spec.rb +120 -0
- data/spec/tests/relation_spec.rb +25 -69
- data/spec/tests/segments_spec.rb +264 -0
- data/spec/tests/struct_spec.rb +1170 -0
- data/spec/tests/table_inheritance_spec.rb +1037 -56
- data/spec/tests/versioned_commands_spec.rb +145 -0
- metadata +198 -2
|
@@ -17,8 +17,31 @@ module Torque
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
class_methods do
|
|
20
|
-
delegate :distinct_on, :with, :itself_only, :
|
|
21
|
-
:buckets, to: :all
|
|
20
|
+
delegate :distinct_on, :with, :itself_only, :expand_records, :join_series,
|
|
21
|
+
:buckets, :segments, to: :all
|
|
22
|
+
|
|
23
|
+
# The Arel node for a path into a document column, typed by the struct
|
|
24
|
+
# class that backs the column when there is one
|
|
25
|
+
def arel_property_of(column, *path)
|
|
26
|
+
type = Adapter::OID.unwrap(attribute_types[column.to_s])
|
|
27
|
+
handler = PredicateBuilder::StructHandler.new(predicate_builder)
|
|
28
|
+
handler.property_for(arel_table[column], type, path)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Composite values are objects that can be invalid on their own, so the
|
|
32
|
+
# attributes backed by one are validated alongside the record
|
|
33
|
+
def load_schema!
|
|
34
|
+
super
|
|
35
|
+
return unless PostgreSQL.config.composite.enabled &&
|
|
36
|
+
Adapter::OID.const_defined?(:Composite)
|
|
37
|
+
|
|
38
|
+
attribute_types.each do |name, type|
|
|
39
|
+
next if Adapter::OID::Composite.from(type).nil?
|
|
40
|
+
next if _validators[name.to_sym].any?(Validations::NestedValidator)
|
|
41
|
+
|
|
42
|
+
validates(name, nested: true)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
22
45
|
|
|
23
46
|
# Make sure that table name is an instance of TableName class
|
|
24
47
|
def reset_table_name
|
|
@@ -27,24 +50,12 @@ module Torque
|
|
|
27
50
|
end
|
|
28
51
|
|
|
29
52
|
# Whenever the base model is inherited, add a list of auxiliary
|
|
30
|
-
# statements
|
|
53
|
+
# statements
|
|
31
54
|
def inherited(subclass)
|
|
32
55
|
super
|
|
33
56
|
|
|
34
57
|
subclass.class_attribute(:auxiliary_statements_list)
|
|
35
58
|
subclass.auxiliary_statements_list = {}
|
|
36
|
-
|
|
37
|
-
record_class = ActiveRecord::Relation._record_class_attribute
|
|
38
|
-
|
|
39
|
-
# Define the dynamic attribute that returns the same information as
|
|
40
|
-
# the one provided by the auxiliary statement
|
|
41
|
-
subclass.dynamic_attribute(record_class) do
|
|
42
|
-
klass = self.class
|
|
43
|
-
next klass.table_name unless klass.physically_inheritances?
|
|
44
|
-
|
|
45
|
-
query = klass.unscoped.where(subclass.primary_key => id)
|
|
46
|
-
query.pluck(klass.arel_table['tableoid'].pg_cast('regclass')).first
|
|
47
|
-
end
|
|
48
59
|
end
|
|
49
60
|
|
|
50
61
|
# Specifies a one-to-many association. The following methods for
|
|
@@ -2,19 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
module Torque
|
|
4
4
|
module PostgreSQL
|
|
5
|
-
|
|
5
|
+
# Stores a version check for compatibility purposes
|
|
6
|
+
AR810 = (ActiveRecord.gem_version >= Gem::Version.new('8.1.0'))
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
class << self
|
|
9
|
+
def config
|
|
10
|
+
@config ||= ActiveSupport::InheritableOptions.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def configure
|
|
14
|
+
yield config
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Use the same logger as the Active Record one
|
|
18
|
+
def logger
|
|
19
|
+
ActiveRecord::Base.logger
|
|
20
|
+
end
|
|
10
21
|
end
|
|
11
22
|
|
|
12
23
|
# Allow nested configurations
|
|
13
|
-
# :TODO: Rely on +inheritable_copy+ to make nested configurations
|
|
14
24
|
config.define_singleton_method(:nested) do |name, &block|
|
|
15
|
-
|
|
16
|
-
block
|
|
17
|
-
|
|
25
|
+
nested = ActiveSupport::InheritableOptions.new
|
|
26
|
+
block&.call(nested)
|
|
27
|
+
self[name] = nested
|
|
18
28
|
end
|
|
19
29
|
|
|
20
30
|
# Set if any information that requires querying and searching or collecting
|
|
@@ -28,10 +38,13 @@ module Torque
|
|
|
28
38
|
# Add support for querying and calculating histogram buckets
|
|
29
39
|
config.buckets = true
|
|
30
40
|
|
|
41
|
+
# Add support for segmenting calculations by named conditions
|
|
42
|
+
config.segments = true
|
|
43
|
+
|
|
31
44
|
# Set a list of irregular model name when associated with table names
|
|
32
45
|
config.irregular_models = {}
|
|
33
46
|
def config.irregular_models=(hash)
|
|
34
|
-
|
|
47
|
+
self[:irregular_models] = hash.map do |(table, model)|
|
|
35
48
|
[table.to_s, model.to_s]
|
|
36
49
|
end.to_h
|
|
37
50
|
end
|
|
@@ -131,6 +144,27 @@ module Torque
|
|
|
131
144
|
|
|
132
145
|
end
|
|
133
146
|
|
|
147
|
+
# Configure composite type features
|
|
148
|
+
config.nested(:composite) do |composite|
|
|
149
|
+
|
|
150
|
+
# Enables composite types handler by this gem
|
|
151
|
+
composite.enabled = true
|
|
152
|
+
|
|
153
|
+
# Specify the namespace of each composite type class
|
|
154
|
+
composite.namespace = nil
|
|
155
|
+
|
|
156
|
+
# Set a list of irregular class names when associated with composite
|
|
157
|
+
# types
|
|
158
|
+
def composite.irregular_types=(hash)
|
|
159
|
+
self[:irregular_types] = hash.map do |type, klass|
|
|
160
|
+
[type.to_s, klass.to_s]
|
|
161
|
+
end.to_h
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
composite.irregular_types = {}
|
|
165
|
+
|
|
166
|
+
end
|
|
167
|
+
|
|
134
168
|
# Configure geometry data types
|
|
135
169
|
config.nested(:geometry) do |geometry|
|
|
136
170
|
|
|
@@ -172,10 +206,21 @@ module Torque
|
|
|
172
206
|
# the name of the table that actually holds the record
|
|
173
207
|
inheritance.record_class_column_name = :_record_class
|
|
174
208
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Configure struct features
|
|
212
|
+
config.nested(:struct) do |struct|
|
|
213
|
+
|
|
214
|
+
# Enables the JSON(B) columns backed by ActiveModel classes handler
|
|
215
|
+
struct.enabled = true
|
|
216
|
+
|
|
217
|
+
# The name of the method to be used on any ActiveRecord::Base to
|
|
218
|
+
# initialize model-based struct features
|
|
219
|
+
struct.base_method = :struct_for
|
|
220
|
+
|
|
221
|
+
# Whether struct classes reject properties that they don't declare
|
|
222
|
+
# by default
|
|
223
|
+
struct.default_strict = true
|
|
179
224
|
|
|
180
225
|
end
|
|
181
226
|
|
|
@@ -260,12 +305,35 @@ module Torque
|
|
|
260
305
|
|
|
261
306
|
end
|
|
262
307
|
|
|
308
|
+
# Configure label tree features
|
|
309
|
+
config.nested(:ltree) do |ltree|
|
|
310
|
+
|
|
311
|
+
# Enables the ltree and lquery data types handler by this gem
|
|
312
|
+
ltree.enabled = true
|
|
313
|
+
|
|
314
|
+
# A hash of replacements applied to every label provided by the
|
|
315
|
+
# application before it is sent to the database, so that a source that
|
|
316
|
+
# does not satisfy PostgreSQL's rules on its own can still be used. Dashes, for
|
|
317
|
+
# example, are only accepted as of PostgreSQL 16
|
|
318
|
+
# { '-' => '_' } turns dashes into underscores
|
|
319
|
+
# { '-' => '' } drops dashes
|
|
320
|
+
# It never applies to values read from the database
|
|
321
|
+
ltree.sanitize = nil
|
|
322
|
+
|
|
323
|
+
# The name of a method that, whenever the given object responds to it, is
|
|
324
|
+
# used to translate that object into a path or a pattern. It is what lets
|
|
325
|
+
# any class be used wherever one is expected, on assignment, on a
|
|
326
|
+
# condition, and while comparing one path to another
|
|
327
|
+
ltree.compatible_method = :to_tree_path
|
|
328
|
+
|
|
329
|
+
end
|
|
330
|
+
|
|
263
331
|
# Configure arel additional features
|
|
264
332
|
config.nested(:arel) do |arel|
|
|
265
333
|
|
|
266
334
|
# When provided, the initializer will expose the Arel function helper on
|
|
267
335
|
# the given module
|
|
268
|
-
|
|
336
|
+
arel.expose_function_helper_on = nil
|
|
269
337
|
|
|
270
338
|
# List of Arel INFIX operators that will be made available for using as
|
|
271
339
|
# methods on Arel::Nodes::Node and Arel::Attribute
|
|
@@ -279,6 +347,8 @@ module Torque
|
|
|
279
347
|
'doesnt_right_extend' => '&<',
|
|
280
348
|
'doesnt_left_extend' => '&>',
|
|
281
349
|
'adjacent_to' => '-|-',
|
|
350
|
+
'matches_lquery' => '~',
|
|
351
|
+
'matches_any_lquery' => '?',
|
|
282
352
|
}
|
|
283
353
|
|
|
284
354
|
end
|
|
@@ -344,7 +414,7 @@ module Torque
|
|
|
344
414
|
|
|
345
415
|
# Define the list of commands that are going to be versioned by this
|
|
346
416
|
# method
|
|
347
|
-
vs.types = %i[function type view]
|
|
417
|
+
vs.types = %i[function type view trigger]
|
|
348
418
|
|
|
349
419
|
# The name of the table that will inherit from +schema_migrations+ and
|
|
350
420
|
# store the list of versioned commands that have been executed
|
|
@@ -352,5 +422,20 @@ module Torque
|
|
|
352
422
|
|
|
353
423
|
end
|
|
354
424
|
|
|
425
|
+
# Configure cross join features
|
|
426
|
+
config.nested(:cross_join) do |cross_join|
|
|
427
|
+
|
|
428
|
+
# This is an experimental feature that developers must explicitly opt-in.
|
|
429
|
+
# TODO: hook into how conditions and columns are resolved, so that the
|
|
430
|
+
# name of a joined set can shadow a real column
|
|
431
|
+
cross_join.enabled = false
|
|
432
|
+
|
|
433
|
+
# The name of the column added by +with_ordinality+ when it is given
|
|
434
|
+
# +true+ instead of a name. It matches what PostgreSQL calls the column
|
|
435
|
+
# when it is not named at all
|
|
436
|
+
cross_join.ordinality_column = :ordinality
|
|
437
|
+
|
|
438
|
+
end
|
|
439
|
+
|
|
355
440
|
end
|
|
356
441
|
end
|
|
@@ -24,8 +24,7 @@ module Torque
|
|
|
24
24
|
case value
|
|
25
25
|
when ::String
|
|
26
26
|
return if value.blank?
|
|
27
|
-
value.gsub
|
|
28
|
-
build_klass(*value.split(','))
|
|
27
|
+
build_klass(*value.gsub(DESTRUCTOR, '').split(','))
|
|
29
28
|
when ::Hash
|
|
30
29
|
build_klass(*value.symbolize_keys.slice(*pieces).values)
|
|
31
30
|
when ::Array
|
|
@@ -49,8 +48,8 @@ module Torque
|
|
|
49
48
|
parts = parts&.compact&.flatten
|
|
50
49
|
return if parts.blank?
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
format(formation, *parts.
|
|
51
|
+
parts = ::Array.new(pieces.size) { |index| parts[index] }
|
|
52
|
+
format(formation, *parts.map(&number_serializer))
|
|
54
53
|
end
|
|
55
54
|
|
|
56
55
|
def deserialize(value)
|
|
@@ -81,13 +80,8 @@ module Torque
|
|
|
81
80
|
|
|
82
81
|
def build_klass(*args)
|
|
83
82
|
return nil if args.empty?
|
|
84
|
-
check_invalid_format!(args)
|
|
85
83
|
|
|
86
|
-
config_class.new(*args.
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def check_invalid_format!(args)
|
|
90
|
-
raise 'Invalid format' if args.size < pieces.size
|
|
84
|
+
config_class.new(*args.first(pieces.size).map(&:to_f))
|
|
91
85
|
end
|
|
92
86
|
end
|
|
93
87
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Torque
|
|
4
|
+
module PostgreSQL
|
|
5
|
+
module Inheritance
|
|
6
|
+
class Expander
|
|
7
|
+
|
|
8
|
+
def initialize(model, records, targets)
|
|
9
|
+
@model = model
|
|
10
|
+
@records = records
|
|
11
|
+
@targets = targets
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Load the columns that are missing from each partial record using one
|
|
15
|
+
# query per inherited table
|
|
16
|
+
def call
|
|
17
|
+
pending.each do |klass, records|
|
|
18
|
+
amend(klass, records, fetch(klass, records.map(&:id)))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
@records
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_reader :model, :targets
|
|
27
|
+
|
|
28
|
+
def pending
|
|
29
|
+
@records.select do |record|
|
|
30
|
+
record.partial_record? && targets.include?(record.class)
|
|
31
|
+
end.group_by(&:class)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def extra_columns(klass)
|
|
35
|
+
klass.attribute_names - model.attribute_names
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def fetch(klass, ids)
|
|
39
|
+
columns = [klass.primary_key, *extra_columns(klass)]
|
|
40
|
+
table = klass.arel_table
|
|
41
|
+
query = klass.unscoped.itself_only.select(*columns.map { |name| table[name] })
|
|
42
|
+
|
|
43
|
+
klass.lease_connection.select_all(
|
|
44
|
+
query.where(klass.primary_key => ids).arel,
|
|
45
|
+
"#{klass.name} Expand",
|
|
46
|
+
).to_a.index_by { |row| row[klass.primary_key] }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def amend(klass, records, rows)
|
|
50
|
+
columns = extra_columns(klass)
|
|
51
|
+
|
|
52
|
+
records.each do |record|
|
|
53
|
+
row = rows[record.id]
|
|
54
|
+
next if row.nil?
|
|
55
|
+
|
|
56
|
+
attributes = record.instance_variable_get(:@attributes)
|
|
57
|
+
columns.each { |name| attributes.write_from_database(name, row[name]) }
|
|
58
|
+
|
|
59
|
+
record.send(:mark_as_full_record!)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Torque
|
|
4
|
+
module PostgreSQL
|
|
5
|
+
module Inheritance
|
|
6
|
+
module Record
|
|
7
|
+
|
|
8
|
+
# Whether the record was loaded from one of its ancestor tables and
|
|
9
|
+
# therefore is missing the columns that only exist on its own table
|
|
10
|
+
def partial_record?
|
|
11
|
+
@partial_record == true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Reload always queries the record's own table, which produces a
|
|
15
|
+
# complete and writable record
|
|
16
|
+
def reload(*)
|
|
17
|
+
return super unless partial_record?
|
|
18
|
+
|
|
19
|
+
super.tap { mark_as_full_record! }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Deleting a row only needs its primary key, so the missing columns of
|
|
23
|
+
# a partial record are no reason to refuse it
|
|
24
|
+
def destroy
|
|
25
|
+
return super unless partial_record?
|
|
26
|
+
|
|
27
|
+
without_readonly { super }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def without_readonly
|
|
33
|
+
@readonly = false
|
|
34
|
+
yield
|
|
35
|
+
ensure
|
|
36
|
+
@readonly = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def mark_as_partial_record!
|
|
40
|
+
@partial_record = true
|
|
41
|
+
readonly!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def mark_as_full_record!
|
|
45
|
+
@partial_record = false
|
|
46
|
+
@readonly = false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|