torque-postgresql 4.1.0 → 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.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +28 -0
  3. data/lib/generators/torque/skill_generator.rb +17 -0
  4. data/lib/generators/torque/templates/trigger.sql.erb +3 -0
  5. data/lib/generators/torque/trigger_generator.rb +13 -0
  6. data/lib/torque/postgresql/adapter/database_statements.rb +9 -0
  7. data/lib/torque/postgresql/adapter/oid/array.rb +0 -4
  8. data/lib/torque/postgresql/adapter/oid/composite.rb +2 -1
  9. data/lib/torque/postgresql/adapter/oid/enum.rb +1 -1
  10. data/lib/torque/postgresql/adapter/oid/enum_set.rb +2 -2
  11. data/lib/torque/postgresql/adapter/oid/interval.rb +1 -1
  12. data/lib/torque/postgresql/adapter/oid/lquery.rb +45 -28
  13. data/lib/torque/postgresql/adapter/oid/ltree.rb +67 -9
  14. data/lib/torque/postgresql/adapter/oid/struct.rb +1 -1
  15. data/lib/torque/postgresql/adapter/oid.rb +13 -0
  16. data/lib/torque/postgresql/adapter/schema_definitions.rb +5 -0
  17. data/lib/torque/postgresql/adapter/schema_dumper.rb +1 -0
  18. data/lib/torque/postgresql/arel/nodes.rb +51 -0
  19. data/lib/torque/postgresql/arel/visitors.rb +46 -0
  20. data/lib/torque/postgresql/attributes/base.rb +10 -7
  21. data/lib/torque/postgresql/attributes/composite.rb +1 -5
  22. data/lib/torque/postgresql/attributes/enum.rb +1 -6
  23. data/lib/torque/postgresql/attributes/lquery.rb +67 -127
  24. data/lib/torque/postgresql/attributes/ltree.rb +35 -83
  25. data/lib/torque/postgresql/base.rb +9 -1
  26. data/lib/torque/postgresql/config.rb +21 -3
  27. data/lib/torque/postgresql/geometry_builder.rb +4 -10
  28. data/lib/torque/postgresql/inheritance.rb +5 -5
  29. data/lib/torque/postgresql/predicate_builder/arel_attribute_handler.rb +1 -1
  30. data/lib/torque/postgresql/predicate_builder/array_handler.rb +16 -8
  31. data/lib/torque/postgresql/predicate_builder/composite_handler.rb +18 -5
  32. data/lib/torque/postgresql/predicate_builder/ltree_handler.rb +86 -18
  33. data/lib/torque/postgresql/predicate_builder/struct_handler.rb +29 -9
  34. data/lib/torque/postgresql/predicate_builder.rb +38 -11
  35. data/lib/torque/postgresql/railtie.rb +17 -0
  36. data/lib/torque/postgresql/relation/auxiliary_statement.rb +7 -3
  37. data/lib/torque/postgresql/relation/buckets.rb +2 -1
  38. data/lib/torque/postgresql/relation/cross_join.rb +193 -0
  39. data/lib/torque/postgresql/relation/inheritance.rb +1 -2
  40. data/lib/torque/postgresql/relation/join_series.rb +1 -0
  41. data/lib/torque/postgresql/relation/merger.rb +9 -0
  42. data/lib/torque/postgresql/relation/segments.rb +140 -0
  43. data/lib/torque/postgresql/relation.rb +23 -4
  44. data/lib/torque/postgresql/version.rb +1 -1
  45. data/lib/torque/postgresql/versioned_commands/command_migration.rb +23 -0
  46. data/lib/torque/postgresql/versioned_commands.rb +39 -0
  47. data/lib/torque/postgresql.rb +0 -2
  48. data/sig/generators/torque/function_generator.rbs +9 -0
  49. data/sig/generators/torque/skill_generator.rbs +7 -0
  50. data/sig/generators/torque/trigger_generator.rbs +9 -0
  51. data/sig/generators/torque/type_generator.rbs +9 -0
  52. data/sig/generators/torque/view_generator.rbs +9 -0
  53. data/sig/manifest.yaml +7 -0
  54. data/sig/torque/postgresql/adapter/database_statements.rbs +42 -0
  55. data/sig/torque/postgresql/adapter/inheritance_statements.rbs +36 -0
  56. data/sig/torque/postgresql/adapter/oid/array.rbs +20 -0
  57. data/sig/torque/postgresql/adapter/oid/box.rbs +28 -0
  58. data/sig/torque/postgresql/adapter/oid/circle.rbs +33 -0
  59. data/sig/torque/postgresql/adapter/oid/composite.rbs +35 -0
  60. data/sig/torque/postgresql/adapter/oid/enum.rbs +28 -0
  61. data/sig/torque/postgresql/adapter/oid/enum_set.rbs +19 -0
  62. data/sig/torque/postgresql/adapter/oid/interval.rbs +20 -0
  63. data/sig/torque/postgresql/adapter/oid/line.rbs +33 -0
  64. data/sig/torque/postgresql/adapter/oid/lquery.rbs +21 -0
  65. data/sig/torque/postgresql/adapter/oid/ltree.rbs +32 -0
  66. data/sig/torque/postgresql/adapter/oid/range.rbs +28 -0
  67. data/sig/torque/postgresql/adapter/oid/segment.rbs +38 -0
  68. data/sig/torque/postgresql/adapter/oid/struct.rbs +41 -0
  69. data/sig/torque/postgresql/adapter/oid/struct_list.rbs +20 -0
  70. data/sig/torque/postgresql/adapter/oid/struct_set.rbs +18 -0
  71. data/sig/torque/postgresql/adapter/oid.rbs +9 -0
  72. data/sig/torque/postgresql/adapter/quoting.rbs +20 -0
  73. data/sig/torque/postgresql/adapter/schema_creation.rbs +13 -0
  74. data/sig/torque/postgresql/adapter/schema_definitions.rbs +55 -0
  75. data/sig/torque/postgresql/adapter/schema_dumper.rbs +37 -0
  76. data/sig/torque/postgresql/adapter/schema_overrides.rbs +46 -0
  77. data/sig/torque/postgresql/adapter/schema_statements.rbs +50 -0
  78. data/sig/torque/postgresql/adapter.rbs +24 -0
  79. data/sig/torque/postgresql/arel/infix_operation.rbs +79 -0
  80. data/sig/torque/postgresql/arel/join_source.rbs +19 -0
  81. data/sig/torque/postgresql/arel/nodes.rbs +83 -0
  82. data/sig/torque/postgresql/arel/operations.rbs +28 -0
  83. data/sig/torque/postgresql/arel/select_manager.rbs +15 -0
  84. data/sig/torque/postgresql/arel/visitors.rbs +30 -0
  85. data/sig/torque/postgresql/arel.rbs +6 -0
  86. data/sig/torque/postgresql/associations/association_scope.rbs +28 -0
  87. data/sig/torque/postgresql/associations/belongs_to_many_association.rbs +51 -0
  88. data/sig/torque/postgresql/associations/builder/belongs_to_many.rbs +24 -0
  89. data/sig/torque/postgresql/associations/builder/has_many.rbs +15 -0
  90. data/sig/torque/postgresql/associations/builder.rbs +8 -0
  91. data/sig/torque/postgresql/associations/foreign_association.rbs +16 -0
  92. data/sig/torque/postgresql/associations/join_dependency.rbs +16 -0
  93. data/sig/torque/postgresql/associations/preloader/association.rbs +32 -0
  94. data/sig/torque/postgresql/associations/preloader/loader_query.rbs +20 -0
  95. data/sig/torque/postgresql/associations/preloader.rbs +8 -0
  96. data/sig/torque/postgresql/associations.rbs +17 -0
  97. data/sig/torque/postgresql/attributes/base.rbs +37 -0
  98. data/sig/torque/postgresql/attributes/builder/enum.rbs +38 -0
  99. data/sig/torque/postgresql/attributes/builder/full_text_search.rbs +27 -0
  100. data/sig/torque/postgresql/attributes/builder/period.rbs +106 -0
  101. data/sig/torque/postgresql/attributes/builder.rbs +19 -0
  102. data/sig/torque/postgresql/attributes/composite.rbs +28 -0
  103. data/sig/torque/postgresql/attributes/enum.rbs +69 -0
  104. data/sig/torque/postgresql/attributes/enum_set.rbs +75 -0
  105. data/sig/torque/postgresql/attributes/full_text_search.rbs +13 -0
  106. data/sig/torque/postgresql/attributes/lazy.rbs +17 -0
  107. data/sig/torque/postgresql/attributes/lquery.rbs +48 -0
  108. data/sig/torque/postgresql/attributes/ltree.rbs +46 -0
  109. data/sig/torque/postgresql/attributes/period.rbs +13 -0
  110. data/sig/torque/postgresql/attributes/simple_enum.rbs +39 -0
  111. data/sig/torque/postgresql/attributes/struct.rbs +38 -0
  112. data/sig/torque/postgresql/attributes.rbs +6 -0
  113. data/sig/torque/postgresql/autosave_association.rbs +16 -0
  114. data/sig/torque/postgresql/auxiliary_statement/recursive.rbs +22 -0
  115. data/sig/torque/postgresql/auxiliary_statement/settings.rbs +63 -0
  116. data/sig/torque/postgresql/auxiliary_statement.rbs +57 -0
  117. data/sig/torque/postgresql/base.rbs +41 -0
  118. data/sig/torque/postgresql/collector.rbs +7 -0
  119. data/sig/torque/postgresql/config.rbs +9 -0
  120. data/sig/torque/postgresql/function.rbs +21 -0
  121. data/sig/torque/postgresql/geometry_builder.rbs +20 -0
  122. data/sig/torque/postgresql/i18n.rbs +15 -0
  123. data/sig/torque/postgresql/inheritance/expander.rbs +23 -0
  124. data/sig/torque/postgresql/inheritance/record.rbs +20 -0
  125. data/sig/torque/postgresql/inheritance.rbs +47 -0
  126. data/sig/torque/postgresql/insert_all.rbs +22 -0
  127. data/sig/torque/postgresql/migration/command_recorder.rbs +30 -0
  128. data/sig/torque/postgresql/migration.rbs +6 -0
  129. data/sig/torque/postgresql/predicate_builder/arel_attribute_handler.rbs +15 -0
  130. data/sig/torque/postgresql/predicate_builder/array_handler.rbs +26 -0
  131. data/sig/torque/postgresql/predicate_builder/composite_handler.rbs +26 -0
  132. data/sig/torque/postgresql/predicate_builder/enumerator_lazy_handler.rbs +18 -0
  133. data/sig/torque/postgresql/predicate_builder/ltree_handler.rbs +36 -0
  134. data/sig/torque/postgresql/predicate_builder/regexp_handler.rbs +16 -0
  135. data/sig/torque/postgresql/predicate_builder/struct_handler.rbs +24 -0
  136. data/sig/torque/postgresql/predicate_builder.rbs +23 -0
  137. data/sig/torque/postgresql/predicate_table.rbs +24 -0
  138. data/sig/torque/postgresql/railtie.rbs +10 -0
  139. data/sig/torque/postgresql/reflection/abstract_reflection.rbs +22 -0
  140. data/sig/torque/postgresql/reflection/association_reflection.rbs +18 -0
  141. data/sig/torque/postgresql/reflection/belongs_to_many_reflection.rbs +30 -0
  142. data/sig/torque/postgresql/reflection/has_many_reflection.rbs +14 -0
  143. data/sig/torque/postgresql/reflection/runtime_reflection.rbs +18 -0
  144. data/sig/torque/postgresql/reflection/through_reflection.rbs +14 -0
  145. data/sig/torque/postgresql/reflection.rbs +11 -0
  146. data/sig/torque/postgresql/relation/auxiliary_statement.rbs +29 -0
  147. data/sig/torque/postgresql/relation/buckets.rbs +35 -0
  148. data/sig/torque/postgresql/relation/cross_join.rbs +63 -0
  149. data/sig/torque/postgresql/relation/distinct_on.rbs +16 -0
  150. data/sig/torque/postgresql/relation/inheritance.rbs +48 -0
  151. data/sig/torque/postgresql/relation/join_series.rbs +28 -0
  152. data/sig/torque/postgresql/relation/merger.rbs +23 -0
  153. data/sig/torque/postgresql/relation/segments.rbs +27 -0
  154. data/sig/torque/postgresql/relation.rbs +48 -0
  155. data/sig/torque/postgresql/schema_cache/bound_schema_reflection.rbs +14 -0
  156. data/sig/torque/postgresql/schema_cache/inheritance.rbs +12 -0
  157. data/sig/torque/postgresql/schema_cache/schema_reflection.rbs +14 -0
  158. data/sig/torque/postgresql/schema_cache.rbs +43 -0
  159. data/sig/torque/postgresql/table_name.rbs +20 -0
  160. data/sig/torque/postgresql/validations.rbs +13 -0
  161. data/sig/torque/postgresql/version.rbs +5 -0
  162. data/sig/torque/postgresql/versioned_commands/command_migration.rbs +54 -0
  163. data/sig/torque/postgresql/versioned_commands/generator.rbs +17 -0
  164. data/sig/torque/postgresql/versioned_commands/migration_context.rbs +30 -0
  165. data/sig/torque/postgresql/versioned_commands/migrator.rbs +19 -0
  166. data/sig/torque/postgresql/versioned_commands/schema_table.rbs +23 -0
  167. data/sig/torque/postgresql/versioned_commands.rbs +25 -0
  168. data/sig/torque/postgresql.rbs +26 -0
  169. data/skills/torque-postgresql/SKILL.md +70 -0
  170. data/spec/fixtures/migrations/20250101000008_create_trigger_audit_users_v1.sql +3 -0
  171. data/spec/initialize.rb +9 -0
  172. data/spec/mocks/cache_query.rb +1 -1
  173. data/spec/rbs_helper.rb +8 -0
  174. data/spec/schema.rb +2 -0
  175. data/spec/spec_helper.rb +1 -0
  176. data/spec/tests/arel_spec.rb +1 -3
  177. data/spec/tests/auxiliary_statement_spec.rb +12 -0
  178. data/spec/tests/buckets_spec.rb +122 -0
  179. data/spec/tests/composite_spec.rb +67 -0
  180. data/spec/tests/cross_join_spec.rb +185 -0
  181. data/spec/tests/distinct_on_spec.rb +5 -0
  182. data/spec/tests/enum_set_spec.rb +4 -0
  183. data/spec/tests/enum_spec.rb +20 -4
  184. data/spec/tests/geometric_builder_spec.rb +16 -5
  185. data/spec/tests/has_many_spec.rb +2 -1
  186. data/spec/tests/interval_spec.rb +6 -0
  187. data/spec/tests/ltree_spec.rb +398 -64
  188. data/spec/tests/predicate_builder_spec.rb +120 -0
  189. data/spec/tests/relation_spec.rb +25 -69
  190. data/spec/tests/segments_spec.rb +264 -0
  191. data/spec/tests/struct_spec.rb +202 -0
  192. data/spec/tests/table_inheritance_spec.rb +10 -0
  193. data/spec/tests/versioned_commands_spec.rb +145 -0
  194. metadata +153 -2
@@ -0,0 +1,48 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Relation
4
+ module Inheritance
5
+ RECORD_CLASS_TOKEN: Symbol
6
+
7
+ def expand_records_values: () -> Array[model]
8
+ def expand_records_values=: (Array[model] value) -> Array[model]
9
+ def expand_records_eager_load_value: () -> bool?
10
+ def expand_records_eager_load_value=: (bool? value) -> bool?
11
+ def expand_records_scoped_value: () -> Hash[model, Array[model]]
12
+ def expand_records_scoped_value=: (Hash[model, Array[model]] value) -> Hash[model, Array[model]]
13
+ def itself_only_value: () -> bool?
14
+ def itself_only_value=: (bool? value) -> bool?
15
+ def quote_table_name: (table_ref name) -> String
16
+ def quote_column_name: (column_ref name) -> String
17
+ def itself_only: () -> relation
18
+ def itself_only!: (*untyped) -> self
19
+ def expand_records: (*model types, ?eager_load: bool, ?filter: bool) -> relation
20
+ def expand_records!: (*model types, ?eager_load: bool, ?filter: bool) -> self
21
+ def select: (*untyped fields) ?{ (?) -> untyped } -> untyped
22
+
23
+ private
24
+
25
+ def raise_itself_only_conflict!: () -> bot
26
+ def build_arel: (*untyped) -> ::Arel::SelectManager
27
+ def inheritance_discriminated?: () -> bool
28
+ def build_record_class_marker: () -> ::Arel::Nodes::As
29
+ def build_inheritances: (::Arel::SelectManager arel) -> untyped
30
+ def build_inheritances_joins: (::Arel::SelectManager arel, Array[model] types) -> Hash[String, Array[::Arel::Nodes::TableAlias]]
31
+ def regclass: () -> Torque::PostgreSQL::Arel::Nodes::Cast
32
+
33
+ public
34
+
35
+ module Expansion
36
+ def preload_associations: (Array[record] records) -> untyped
37
+
38
+ private
39
+
40
+ def exec_queries: () ?{ (record) -> void } -> Array[record]
41
+ def preloaded_association_names: () -> Array[Symbol]
42
+ def warn_about_missing_record_class: (Array[record] records) -> untyped
43
+ def record_class_marker?: (arel_node | column_ref value) -> bool
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Relation
4
+ module JoinSeries
5
+ type step = Numeric | ActiveSupport::Duration | Symbol | String
6
+ type with = column_ref | Hash[column_ref, untyped] | arel_node
7
+
8
+ def self.build: (relation relation, untyped range, ?with: with?, ?as: column_ref, ?step: step?, ?time_zone: untyped, ?cast: column_ref?, ?mode: Symbol) ?{ (Torque::PostgreSQL::Arel::Nodes::Ref series, arel_table table) -> arel_node } -> ::Arel::Nodes::Join
9
+
10
+ private
11
+
12
+ def self.validate_build!: (untyped range, step? step) -> nil
13
+ def self.bind_value: (untyped value) -> arel_node
14
+ def self.arel_join: (Symbol | String mode) -> singleton(::Arel::Nodes::Join)
15
+ def self.build_join_on: (Torque::PostgreSQL::Arel::Nodes::Ref result, relation relation, with? with, column_ref? cast) ?{ (Torque::PostgreSQL::Arel::Nodes::Ref series, arel_table table) -> arel_node } -> arel_node
16
+
17
+ public
18
+
19
+ def join_series: (untyped range, ?with: with?, ?as: column_ref, ?step: step?, ?time_zone: untyped, ?cast: column_ref?, ?mode: Symbol) ?{ (Torque::PostgreSQL::Arel::Nodes::Ref series, arel_table table) -> arel_node } -> relation
20
+ def join_series!: (untyped range, ?with: with?, ?as: column_ref, ?step: step?, ?time_zone: untyped, ?cast: column_ref?, ?mode: Symbol) ?{ (Torque::PostgreSQL::Arel::Nodes::Ref series, arel_table table) -> arel_node } -> self
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ class ActiveRecord::Relation
27
+ include Torque::PostgreSQL::Relation::JoinSeries
28
+ end
@@ -0,0 +1,23 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Relation
4
+ module Merger
5
+ def merge: () -> relation
6
+
7
+ private
8
+
9
+ def merge_select_extra: () -> untyped
10
+ def merge_distinct_on: () -> untyped
11
+ def merge_auxiliary_statements: () -> untyped
12
+ def merge_inheritance: () -> untyped
13
+ def raise_eager_load_conflict!: () -> bot
14
+ def merge_buckets: () -> untyped
15
+ def merge_segments: () -> untyped
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class ActiveRecord::Relation::Merger
22
+ prepend Torque::PostgreSQL::Relation::Merger
23
+ end
@@ -0,0 +1,27 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Relation
4
+ module Segments
5
+ type condition = relation | Symbol | Proc | Hash[untyped, untyped] | String | Array[untyped] | arel_node | nil
6
+
7
+ def segments_value: () -> Hash[Symbol, arel_node?]
8
+ def segments_value=: (Hash[Symbol, arel_node?] value) -> Hash[Symbol, arel_node?]
9
+ def segments: (**condition map) -> relation
10
+ def segments!: (**condition map) -> self
11
+
12
+ private
13
+
14
+ def execute_simple_calculation: (String operation, column_spec | arel_node | nil column_name, bool? distinct) -> untyped
15
+ def execute_grouped_calculation: (String operation, column_spec | arel_node | nil column_name, bool? distinct) -> untyped
16
+ def execute_segments_calculation: (String operation, column_spec | arel_node | nil column_name, bool? distinct) -> untyped
17
+ def segments_projections: (Array[arel_node] groups, arel_node aggregate, connection connection) -> Array[::Arel::Nodes::As]
18
+ def segments_result: (ActiveRecord::Result data, Array[arel_node] groups, arel_node column, String operation) -> (Hash[untyped, untyped] | nil)
19
+ def segment_predicate_for: (Symbol name, condition condition) -> arel_node?
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ class ActiveRecord::Relation
26
+ include Torque::PostgreSQL::Relation::Segments
27
+ end
@@ -0,0 +1,48 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Relation
4
+ extend ActiveSupport::Concern
5
+ include DistinctOn
6
+ include Inheritance
7
+
8
+ type column_spec = column_ref | Hash[column_ref, untyped] | Array[untyped]
9
+
10
+ SINGLE_VALUE_METHODS: Array[Symbol]
11
+ MULTI_VALUE_METHODS: Array[Symbol]
12
+ VALUE_METHODS: Array[Symbol]
13
+ FROZEN_EMPTY_ARRAY: Array[untyped]
14
+ ARColumn: singleton(ActiveRecord::ConnectionAdapters::PostgreSQL::Column)
15
+
16
+ def select_extra_values: () -> Array[arel_node]
17
+ def select_extra_values=: (Array[arel_node] value) -> Array[arel_node]
18
+ def calculate: (Symbol | String operation, column_spec | nil column_name) -> untyped
19
+ def resolve_column: (column_spec list, ?column_ref | false base) -> Array[arel_node]
20
+ def resolve_base_table: (column_ref | false relation) -> (model | PredicateTable | nil)
21
+ def cast_for_condition: (column_ref | column column, untyped value) -> untyped
22
+
23
+ private
24
+
25
+ def build_arel: (*untyped) -> ::Arel::SelectManager
26
+ def part_table_for: (ActiveRecord::TableMetadata table, String name) -> PredicateTable?
27
+
28
+ public
29
+
30
+ module ClassMethods
31
+ def _record_class_attribute: () -> Symbol
32
+ def _record_class_column_name: () -> String
33
+ end
34
+
35
+ module Initializer
36
+ def initialize: (model klass, *untyped, **untyped) -> void
37
+ def upsert_all: (Array[Hash[column_ref, untyped]] attributes, ?where: String | relation | nil, **untyped xargs) -> untyped
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class ActiveRecord::Relation
44
+ include Torque::PostgreSQL::Relation
45
+ extend Torque::PostgreSQL::Relation::ClassMethods
46
+ prepend Torque::PostgreSQL::Relation::Initializer
47
+ prepend Torque::PostgreSQL::Relation::Inheritance::Expansion
48
+ end
@@ -0,0 +1,14 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module BoundSchemaReflection
4
+ def add_model_name: (String table_name, model model) -> model?
5
+ def dependencies: (String table_name) -> Array[String]?
6
+ def associations: (String table_name) -> Array[String]?
7
+ def lookup_model: (String table_name, ?String | model scoped_class) -> model
8
+ end
9
+ end
10
+ end
11
+
12
+ class ActiveRecord::ConnectionAdapters::BoundSchemaReflection
13
+ prepend Torque::PostgreSQL::BoundSchemaReflection
14
+ end
@@ -0,0 +1,12 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module SchemaCache
4
+ module Inheritance
5
+ def lookup_model: (String table_name, ?String | model scoped_class, source_to_model: Hash[String, model]) -> model
6
+ def find_model: (String | Array[String] max_name, String table_name, ?Module scope) -> model?
7
+ def generate_associations: (Hash[String, Array[String]] inheritance_dependencies) -> Hash[String, Array[String]]
8
+ def prepare_irregular_models: (Array[String] data_sources) -> Hash[String, model]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module SchemaReflection
4
+ def add_model_name: (SchemaCache::source source, String table_name, model model) -> model?
5
+ def dependencies: (SchemaCache::source source, String table_name) -> Array[String]?
6
+ def associations: (SchemaCache::source source, String table_name) -> Array[String]?
7
+ def lookup_model: (SchemaCache::source source, String table_name, String | model scoped_class) -> model
8
+ end
9
+ end
10
+ end
11
+
12
+ class ActiveRecord::ConnectionAdapters::SchemaReflection
13
+ prepend Torque::PostgreSQL::SchemaReflection
14
+ end
@@ -0,0 +1,43 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ class LookupError < ArgumentError
4
+ end
5
+
6
+ # initialize is not declared: schema_cache/inheritance.rb reopens this
7
+ # module before it is defined, and the runtime checker hooks it eagerly
8
+ module SchemaCache
9
+ include SchemaCache::Inheritance
10
+
11
+ type source = connection | pool
12
+
13
+ @data_sources_model_names: Hash[String, model]
14
+ @inheritance_dependencies: Hash[String, Array[String]]
15
+ @inheritance_associations: Hash[String, Array[String]]
16
+ @inheritance_loaded: bool
17
+
18
+ def initialize_dup: (*untyped) -> untyped
19
+ def encode_with: (untyped coder) -> untyped
20
+ def init_with: (untyped coder) -> untyped
21
+ def add: (source | String connection_or_table_name, ?String table_name, *untyped) -> untyped
22
+ def clear!: () -> untyped
23
+ def size: () -> Integer
24
+ def clear_data_source_cache!: (source | String connection_or_name, ?String name) -> untyped
25
+ def marshal_dump: () -> Array[untyped]
26
+ def marshal_load: (Array[untyped] array) -> untyped
27
+ def add_model_name: (*untyped args) -> model?
28
+ def dependencies: (source | String source, ?String table_name) -> Array[String]?
29
+ def associations: (source | String source, ?String table_name) -> Array[String]?
30
+ def lookup_model: (String table_name, ?String | model scoped_class) -> model
31
+
32
+ private
33
+
34
+ def reload_inheritance_data!: (source source) -> untyped
35
+ def generate_associations: () -> Hash[String, Array[String]]
36
+ def add_all: (?source? source) -> untyped
37
+ end
38
+ end
39
+ end
40
+
41
+ class ActiveRecord::ConnectionAdapters::SchemaCache
42
+ prepend Torque::PostgreSQL::SchemaCache
43
+ end
@@ -0,0 +1,20 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ class TableName < Delegator
4
+ @klass: model
5
+ @table_name: String
6
+ @schema: String?
7
+
8
+ def initialize: (model klass, String table_name) -> void
9
+ def schema: () -> String?
10
+ def to_s: () -> String
11
+ alias __getobj__ to_s
12
+ def ==: (untyped other) -> Integer?
13
+ def __setobj__: (String value) -> String
14
+
15
+ private
16
+
17
+ def search_path_schemes: () -> Array[String]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Validations
4
+ class NestedValidator < ActiveModel::EachValidator
5
+ def validate_each: (ActiveModel::Validations record, column_ref attribute, untyped value) -> untyped
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ class ActiveRecord::Base
12
+ include Torque::PostgreSQL::Validations
13
+ end
@@ -0,0 +1,5 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ VERSION: String
4
+ end
5
+ end
@@ -0,0 +1,54 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module VersionedCommands
4
+ module Migration
5
+ @command: CommandMigration
6
+ @description: [String, String]
7
+ @connection: connection?
8
+ @execution_strategy: untyped
9
+
10
+ def initialize: (*untyped args) -> void
11
+ def migrate: (:up | :down direction) -> untyped
12
+ def exec_migration: (connection conn, :up | :down direction) -> untyped
13
+ def announce: (String message) -> untyped
14
+ def description_for: (:up | :down direction) -> [String, String]
15
+ def execute: (String command) -> untyped
16
+ end
17
+
18
+ class CommandMigration < ::Struct[untyped]
19
+ @migration: ActiveRecord::Migration?
20
+
21
+ def filename: () -> String
22
+ def filename=: (String value) -> String
23
+ def version: () -> Integer
24
+ def version=: (Integer value) -> Integer
25
+ def op: () -> String
26
+ def op=: (String value) -> String
27
+ def type: () -> String
28
+ def type=: (String value) -> String
29
+ def object_name: () -> String
30
+ def object_name=: (String value) -> String
31
+ def op_version: () -> Integer
32
+ def op_version=: (Integer value) -> Integer
33
+ def scope: () -> String?
34
+ def scope=: (String? value) -> String?
35
+
36
+ def execute: (String command) -> untyped
37
+ def initialize: (String filename, *untyped args) -> void
38
+ def name: () -> String
39
+ def disable_ddl_transaction: () -> false
40
+ def migrate: (:up | :down direction) -> untyped
41
+ def up: () -> untyped
42
+ def down: () -> untyped
43
+ def drop: () -> untyped
44
+
45
+ private
46
+
47
+ def drop_function: () -> untyped
48
+ def drop_type: () -> untyped
49
+ def drop_trigger: () -> untyped
50
+ def drop_view: () -> untyped
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module VersionedCommands
4
+ module Generator
5
+ TEMPLATES_PATH: String
6
+
7
+ attr_reader file_name: String?
8
+
9
+ def self.included: (singleton(Rails::Generators::Base) base) -> untyped
10
+ def type: () -> String
11
+ def create_migration_file: () -> untyped
12
+ def count_object_entries: () -> Integer
13
+ def validate_file_name!: () -> nil
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ class IllegalCommandTypeError < ActiveRecord::MigrationError
4
+ def initialize: (String file) -> void
5
+ end
6
+
7
+ module VersionedCommands
8
+ module MigrationContext
9
+ type status = [String, String, String]
10
+
11
+ InvalidMigrationTimestampError: untyped
12
+ PGAdapter: singleton(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
13
+
14
+ def migrations: () -> Array[untyped]
15
+ def migrations_status: () -> Array[status]
16
+ def migration_commands: () -> Array[CommandMigration]
17
+
18
+ private
19
+
20
+ def running_for_pg?: () -> bool
21
+ def command_files: () -> Array[String]
22
+ def parse_command_filename: (String filename) -> Array[String?]?
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ class ActiveRecord::MigrationContext
29
+ prepend Torque::PostgreSQL::VersionedCommands::MigrationContext
30
+ end
@@ -0,0 +1,19 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module VersionedCommands
4
+ module Migrator
5
+ @versioned_command: CommandMigration | false
6
+ @versioned_table: SchemaTable
7
+ @versioned_counter: Integer
8
+
9
+ def execute_migration_in_transaction: (untyped migration) -> untyped
10
+ def record_version_state_after_migrating: (Integer version) -> untyped
11
+ def versioned_command?: (untyped migration) -> bool
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ class ActiveRecord::Migrator
18
+ prepend Torque::PostgreSQL::VersionedCommands::Migrator
19
+ end
@@ -0,0 +1,23 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module VersionedCommands
4
+ class SchemaTable
5
+ attr_reader arel_table: arel_table
6
+
7
+ @pool: pool
8
+
9
+ def initialize: (pool pool) -> void
10
+ def create_version: (CommandMigration command) -> untyped
11
+ def delete_version: (CommandMigration command) -> Integer
12
+ def primary_key: () -> String
13
+ def name: () -> String
14
+ def table_name: () -> String
15
+ def create_table: () -> untyped
16
+ def drop_table: () -> untyped
17
+ def count: () -> Integer
18
+ def table_exists?: () -> bool
19
+ def versions_of: (Symbol | String type) -> Array[[String, Integer]]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module VersionedCommands
4
+ type command_type = :function | :type | :view | :trigger
5
+ type dirs = String | Array[String]
6
+
7
+ RAILS_APP: untyped
8
+ NAME_MATCH: String
9
+
10
+ @filename_regexp: Regexp
11
+
12
+ def self.valid_type?: (Symbol | String type) -> bool
13
+ def self.validate!: (Symbol | String type, String content, String name) -> nil
14
+ def self.fetch_command: (dirs dirs, Symbol | String type, String name, Integer | String version) -> String
15
+ def self.filename_regexp: () -> Regexp
16
+
17
+ private
18
+
19
+ def self.validate_function!: (String content, String name) -> nil
20
+ def self.validate_type!: (String content, String name) -> nil
21
+ def self.validate_trigger!: (String content, String name) -> nil
22
+ def self.validate_view!: (String content, String name) -> nil
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ type model = singleton(ActiveRecord::Base)
4
+ type record = ActiveRecord::Base
5
+ type relation = ActiveRecord::Relation
6
+ type connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
7
+ type pool = ActiveRecord::ConnectionAdapters::ConnectionPool
8
+ type reflection = ActiveRecord::Reflection::AssociationReflection
9
+ type any_reflection = ActiveRecord::Reflection::AbstractReflection
10
+ type column = ActiveRecord::ConnectionAdapters::PostgreSQL::Column
11
+ type type_caster = ActiveModel::Type::Value
12
+ type column_ref = String | Symbol
13
+ type table_ref = String | Symbol | ActiveRecord::ConnectionAdapters::PostgreSQL::Name
14
+ type arel_table = ::Arel::Table
15
+ type arel_attribute = ::Arel::Attributes::Attribute
16
+ type arel_node = ::Arel::Nodes::Node | ::Arel::Nodes::SqlLiteral | arel_attribute
17
+ type collector = ::Arel::Collectors::SQLString | ::Arel::Collectors::Composite | ::Arel::Collectors::Bind | ::Arel::Collectors::SubstituteBinds
18
+ type stream = IO | StringIO
19
+ type table_node = arel_table | ::Arel::Nodes::TableAlias
20
+ type path_key = column_ref | Integer
21
+
22
+ interface _Callable
23
+ def call: (*untyped) -> untyped
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: torque-postgresql
3
+ description: PostgreSQL features in Rails through the torque-postgresql gem. Use when writing models, migrations, or queries in an app whose Gemfile has torque-postgresql, or when a task needs a PostgreSQL type (enum, enum set, jsonb document, composite, ltree, range, interval, geometry) or query feature (CTE, DISTINCT ON, FILTER aggregates, width_bucket, generate_series, full-text search, array associations, table inheritance).
4
+ ---
5
+
6
+ # torque-postgresql
7
+
8
+ The gem exposes PostgreSQL features through the regular Rails DSL: migration methods that dump
9
+ to `schema.rb`, model macros, and relation methods. Reach for it before raw SQL.
10
+
11
+ ## Steps
12
+
13
+ 1. Locate the installed gem with `bundle info torque-postgresql`. Done when you know its version
14
+ and path.
15
+ 2. Read the app's `Torque::PostgreSQL.configure` block (search `config/` for it). Done when you
16
+ know which features are off and which macros are renamed: every `base_method` key renames a
17
+ macro, and `versioned_commands` and `cross_join` stay off unless enabled there.
18
+ 3. Pick the feature from the table below and read its docs page before writing code. Done when
19
+ the migration, the model macro, and the query you plan all appear on that page.
20
+ 4. Check exact signatures in `<gem path>/sig/`, when the installed release ships one. Methods
21
+ generated per attribute (`admin?`, period scopes, `full_text_search`) are named on the docs
22
+ page, never in `sig/`.
23
+ 5. Write the migration with the gem's DSL, run it, and confirm `db/schema.rb` dumps it.
24
+
25
+ ## Features
26
+
27
+ Docs live at `https://torque.dev/postgresql/<page>/`. The index is
28
+ `https://torque.dev/postgresql/llms.txt`, and every page in one file is
29
+ `https://torque.dev/postgresql/llms-full.txt`.
30
+
31
+ | Need | Migration | Model or query | Page |
32
+ |---|---|---|---|
33
+ | Fixed list of values | `create_enum`, `t.enum enum_type:` | `torque_enum :role`, `Enum::Roles` | `data-types/enum` |
34
+ | Several values of one enum | `t.enum enum_type:, array: true` | `torque_enum_set :perms` | `data-types/enum-set` |
35
+ | Typed jsonb document | `t.jsonb` | `struct_for :settings, Klass` | `data-types/struct` |
36
+ | Database composite type | `create_composite_type`, `t.composite composite_type:` | `Composite::Address` | `data-types/composite` |
37
+ | Tree paths | `enable_extension 'ltree'`, `t.ltree`, `t.lquery` | `where(path: ...)` | `data-types/ltree` |
38
+ | Time windows | `t.tsrange`, `t.daterange` | `period_for :period` | `data-types/date-time-range` |
39
+ | Durations | `t.interval` | `ActiveSupport::Duration` values | `data-types/interval` |
40
+ | Geometry | `t.box`, `t.circle`, `t.line`, `t.segment` | value objects | `data-types/box` and siblings |
41
+ | Array of foreign keys | `t.bigint :tag_ids, array: true` | `belongs_to_many :tags`, `has_many :videos, array: true` | `modeling/belongs-to-many`, `modeling/has-many` |
42
+ | Table inheritance | `create_table :child, inherits: :parent` | `expand_records` | `modeling/inherited-tables` |
43
+ | Value computed on demand | | `dynamic_attribute(:name) { }` | `modeling/dynamic-attributes` |
44
+ | Conditional upsert | | `upsert_all(rows, where: ...)` | `modeling/insert-all` |
45
+ | CTE | | `auxiliary_statement :name`, `.with(:name)` | `querying/auxiliary-statements` |
46
+ | First row per group | | `distinct_on(:col)` | `querying/distinct-on` |
47
+ | Histogram | | `buckets(:col, range_or_list)` | `querying/buckets` |
48
+ | Several filtered aggregates | | `segments(name: condition).count` | `querying/segments` |
49
+ | Report rows with no data | | `join_series(range, with: :col)` | `querying/join-series` |
50
+ | Full-text search | `t.search_vector columns:` | `torque_search_for :col`, `.full_text_search` | `querying/full-text-search` |
51
+ | Regexp and array conditions | | `where(title: /x/)` | `querying/predicate-builder` |
52
+ | SQL functions and operators | | `FN.*`, Arel infix methods | `querying/arel` |
53
+ | Several schemas | `create_schema` | `self.schema =` | `experimental/multiple-schemas` |
54
+ | Versioned views, functions, triggers, types | `rails g torque:view` and siblings | | `experimental/versioned-commands` |
55
+ | Join a function, subquery, or row list | | `cross_join(source, as:)` | `experimental/cross-join` |
56
+
57
+ ## Rules
58
+
59
+ - **Enum types** come from Rails' own `create_enum`. Adding values with `add_enum_values` may
60
+ need `disable_ddl_transaction!` in that migration.
61
+ - **Struct classes** subclass `Torque::PostgreSQL::Struct` and are strict by default. Only `jsonb`
62
+ columns can be queried by property. Encrypt properties, never the whole column.
63
+ - **Inherited records** reached through an association come back partial and read-only. Load
64
+ them with `expand_records` before writing to them.
65
+ - **ltree labels** accept dashes only on PostgreSQL 16+. The `ltree.sanitize` setting rewrites
66
+ them, which matters for UUID labels.
67
+ - **`FN`** is `Torque::PostgreSQL::FN`. The app may expose it under a shorter name through
68
+ `arel.expose_function_helper_on`, which the docs write as `PG::Fn`.
69
+ - **Array conditions** use `ANY` and overlaps only when `predicate_builder.handle_array_attributes`
70
+ is on. It is off by default.
@@ -0,0 +1,3 @@
1
+ CREATE OR REPLACE TRIGGER audit_users
2
+ BEFORE INSERT ON users
3
+ FOR EACH ROW EXECUTE FUNCTION count_users();
data/spec/initialize.rb CHANGED
@@ -22,10 +22,14 @@ require_relative '../lib/torque/postgresql/attributes/enum_set'
22
22
  require_relative '../lib/torque/postgresql/attributes/period'
23
23
  require_relative '../lib/torque/postgresql/attributes/struct'
24
24
  require_relative '../lib/torque/postgresql/attributes/full_text_search'
25
+ require_relative '../lib/torque/postgresql/attributes/ltree'
26
+ require_relative '../lib/torque/postgresql/attributes/lquery'
25
27
 
26
28
  require_relative '../lib/torque/postgresql/relation/auxiliary_statement'
27
29
  require_relative '../lib/torque/postgresql/relation/join_series'
28
30
  require_relative '../lib/torque/postgresql/relation/buckets'
31
+ require_relative '../lib/torque/postgresql/relation/segments'
32
+ require_relative '../lib/torque/postgresql/relation/cross_join'
29
33
 
30
34
  require_relative '../lib/torque/postgresql/versioned_commands'
31
35
 
@@ -42,6 +46,11 @@ module Torque
42
46
  Relation.include(Relation::AuxiliaryStatement)
43
47
  Relation.include(Relation::JoinSeries)
44
48
  Relation.include(Relation::Buckets)
49
+ Relation.include(Relation::Segments)
50
+ Relation.include(Relation::CrossJoin)
51
+
52
+ config.cross_join.enabled = true
53
+ ActiveRecord::Base.singleton_class.delegate(:cross_join, to: :all)
45
54
 
46
55
  config.versioned_commands.enabled = true
47
56
  ActiveRecord::Schema::Definition.include(Adapter::Definition)
@@ -32,7 +32,7 @@ module Mocks
32
32
 
33
33
  original_method = ActiveRecord::Base.connection.method(:raw_execute)
34
34
  original_method.receiver.define_singleton_method(:raw_execute) do |*args, **xargs, &block|
35
- result ||= [args.first, args.third]
35
+ result ||= [args.first, args.third] unless %w[SCHEMA TRANSACTION].include?(args.second)
36
36
  super(*args, **xargs, &block)
37
37
  end
38
38
 
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['RBS_TEST_TARGET'] ||= 'Torque::PostgreSQL::*,Torque::Generators::*'
4
+ ENV['RBS_TEST_SKIP'] ||= '::Torque::PostgreSQL::Attributes::Lazy,::Torque::PostgreSQL::Adapter::OID::Range::Comparison'
5
+ ENV['RBS_TEST_OPT'] ||= '-I sig'
6
+ ENV['RBS_TEST_LOGLEVEL'] ||= 'warn'
7
+
8
+ require 'rbs/test/setup'
data/spec/schema.rb CHANGED
@@ -102,6 +102,8 @@ ActiveRecord::Schema.define do
102
102
  t.integer "parent_id"
103
103
  t.string "title"
104
104
  t.ltree "path", index: { using: :gist }
105
+ t.lquery "pattern"
106
+ t.lquery "patterns", array: true
105
107
  end
106
108
 
107
109
  create_table "texts", force: :cascade do |t|
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require_relative 'rbs_helper' if ENV['RBS_TEST']
1
2
  require 'torque-postgresql'
2
3
  require 'database_cleaner'
3
4
  require 'factory_bot'