rom-sql 3.1.0 → 3.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +214 -101
  3. data/LICENSE +1 -1
  4. data/README.md +12 -54
  5. data/lib/rom-sql.rb +2 -0
  6. data/lib/rom/plugins/relation/sql/auto_restrictions.rb +2 -0
  7. data/lib/rom/plugins/relation/sql/instrumentation.rb +2 -0
  8. data/lib/rom/plugins/relation/sql/postgres/explain.rb +6 -7
  9. data/lib/rom/plugins/relation/sql/postgres/full_text_search.rb +53 -0
  10. data/lib/rom/plugins/relation/sql/postgres/streaming.rb +108 -0
  11. data/lib/rom/sql.rb +2 -0
  12. data/lib/rom/sql/associations.rb +2 -0
  13. data/lib/rom/sql/associations/core.rb +3 -1
  14. data/lib/rom/sql/associations/many_to_many.rb +3 -1
  15. data/lib/rom/sql/associations/many_to_one.rb +2 -0
  16. data/lib/rom/sql/associations/one_to_many.rb +2 -0
  17. data/lib/rom/sql/associations/one_to_one.rb +2 -0
  18. data/lib/rom/sql/associations/one_to_one_through.rb +2 -0
  19. data/lib/rom/sql/associations/self_ref.rb +2 -0
  20. data/lib/rom/sql/attribute.rb +26 -7
  21. data/lib/rom/sql/attribute_aliasing.rb +28 -0
  22. data/lib/rom/sql/commands.rb +2 -0
  23. data/lib/rom/sql/commands/create.rb +2 -0
  24. data/lib/rom/sql/commands/delete.rb +2 -0
  25. data/lib/rom/sql/commands/error_wrapper.rb +2 -0
  26. data/lib/rom/sql/commands/update.rb +2 -0
  27. data/lib/rom/sql/dsl.rb +11 -3
  28. data/lib/rom/sql/error.rb +2 -0
  29. data/lib/rom/sql/errors.rb +2 -0
  30. data/lib/rom/sql/extensions.rb +2 -0
  31. data/lib/rom/sql/extensions/active_support_notifications.rb +2 -0
  32. data/lib/rom/sql/extensions/mysql.rb +2 -0
  33. data/lib/rom/sql/extensions/mysql/type_builder.rb +2 -0
  34. data/lib/rom/sql/extensions/postgres.rb +3 -0
  35. data/lib/rom/sql/extensions/postgres/commands.rb +3 -1
  36. data/lib/rom/sql/extensions/postgres/type_builder.rb +6 -4
  37. data/lib/rom/sql/extensions/postgres/type_serializer.rb +2 -0
  38. data/lib/rom/sql/extensions/postgres/types.rb +2 -0
  39. data/lib/rom/sql/extensions/postgres/types/array.rb +6 -4
  40. data/lib/rom/sql/extensions/postgres/types/array_types.rb +3 -1
  41. data/lib/rom/sql/extensions/postgres/types/geometric.rb +2 -0
  42. data/lib/rom/sql/extensions/postgres/types/json.rb +13 -11
  43. data/lib/rom/sql/extensions/postgres/types/ltree.rb +25 -23
  44. data/lib/rom/sql/extensions/postgres/types/network.rb +2 -0
  45. data/lib/rom/sql/extensions/postgres/types/range.rb +2 -0
  46. data/lib/rom/sql/extensions/rails_log_subscriber.rb +2 -0
  47. data/lib/rom/sql/extensions/sqlite.rb +2 -0
  48. data/lib/rom/sql/extensions/sqlite/type_builder.rb +2 -0
  49. data/lib/rom/sql/extensions/sqlite/types.rb +2 -0
  50. data/lib/rom/sql/foreign_key.rb +3 -1
  51. data/lib/rom/sql/function.rb +14 -3
  52. data/lib/rom/sql/gateway.rb +6 -1
  53. data/lib/rom/sql/group_dsl.rb +2 -0
  54. data/lib/rom/sql/index.rb +2 -0
  55. data/lib/rom/sql/join_dsl.rb +2 -0
  56. data/lib/rom/sql/mapper_compiler.rb +2 -0
  57. data/lib/rom/sql/migration.rb +5 -3
  58. data/lib/rom/sql/migration/inline_runner.rb +2 -0
  59. data/lib/rom/sql/migration/migrator.rb +4 -2
  60. data/lib/rom/sql/migration/recorder.rb +2 -0
  61. data/lib/rom/sql/migration/runner.rb +4 -2
  62. data/lib/rom/sql/migration/schema_diff.rb +2 -0
  63. data/lib/rom/sql/migration/template.rb +2 -0
  64. data/lib/rom/sql/migration/writer.rb +12 -4
  65. data/lib/rom/sql/order_dsl.rb +2 -0
  66. data/lib/rom/sql/plugin/associates.rb +4 -2
  67. data/lib/rom/sql/plugin/nullify.rb +2 -0
  68. data/lib/rom/sql/plugin/pagination.rb +2 -0
  69. data/lib/rom/sql/plugins.rb +2 -0
  70. data/lib/rom/sql/projection_dsl.rb +3 -1
  71. data/lib/rom/sql/rake_task.rb +2 -0
  72. data/lib/rom/sql/relation.rb +3 -1
  73. data/lib/rom/sql/relation/reading.rb +6 -4
  74. data/lib/rom/sql/relation/writing.rb +2 -0
  75. data/lib/rom/sql/restriction_dsl.rb +9 -1
  76. data/lib/rom/sql/schema.rb +16 -2
  77. data/lib/rom/sql/schema/attributes_inferrer.rb +5 -3
  78. data/lib/rom/sql/schema/dsl.rb +3 -1
  79. data/lib/rom/sql/schema/index_dsl.rb +5 -2
  80. data/lib/rom/sql/schema/inferrer.rb +12 -8
  81. data/lib/rom/sql/schema/type_builder.rb +4 -2
  82. data/lib/rom/sql/spec/support.rb +5 -3
  83. data/lib/rom/sql/tasks/migration_tasks.rake +16 -11
  84. data/lib/rom/sql/transaction.rb +2 -0
  85. data/lib/rom/sql/type_dsl.rb +2 -0
  86. data/lib/rom/sql/type_extensions.rb +3 -1
  87. data/lib/rom/sql/type_serializer.rb +2 -0
  88. data/lib/rom/sql/types.rb +2 -0
  89. data/lib/rom/sql/version.rb +3 -1
  90. data/lib/rom/sql/wrap.rb +2 -0
  91. data/lib/rom/types/values.rb +2 -0
  92. metadata +25 -45
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ipaddr'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sequel/core'
2
4
 
3
5
  Sequel.extension(:pg_range, :pg_range_ops)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/log_subscriber'
2
4
 
3
5
  module ROM
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/extensions/sqlite/types'
2
4
  require 'rom/sql/extensions/sqlite/type_builder'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  module SQLite
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry-types'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  # @api private
@@ -5,7 +7,7 @@ module ROM
5
7
  extend Initializer
6
8
  include Dry::Equalizer(:attributes, :parent_table, :options)
7
9
 
8
- DEFAULT_PARENT_KEYS = %i(id).freeze
10
+ DEFAULT_PARENT_KEYS = %i[id].freeze
9
11
 
10
12
  param :attributes
11
13
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/attribute'
2
4
  require 'rom/sql/attribute_wrapping'
3
5
 
@@ -76,10 +78,19 @@ module ROM
76
78
  )
77
79
  end
78
80
 
81
+ # @see Attribute#qualified_projection
82
+ #
83
+ # @api private
84
+ def qualified_projection(table_alias = nil)
85
+ meta(
86
+ func: ::Sequel::SQL::Function.new(func.name, *func.args.map { |arg| arg.respond_to?(:qualified_projection) ? arg.qualified_projection(table_alias) : arg })
87
+ )
88
+ end
89
+
79
90
  # @see Attribute#qualified?
80
91
  #
81
92
  # @api private
82
- def qualified?(table_alias = nil)
93
+ def qualified?(_table_alias = nil)
83
94
  meta[:func].args.all?(&:qualified?)
84
95
  end
85
96
 
@@ -184,7 +195,7 @@ module ROM
184
195
  # users.project { integer::count(:id).filter(name.is("Jack")).as(:jacks) }.order(nil)
185
196
  # users.project { integer::count(:id).filter { name.is("John") }).as(:johns) }.order(nil)
186
197
  #
187
- # @param [Hash,SQL::Attribute] Conditions
198
+ # @param condition [Hash,SQL::Attribute] Conditions
188
199
  # @yield [block] A block with restrictions
189
200
  #
190
201
  # @return [SQL::Function]
@@ -209,7 +220,7 @@ module ROM
209
220
  # @example
210
221
  # households.project { fload::percentile_cont(0.5).within_group(income).as(:percentile) }
211
222
  #
212
- # @param [Array] A list of expressions for sorting within a group
223
+ # @param args [Array] A list of expressions for sorting within a group
213
224
  # @yield [block] A block for getting the expressions using the Order DSL
214
225
  #
215
226
  # @return [SQL::Function]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'logger'
2
4
  require 'sequel/core'
3
5
 
@@ -21,7 +23,7 @@ module ROM
21
23
  adapter :sql
22
24
 
23
25
  CONNECTION_EXTENSIONS = {
24
- postgres: %i(pg_array pg_json pg_enum)
26
+ postgres: %i[pg_array pg_json pg_enum]
25
27
  }.freeze
26
28
 
27
29
  # @!attribute [r] logger
@@ -79,6 +81,7 @@ module ROM
79
81
  def initialize(uri, options = EMPTY_HASH)
80
82
  @connection = connect(uri, options)
81
83
  load_extensions(Array(options[:extensions]))
84
+ Notifications.trigger("configuration.gateway.connected", connection: @connection)
82
85
 
83
86
  @options = options
84
87
 
@@ -245,4 +248,6 @@ module ROM
245
248
  end
246
249
  end
247
250
  end
251
+
252
+ Configuration.register_event("configuration.gateway.connected")
248
253
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/dsl'
2
4
 
3
5
  module ROM
data/lib/rom/sql/index.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  # @api private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/restriction_dsl'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/mapper_compiler'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/migration/migrator'
2
4
  require 'rom/sql/migration/schema_diff'
3
5
 
@@ -97,7 +99,7 @@ module ROM
97
99
  attr_reader :migrator
98
100
 
99
101
  # @api private
100
- def initialize(uri, options = EMPTY_HASH)
102
+ def initialize(_uri, options = EMPTY_HASH)
101
103
  @migrator = create_migrator(options[:migrator])
102
104
 
103
105
  self.class.instance ||= self
@@ -139,7 +141,7 @@ module ROM
139
141
  end
140
142
 
141
143
  # @api public
142
- def auto_migrate!(conf, options = EMPTY_HASH, &block)
144
+ def auto_migrate!(conf, options = EMPTY_HASH)
143
145
  schemas = conf.relation_classes(self).map do |klass|
144
146
  klass.schema_proc.call.finalize_attributes!(gateway: self)
145
147
  end
@@ -156,7 +158,7 @@ module ROM
156
158
  return Migrator.new(connection) unless migrator_option
157
159
 
158
160
  if migrator_option.is_a?(Hash)
159
- Migrator.new(connection, migrator_option)
161
+ Migrator.new(connection, **migrator_option)
160
162
  else
161
163
  migrator_option
162
164
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  module Migration
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'rom/types'
@@ -65,12 +67,12 @@ module ROM
65
67
  end
66
68
 
67
69
  # @api private
68
- def auto_migrate!(gateway, schemas, options = EMPTY_HASH, &block)
70
+ def auto_migrate!(gateway, schemas, options = EMPTY_HASH)
69
71
  diff_finder = SchemaDiff.new(gateway.database_type)
70
72
 
71
73
  changes = schemas.map { |target|
72
74
  empty = SQL::Schema.define(target.name)
73
- current = target.with(inferrer.(empty, gateway))
75
+ current = target.with(**inferrer.(empty, gateway))
74
76
 
75
77
  diff_finder.(current, target)
76
78
  }.reject(&:empty?)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  module Migration
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  module Migration
@@ -67,8 +69,8 @@ module ROM
67
69
  if attribute.type_changed?
68
70
  from, to = attribute.current.unwrap, attribute.target.unwrap
69
71
  raise UnsupportedConversion.new(
70
- "Don't know how to convert #{ from.inspect } to #{ to.inspect }"
71
- )
72
+ "Don't know how to convert #{from.inspect} to #{to.inspect}"
73
+ )
72
74
  end
73
75
 
74
76
  if attribute.nullability_changed?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/type_serializer'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ROM::SQL.migration do
2
4
  change do
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/migration/recorder'
2
4
 
3
5
  module ROM
@@ -32,7 +34,7 @@ module ROM
32
34
  operations.each do |operation|
33
35
  op, args, nested = operation
34
36
  buffer << indent << op.to_s << ' '
35
- write_arguments(buffer, *args)
37
+ write_arguments(buffer, args)
36
38
 
37
39
  if !nested.empty?
38
40
  buffer << ' do'
@@ -42,9 +44,15 @@ module ROM
42
44
  end
43
45
  end
44
46
 
45
- def write_arguments(buffer, *args, **kwargs)
47
+ def write_arguments(buffer, args)
48
+ if args.last.is_a?(::Hash)
49
+ args, options = args[0...-1], args.last
50
+ else
51
+ options = EMPTY_HASH
52
+ end
53
+
46
54
  buffer << args.map(&:inspect).join(', ')
47
- kwargs.each do |key, value|
55
+ options.each do |key, value|
48
56
  buffer << ', ' << key.to_s << ': ' << value.inspect
49
57
  end
50
58
  end
@@ -53,7 +61,7 @@ module ROM
53
61
  create_or_alter, args = op
54
62
  table_name = args[0]
55
63
 
56
- "#{ create_or_alter.to_s.sub('_table', '') }_#{ table_name }"
64
+ "#{create_or_alter.to_s.sub('_table', '')}_#{table_name}"
57
65
  end
58
66
  end
59
67
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/dsl'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/associations'
2
4
 
3
5
  module ROM
@@ -48,7 +50,7 @@ module ROM
48
50
  # @see ROM::Command::ClassInterface.build
49
51
  #
50
52
  # @api public
51
- def build(relation, options = EMPTY_HASH)
53
+ def build(relation, **options)
52
54
  command = super
53
55
 
54
56
  configured_assocs = command.configured_associations
@@ -146,7 +148,7 @@ module ROM
146
148
  def with_association(name, opts = EMPTY_HASH)
147
149
  self.class.build(
148
150
  relation,
149
- { **options, associations: associations.merge(name => opts) }
151
+ **options, associations: associations.merge(name => opts)
150
152
  )
151
153
  end
152
154
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  module Plugin
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/initializer'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/plugins/relation/sql/instrumentation'
2
4
  require 'rom/plugins/relation/sql/auto_restrictions'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/dsl'
2
4
  require 'rom/sql/function'
3
5
 
@@ -29,7 +31,7 @@ module ROM
29
31
  # users.select { function(:count, :id).as(:total) }
30
32
  #
31
33
  # @param [Symbol] name SQL function
32
- # @param [Symbol] attr
34
+ # @param [Symbol] attrs
33
35
  #
34
36
  # @return [Rom::SQL::Function]
35
37
  #
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
  load 'rom/sql/tasks/migration_tasks.rake'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/types'
2
4
  require 'rom/sql/schema'
3
5
  require 'rom/sql/attribute'
@@ -35,7 +37,7 @@ module ROM
35
37
  table = opts[:from].first
36
38
 
37
39
  if db.table_exists?(table)
38
- select(*schema.map(&:qualified)).order(*schema.project(*schema.primary_key_names).qualified)
40
+ select(*schema.qualified_projection).order(*schema.project(*schema.primary_key_names).qualified)
39
41
  else
40
42
  self
41
43
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/support/inflector'
2
4
  require 'rom/sql/join_dsl'
3
5
 
@@ -891,8 +893,8 @@ module ROM
891
893
  # @yieldparam relation [Array]
892
894
  #
893
895
  # @api public
894
- def lock(options = EMPTY_HASH, &block)
895
- clause = lock_clause(options)
896
+ def lock(**options, &block)
897
+ clause = lock_clause(**options)
896
898
 
897
899
  if block
898
900
  transaction do
@@ -1036,7 +1038,7 @@ module ROM
1036
1038
  stmt << ' OF ' << Array(of).join(', ') if of
1037
1039
 
1038
1040
  if skip_locked
1039
- raise ArgumentError, "SKIP LOCKED cannot be used with (NO)WAIT clause" if !wait.nil?
1041
+ raise ArgumentError, 'SKIP LOCKED cannot be used with (NO)WAIT clause' if !wait.nil?
1040
1042
 
1041
1043
  stmt << ' SKIP LOCKED'
1042
1044
  else
@@ -1092,7 +1094,7 @@ module ROM
1092
1094
  join_opts = EMPTY_HASH
1093
1095
  end
1094
1096
 
1095
- new(dataset.__send__(type, other.name.to_sym, join_cond, join_opts))
1097
+ new(dataset.__send__(type, other.name.dataset.to_sym, join_cond, join_opts))
1096
1098
  else
1097
1099
  associations[other.name.key].join(type, self, other)
1098
1100
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module SQL
3
5
  class Relation < ROM::Relation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/sql/dsl'
2
4
 
3
5
  module ROM
@@ -6,7 +8,13 @@ module ROM
6
8
  class RestrictionDSL < DSL
7
9
  # @api private
8
10
  def call(&block)
9
- instance_exec(select_relations(block.parameters), &block)
11
+ arg, kwargs = select_relations(block.parameters)
12
+
13
+ if kwargs.nil?
14
+ instance_exec(arg, &block)
15
+ else
16
+ instance_exec(**kwargs, &block)
17
+ end
10
18
  end
11
19
 
12
20
  private