rom-sql 2.0.0.beta2 → 2.0.0.beta3

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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/lib/rom/plugins/relation/sql/postgres/explain.rb +54 -0
  4. data/lib/rom/sql.rb +1 -1
  5. data/lib/rom/sql/attribute.rb +17 -18
  6. data/lib/rom/sql/errors.rb +3 -0
  7. data/lib/rom/sql/extensions/mysql.rb +1 -1
  8. data/lib/rom/sql/extensions/mysql/type_builder.rb +28 -0
  9. data/lib/rom/sql/extensions/postgres.rb +3 -1
  10. data/lib/rom/sql/extensions/postgres/commands.rb +30 -13
  11. data/lib/rom/sql/extensions/postgres/{attributes_inferrer.rb → type_builder.rb} +24 -28
  12. data/lib/rom/sql/extensions/postgres/type_serializer.rb +39 -0
  13. data/lib/rom/sql/extensions/postgres/types.rb +24 -477
  14. data/lib/rom/sql/extensions/postgres/types/array.rb +163 -0
  15. data/lib/rom/sql/extensions/postgres/types/geometric.rb +135 -0
  16. data/lib/rom/sql/extensions/postgres/types/json.rb +235 -0
  17. data/lib/rom/sql/extensions/postgres/types/network.rb +15 -0
  18. data/lib/rom/sql/extensions/sqlite.rb +1 -1
  19. data/lib/rom/sql/extensions/sqlite/{attributes_inferrer.rb → type_builder.rb} +5 -5
  20. data/lib/rom/sql/extensions/sqlite/types.rb +8 -3
  21. data/lib/rom/sql/foreign_key.rb +17 -0
  22. data/lib/rom/sql/function.rb +86 -8
  23. data/lib/rom/sql/gateway.rb +26 -26
  24. data/lib/rom/sql/index.rb +4 -0
  25. data/lib/rom/sql/migration.rb +3 -3
  26. data/lib/rom/sql/migration/inline_runner.rb +9 -83
  27. data/lib/rom/sql/migration/migrator.rb +35 -12
  28. data/lib/rom/sql/migration/recorder.rb +21 -0
  29. data/lib/rom/sql/migration/runner.rb +115 -0
  30. data/lib/rom/sql/migration/schema_diff.rb +108 -53
  31. data/lib/rom/sql/migration/writer.rb +61 -0
  32. data/lib/rom/sql/relation.rb +2 -1
  33. data/lib/rom/sql/relation/reading.rb +63 -3
  34. data/lib/rom/sql/relation/writing.rb +38 -0
  35. data/lib/rom/sql/schema.rb +9 -3
  36. data/lib/rom/sql/schema/attributes_inferrer.rb +3 -119
  37. data/lib/rom/sql/schema/inferrer.rb +99 -18
  38. data/lib/rom/sql/schema/type_builder.rb +94 -0
  39. data/lib/rom/sql/type_dsl.rb +30 -0
  40. data/lib/rom/sql/type_extensions.rb +11 -6
  41. data/lib/rom/sql/type_serializer.rb +46 -0
  42. data/lib/rom/sql/types.rb +12 -0
  43. data/lib/rom/sql/version.rb +1 -1
  44. metadata +26 -244
  45. data/.codeclimate.yml +0 -15
  46. data/.gitignore +0 -17
  47. data/.rspec +0 -3
  48. data/.travis.yml +0 -39
  49. data/.yardopts +0 -2
  50. data/Gemfile +0 -33
  51. data/Guardfile +0 -24
  52. data/LICENSE.txt +0 -22
  53. data/Rakefile +0 -19
  54. data/circle.yml +0 -10
  55. data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +0 -10
  56. data/lib/rom/sql/relation/sequel_api.rb +0 -133
  57. data/log/.gitkeep +0 -0
  58. data/rom-sql.gemspec +0 -29
  59. data/spec/extensions/postgres/attribute_spec.rb +0 -217
  60. data/spec/extensions/postgres/integration_spec.rb +0 -59
  61. data/spec/extensions/postgres/types_spec.rb +0 -252
  62. data/spec/extensions/sqlite/types_spec.rb +0 -11
  63. data/spec/fixtures/migrations/20150403090603_create_carrots.rb +0 -8
  64. data/spec/integration/associations/many_to_many/custom_fks_spec.rb +0 -76
  65. data/spec/integration/associations/many_to_many/from_view_spec.rb +0 -88
  66. data/spec/integration/associations/many_to_many_spec.rb +0 -162
  67. data/spec/integration/associations/many_to_one/custom_fks_spec.rb +0 -64
  68. data/spec/integration/associations/many_to_one/from_view_spec.rb +0 -84
  69. data/spec/integration/associations/many_to_one/self_ref_spec.rb +0 -53
  70. data/spec/integration/associations/many_to_one_spec.rb +0 -117
  71. data/spec/integration/associations/one_to_many/custom_fks_spec.rb +0 -54
  72. data/spec/integration/associations/one_to_many/from_view_spec.rb +0 -57
  73. data/spec/integration/associations/one_to_many/self_ref_spec.rb +0 -54
  74. data/spec/integration/associations/one_to_many_spec.rb +0 -86
  75. data/spec/integration/associations/one_to_one_spec.rb +0 -69
  76. data/spec/integration/associations/one_to_one_through_spec.rb +0 -92
  77. data/spec/integration/auto_migrations/errors_spec.rb +0 -31
  78. data/spec/integration/auto_migrations/indexes_spec.rb +0 -253
  79. data/spec/integration/auto_migrations/managing_columns_spec.rb +0 -156
  80. data/spec/integration/auto_migrations/postgres/column_types_spec.rb +0 -63
  81. data/spec/integration/combine_with_spec.rb +0 -43
  82. data/spec/integration/commands/create_spec.rb +0 -304
  83. data/spec/integration/commands/delete_spec.rb +0 -84
  84. data/spec/integration/commands/update_spec.rb +0 -90
  85. data/spec/integration/commands/upsert_spec.rb +0 -83
  86. data/spec/integration/gateway_spec.rb +0 -107
  87. data/spec/integration/migration_spec.rb +0 -55
  88. data/spec/integration/plugins/associates/many_to_many_spec.rb +0 -69
  89. data/spec/integration/plugins/associates_spec.rb +0 -250
  90. data/spec/integration/plugins/auto_restrictions_spec.rb +0 -74
  91. data/spec/integration/relation_schema_spec.rb +0 -271
  92. data/spec/integration/schema/call_spec.rb +0 -24
  93. data/spec/integration/schema/inferrer/mysql_spec.rb +0 -45
  94. data/spec/integration/schema/inferrer/postgres_spec.rb +0 -203
  95. data/spec/integration/schema/inferrer/sqlite_spec.rb +0 -37
  96. data/spec/integration/schema/inferrer_spec.rb +0 -390
  97. data/spec/integration/schema/prefix_spec.rb +0 -16
  98. data/spec/integration/schema/qualified_spec.rb +0 -16
  99. data/spec/integration/schema/rename_spec.rb +0 -21
  100. data/spec/integration/schema/view_spec.rb +0 -29
  101. data/spec/integration/sequel_api_spec.rb +0 -36
  102. data/spec/integration/setup_spec.rb +0 -26
  103. data/spec/integration/support/active_support_notifications_spec.rb +0 -24
  104. data/spec/integration/support/rails_log_subscriber_spec.rb +0 -30
  105. data/spec/integration/wrap_spec.rb +0 -91
  106. data/spec/shared/accounts.rb +0 -48
  107. data/spec/shared/database_setup.rb +0 -70
  108. data/spec/shared/notes.rb +0 -23
  109. data/spec/shared/posts.rb +0 -34
  110. data/spec/shared/puppies.rb +0 -15
  111. data/spec/shared/relations.rb +0 -8
  112. data/spec/shared/users.rb +0 -32
  113. data/spec/shared/users_and_tasks.rb +0 -50
  114. data/spec/spec_helper.rb +0 -122
  115. data/spec/support/env_helper.rb +0 -25
  116. data/spec/support/helpers.rb +0 -24
  117. data/spec/support/oracle/create_users.sql +0 -7
  118. data/spec/support/oracle/set_sys_passwords.sql +0 -2
  119. data/spec/support/test_configuration.rb +0 -16
  120. data/spec/unit/attribute_spec.rb +0 -104
  121. data/spec/unit/function_spec.rb +0 -48
  122. data/spec/unit/gateway_spec.rb +0 -70
  123. data/spec/unit/logger_spec.rb +0 -14
  124. data/spec/unit/migration_tasks_spec.rb +0 -111
  125. data/spec/unit/migrator_spec.rb +0 -25
  126. data/spec/unit/order_dsl_spec.rb +0 -43
  127. data/spec/unit/plugin/associates_spec.rb +0 -94
  128. data/spec/unit/plugin/pagination_spec.rb +0 -91
  129. data/spec/unit/plugin/timestamp_spec.rb +0 -117
  130. data/spec/unit/projection_dsl_spec.rb +0 -110
  131. data/spec/unit/relation/assoc_spec.rb +0 -87
  132. data/spec/unit/relation/associations_spec.rb +0 -27
  133. data/spec/unit/relation/avg_spec.rb +0 -11
  134. data/spec/unit/relation/by_pk_spec.rb +0 -62
  135. data/spec/unit/relation/dataset_spec.rb +0 -50
  136. data/spec/unit/relation/distinct_spec.rb +0 -15
  137. data/spec/unit/relation/exclude_spec.rb +0 -11
  138. data/spec/unit/relation/exist_predicate_spec.rb +0 -25
  139. data/spec/unit/relation/exists_spec.rb +0 -18
  140. data/spec/unit/relation/fetch_spec.rb +0 -21
  141. data/spec/unit/relation/group_spec.rb +0 -61
  142. data/spec/unit/relation/having_spec.rb +0 -22
  143. data/spec/unit/relation/inner_join_spec.rb +0 -158
  144. data/spec/unit/relation/inspect_spec.rb +0 -11
  145. data/spec/unit/relation/instrument_spec.rb +0 -45
  146. data/spec/unit/relation/invert_spec.rb +0 -11
  147. data/spec/unit/relation/left_join_spec.rb +0 -55
  148. data/spec/unit/relation/lock_spec.rb +0 -93
  149. data/spec/unit/relation/map_spec.rb +0 -16
  150. data/spec/unit/relation/max_spec.rb +0 -11
  151. data/spec/unit/relation/min_spec.rb +0 -11
  152. data/spec/unit/relation/order_spec.rb +0 -51
  153. data/spec/unit/relation/pluck_spec.rb +0 -11
  154. data/spec/unit/relation/prefix_spec.rb +0 -29
  155. data/spec/unit/relation/primary_key_spec.rb +0 -27
  156. data/spec/unit/relation/project_spec.rb +0 -24
  157. data/spec/unit/relation/qualified_columns_spec.rb +0 -30
  158. data/spec/unit/relation/qualified_spec.rb +0 -25
  159. data/spec/unit/relation/read_spec.rb +0 -25
  160. data/spec/unit/relation/rename_spec.rb +0 -23
  161. data/spec/unit/relation/right_join_spec.rb +0 -57
  162. data/spec/unit/relation/select_append_spec.rb +0 -21
  163. data/spec/unit/relation/select_spec.rb +0 -40
  164. data/spec/unit/relation/sum_spec.rb +0 -11
  165. data/spec/unit/relation/union_spec.rb +0 -19
  166. data/spec/unit/relation/unique_predicate_spec.rb +0 -18
  167. data/spec/unit/relation/where_spec.rb +0 -133
  168. data/spec/unit/restriction_dsl_spec.rb +0 -34
  169. data/spec/unit/schema_spec.rb +0 -25
  170. data/spec/unit/types_spec.rb +0 -65
@@ -1,496 +1,43 @@
1
- require 'dry/types'
2
- require 'sequel'
3
- require 'ipaddr'
1
+ require 'sequel/core'
4
2
 
5
3
  require 'rom/sql/type_extensions'
6
4
 
7
- Sequel.extension(*%i(pg_array pg_array_ops pg_json pg_json_ops pg_hstore))
5
+ Sequel.extension(:pg_hstore)
8
6
 
9
7
  module ROM
10
8
  module SQL
11
- module Types
12
- module PG
13
- # UUID
14
-
15
- UUID = Types::String
16
-
17
- # Array
18
-
19
- Array = Types.Definition(Sequel::Postgres::PGArray)
20
-
21
- def self.Array(db_type)
22
- Array.constructor(-> (v) { Sequel.pg_array(v, db_type) }).meta(type: db_type)
23
- end
24
-
25
- # @!parse
26
- # class ROM::SQL::Attribute
27
- # # @!method contain(other)
28
- # # Check whether the array includes another array
29
- # # Translates to the @> operator
30
- # #
31
- # # @param [Array] other
32
- # #
33
- # # @return [SQL::Attribute<Types::Bool>]
34
- # #
35
- # # @api public
36
- #
37
- # # @!method get(idx)
38
- # # Get element by index (PG uses 1-based indexing)
39
- # #
40
- # # @param [Integer] idx
41
- # #
42
- # # @return [SQL::Attribute]
43
- # #
44
- # # @api public
45
- #
46
- # # @!method any(value)
47
- # # Check whether the array includes a value
48
- # # Translates to the ANY operator
49
- # #
50
- # # @param [Object] value
51
- # #
52
- # # @return [SQL::Attribute<Types::Bool>]
53
- # #
54
- # # @api public
55
- #
56
- # # @!method contained_by(other)
57
- # # Check whether the array is contained by another array
58
- # # Translates to the <@ operator
59
- # #
60
- # # @param [Array] other
61
- # #
62
- # # @return [SQL::Attribute<Types::Bool>]
63
- # #
64
- # # @api public
65
- #
66
- # # @!method length
67
- # # Return array size
68
- # #
69
- # # @return [SQL::Attribute<Types::Int>]
70
- # #
71
- # # @api public
72
- #
73
- # # @!method overlaps(other)
74
- # # Check whether the arrays have common values
75
- # # Translates to &&
76
- # #
77
- # # @param [Array] other
78
- # #
79
- # # @return [SQL::Attribute<Types::Bool>]
80
- # #
81
- # # @api public
82
- #
83
- # # @!method remove_value(value)
84
- # # Remove elements by value
85
- # #
86
- # # @param [Object] value
87
- # #
88
- # # @return [SQL::Attribute<Types::PG::Array>]
89
- # #
90
- # # @api public
91
- #
92
- # # @!method join(delimiter, null_repr)
93
- # # Convert the array to a string by joining
94
- # # values with a delimiter (empty stirng by default)
95
- # # and optional filler for NULL values
96
- # # Translates to an `array_to_string` call
97
- # #
98
- # # @param [Object] delimiter
99
- # # @param [Object] null
100
- # #
101
- # # @return [SQL::Attribute<Types::String>]
102
- # #
103
- # # @api public
104
- #
105
- # # @!method +(other)
106
- # # Concatenate two arrays
107
- # #
108
- # # @param [Array] other
109
- # #
110
- # # @return [SQL::Attribute<Types::PG::Array>]
111
- # #
112
- # # @api public
113
- # end
114
- TypeExtensions.register(Array.constructor -> { }) do
115
- def contain(type, expr, other)
116
- Attribute[Types::Bool].meta(sql_expr: expr.pg_array.contains(type[other]))
117
- end
118
-
119
- def get(type, expr, idx)
120
- Attribute[type].meta(sql_expr: expr.pg_array[idx])
121
- end
122
-
123
- def any(type, expr, value)
124
- Attribute[Types::Bool].meta(sql_expr: { value => expr.pg_array.any })
125
- end
126
-
127
- def contained_by(type, expr, other)
128
- Attribute[Types::Bool].meta(sql_expr: expr.pg_array.contained_by(type[other]))
129
- end
130
-
131
- def length(type, expr)
132
- Attribute[Types::Int].meta(sql_expr: expr.pg_array.length)
133
- end
134
-
135
- def overlaps(type, expr, other_array)
136
- Attribute[Types::Bool].meta(sql_expr: expr.pg_array.overlaps(type[other_array]))
137
- end
138
-
139
- def remove_value(type, expr, value)
140
- Attribute[type].meta(sql_expr: expr.pg_array.remove(value))
141
- end
142
-
143
- def join(type, expr, delimiter = '', null = nil)
144
- Attribute[Types::String].meta(sql_expr: expr.pg_array.join(delimiter, null))
145
- end
146
-
147
- def +(type, expr, other)
148
- Attribute[type].meta(sql_expr: expr.pg_array.concat(other))
149
- end
150
- end
151
-
152
- # JSON
153
-
154
- JSONArray = Types.Constructor(Sequel::Postgres::JSONArray, &Sequel.method(:pg_json))
155
-
156
- JSONHash = Types.Constructor(Sequel::Postgres::JSONArray, &Sequel.method(:pg_json))
157
-
158
- JSONOp = Types.Constructor(Sequel::Postgres::JSONOp, &Sequel.method(:pg_json))
159
-
160
- JSON = JSONArray | JSONHash | JSONOp
161
-
162
- # JSONB
163
-
164
- JSONBArray = Types.Constructor(Sequel::Postgres::JSONBArray, &Sequel.method(:pg_jsonb))
165
-
166
- JSONBHash = Types.Constructor(Sequel::Postgres::JSONBHash, &Sequel.method(:pg_jsonb))
167
-
168
- JSONBOp = Types.Constructor(Sequel::Postgres::JSONBOp, &Sequel.method(:pg_jsonb))
169
-
170
- JSONB = JSONBArray | JSONBHash | JSONBOp
171
-
172
- # @!parse
173
- # class ROM::SQL::Attribute
174
- # # @!method contain(value)
175
- # # Check whether the JSON value includes a json value
176
- # # Translates to the @> operator
177
- # #
178
- # # @example
179
- # # people.where { fields.contain(gender: 'Female') }
180
- # # people.where(people[:fields].contain([name: 'age']))
181
- # # people.select { fields.contain(gender: 'Female').as(:is_female) }
182
- # #
183
- # # @param [Hash,Array,Object] value
184
- # #
185
- # # @return [SQL::Attribute<Types::Bool>]
186
- # #
187
- # # @api public
188
- #
189
- # # @!method contained_by(value)
190
- # # Check whether the JSON value is contained by other value
191
- # # Translates to the <@ operator
192
- # #
193
- # # @example
194
- # # people.where { custom_values.contained_by(age: 25, foo: 'bar') }
195
- # #
196
- # # @param [Hash,Array] value
197
- # #
198
- # # @return [SQL::Attribute<Types::Bool>]
199
- # #
200
- # # @api public
201
- #
202
- # # @!method get(*path)
203
- # # Extract the JSON value using at the specified path
204
- # # Translates to -> or #> depending on the number of arguments
205
- # #
206
- # # @example
207
- # # people.select { data.get('age').as(:person_age) }
208
- # # people.select { fields.get(0).as(:first_field) }
209
- # # people.select { fields.get('0', 'value').as(:first_field_value) }
210
- # #
211
- # # @param [Array<Integer>,Array<String>] path Path to extract
212
- # #
213
- # # @return [SQL::Attribute<Types::PG::JSON>,SQL::Attribute<Types::PG::JSONB>]
214
- # #
215
- # # @api public
216
- #
217
- # # @!method get_text(*path)
218
- # # Extract the JSON value as text using at the specified path
219
- # # Translates to ->> or #>> depending on the number of arguments
220
- # #
221
- # # @example
222
- # # people.select { data.get('age').as(:person_age) }
223
- # # people.select { fields.get(0).as(:first_field) }
224
- # # people.select { fields.get('0', 'value').as(:first_field_value) }
225
- # #
226
- # # @param [Array<Integer>,Array<String>] path Path to extract
227
- # #
228
- # # @return [SQL::Attribute<Types::String>]
229
- # #
230
- # # @api public
231
- #
232
- # # @!method has_key(key)
233
- # # Does the JSON value have the specified top-level key
234
- # # Translates to ?
235
- # #
236
- # # @example
237
- # # people.where { data.has_key('age') }
238
- # #
239
- # # @param [String] key
240
- # #
241
- # # @return [SQL::Attribute<Types::Bool>]
242
- # #
243
- # # @api public
244
- #
245
- # # @!method has_any_key(*keys)
246
- # # Does the JSON value have any of the specified top-level keys
247
- # # Translates to ?|
248
- # #
249
- # # @example
250
- # # people.where { data.has_any_key('age', 'height') }
251
- # #
252
- # # @param [Array<String>] keys
253
- # #
254
- # # @return [SQL::Attribute<Types::Bool>]
255
- # #
256
- # # @api public
257
- #
258
- # # @!method has_all_keys(*keys)
259
- # # Does the JSON value have all the specified top-level keys
260
- # # Translates to ?&
261
- # #
262
- # # @example
263
- # # people.where { data.has_all_keys('age', 'height') }
264
- # #
265
- # # @param [Array<String>] keys
266
- # #
267
- # # @return [SQL::Attribute<Types::Bool>]
268
- # #
269
- # # @api public
270
- #
271
- # # @!method merge(value)
272
- # # Concatenate two JSON values
273
- # # Translates to ||
274
- # #
275
- # # @example
276
- # # people.select { data.merge(fetched_at: Time.now).as(:data) }
277
- # # people.select { (fields + [name: 'height', value: 165]).as(:fields) }
278
- # #
279
- # # @param [Hash,Array] value
280
- # #
281
- # # @return [SQL::Attribute<Types::PG::JSONB>]
282
- # #
283
- # # @api public
284
- #
285
- # # @!method +(value)
286
- # # An alias for ROM::SQL::Attribute<JSONB>#merge
287
- # #
288
- # # @api public
289
- #
290
- # # @!method delete(*path)
291
- # # Deletes the specified value by key, index, or path
292
- # # Translates to - or #- depending on the number of arguments
293
- # #
294
- # # @example
295
- # # people.select { data.delete('age').as(:data_without_age) }
296
- # # people.select { fields.delete(0).as(:fields_without_first) }
297
- # # people.select { fields.delete(-1).as(:fields_without_last) }
298
- # # people.select { data.delete('deeply', 'nested', 'value').as(:data) }
299
- # # people.select { fields.delete('0', 'name').as(:data) }
300
- # #
301
- # # @param [Array<String>] path
302
- # #
303
- # # @return [SQL::Attribute<Types::PG::JSONB>]
304
- # #
305
- # # @api public
306
- # end
307
- module JSONMethods
308
- def self.[](type, wrap)
309
- parent = self
310
- Module.new do
311
- include parent
312
- define_method(:json_type) { type }
313
- define_method(:wrap, wrap)
314
- end
315
- end
316
-
317
- def get(type, expr, *path)
318
- Attribute[json_type].meta(sql_expr: wrap(expr)[path_args(path)])
319
- end
320
-
321
- def get_text(type, expr, *path)
322
- Attribute[Types::String].meta(sql_expr: wrap(expr).get_text(path_args(path)))
323
- end
324
-
325
- private
326
-
327
- def path_args(path)
328
- case path.size
329
- when 0 then raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
330
- when 1 then path[0]
331
- else path
332
- end
333
- end
334
- end
335
-
336
- TypeExtensions.register(JSON) do
337
- include JSONMethods[JSON, :pg_json.to_proc]
338
- end
339
-
340
- TypeExtensions.register(JSONB) do
341
- include JSONMethods[JSONB, :pg_jsonb.to_proc]
342
-
343
- def contain(type, expr, value)
344
- Attribute[Types::Bool].meta(sql_expr: wrap(expr).contains(value))
345
- end
346
-
347
- def contained_by(type, expr, value)
348
- Attribute[Types::Bool].meta(sql_expr: wrap(expr).contained_by(value))
349
- end
350
-
351
- def has_key(type, expr, key)
352
- Attribute[Types::Bool].meta(sql_expr: wrap(expr).has_key?(key))
353
- end
354
-
355
- def has_any_key(type, expr, *keys)
356
- Attribute[Types::Bool].meta(sql_expr: wrap(expr).contain_any(keys))
357
- end
358
-
359
- def has_all_keys(type, expr, *keys)
360
- Attribute[Types::Bool].meta(sql_expr: wrap(expr).contain_all(keys))
361
- end
362
-
363
- def merge(type, expr, value)
364
- Attribute[JSONB].meta(sql_expr: wrap(expr).concat(value))
365
- end
366
- alias_method :+, :merge
367
-
368
- def delete(type, expr, *path)
369
- sql_expr = path.size == 1 ? wrap(expr) - path : wrap(expr).delete_path(path)
370
- Attribute[JSONB].meta(sql_expr: sql_expr)
371
- end
372
- end
373
-
374
- # HStore
375
-
376
- HStoreR = Types.Constructor(Hash, &:to_hash)
377
- HStore = Types.Constructor(Sequel::Postgres::HStore, &Sequel.method(:hstore)).meta(read: HStoreR)
378
-
379
- Bytea = Types.Constructor(Sequel::SQL::Blob, &Sequel::SQL::Blob.method(:new))
380
-
381
- IPAddressR = Types.Constructor(IPAddr) { |ip| IPAddr.new(ip.to_s) }
382
-
383
- IPAddress = Types.Constructor(IPAddr, &:to_s).meta(read: IPAddressR)
384
-
385
- Money = Types::Decimal
386
-
387
- # Geometric types
388
-
389
- Point = ::Struct.new(:x, :y)
390
-
391
- PointD = Types.Definition(Point)
392
-
393
- PointTR = Types.Constructor(Point) do |p|
394
- x, y = p.to_s[1...-1].split(',', 2)
395
- Point.new(Float(x), Float(y))
396
- end
397
-
398
- PointT = Types.Constructor(Point) { |p| "(#{ p.x },#{ p.y })" }.meta(read: PointTR)
399
-
400
- Line = ::Struct.new(:a, :b, :c)
401
-
402
- LineTR = Types.Constructor(Line) do |ln|
403
- a, b, c = ln.to_s[1..-2].split(',', 3)
404
- Line.new(Float(a), Float(b), Float(c))
405
- end
406
-
407
- LineT = Types.Constructor(Line) { |ln| "{#{ ln.a },#{ ln.b },#{ln.c}}"}.meta(read: LineTR)
408
-
409
- Circle = ::Struct.new(:center, :radius)
410
-
411
- CircleTR = Types.Constructor(Circle) do |c|
412
- x, y, r = c.to_s.tr('()<>', '').split(',', 3)
413
- center = Point.new(Float(x), Float(y))
414
- Circle.new(center, Float(r))
415
- end
416
-
417
- CircleT = Types.Constructor(Circle) { |c| "<(#{ c.center.x },#{ c.center.y }),#{ c.radius }>" }.meta(read: CircleTR)
418
-
419
- Box = ::Struct.new(:upper_right, :lower_left)
420
-
421
- BoxTR = Types.Constructor(Box) do |b|
422
- x_right, y_right, x_left, y_left = b.to_s.tr('()', '').split(',', 4)
423
- upper_right = Point.new(Float(x_right), Float(y_right))
424
- lower_left = Point.new(Float(x_left), Float(y_left))
425
- Box.new(upper_right, lower_left)
426
- end
427
-
428
- BoxT = Types.Constructor(Box) { |b| "((#{ b.upper_right.x },#{ b.upper_right.y }),(#{ b.lower_left.x },#{ b.lower_left.y }))" }.meta(read: BoxTR)
429
-
430
- LineSegment = ::Struct.new(:begin, :end)
431
-
432
- LineSegmentTR = Types.Constructor(LineSegment) do |lseg|
433
- x_begin, y_begin, x_end, y_end = lseg.to_s.tr('()[]', '').split(',', 4)
434
- point_begin = Point.new(Float(x_begin), Float(y_begin))
435
- point_end = Point.new(Float(x_end), Float(y_end))
436
- LineSegment.new(point_begin, point_end)
437
- end
438
-
439
- LineSegmentT = Types.Constructor(LineSegment) do |lseg|
440
- "[(#{ lseg.begin.x },#{ lseg.begin.y }),(#{ lseg.end.x },#{ lseg.end.y })]"
441
- end.meta(read: LineSegmentTR)
442
-
443
- Polygon = Types::Strict::Array.member(PointD)
444
-
445
- PolygonTR = Polygon.constructor do |p|
446
- coordinates = p.to_s.tr('()', '').split(',').each_slice(2)
447
- points = coordinates.map { |x, y| Point.new(Float(x), Float(y)) }
448
- Polygon[points]
9
+ module Postgres
10
+ module Types
11
+ def self.Type(name, type = yield)
12
+ type.meta(db_type: name, database: 'postgres')
449
13
  end
450
14
 
451
- PolygonT = PointD.constructor do |path|
452
- points_joined = path.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
453
- "(#{ points_joined })"
454
- end.meta(read: PolygonTR)
15
+ UUID = Type('uuid', SQL::Types::String)
455
16
 
456
- Path = ::Struct.new(:points, :type) do
457
- def open?
458
- type == :open
459
- end
17
+ HStore = Type('hstore') do
18
+ read = SQL::Types.Constructor(Hash, &:to_hash)
460
19
 
461
- def closed?
462
- type == :closed
463
- end
464
-
465
- def to_a
466
- points
467
- end
20
+ SQL::Types.Constructor(Hash, &Sequel.method(:hstore))
21
+ .meta(read: read)
468
22
  end
469
23
 
470
- PathD = Types.Definition(Path)
471
-
472
- PathTR = PathD.constructor do |path|
473
- open = path.to_s.start_with?('[') && path.to_s.end_with?(']')
474
- coordinates = path.to_s.tr('()[]', '').split(',').each_slice(2)
475
- points = coordinates.map { |x, y| Point.new(Float(x), Float(y)) }
476
-
477
- if open
478
- Path.new(points, :open)
479
- else
480
- Path.new(points, :closed)
481
- end
24
+ Bytea = Type('bytea') do
25
+ SQL::Types.Constructor(Sequel::SQL::Blob, &Sequel::SQL::Blob.method(:new))
482
26
  end
483
27
 
484
- PathT = PathD.constructor do |path|
485
- points_joined = path.to_a.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
28
+ Money = Type('money', SQL::Types::Decimal)
486
29
 
487
- if path.open?
488
- "[#{ points_joined }]"
489
- else
490
- "(#{ points_joined })"
491
- end
492
- end.meta(read: PathTR)
30
+ XML = Type('xml', SQL::Types::String)
493
31
  end
494
32
  end
33
+
34
+ module Types
35
+ PG = Postgres::Types
36
+ end
495
37
  end
496
38
  end
39
+
40
+ require 'rom/sql/extensions/postgres/types/array'
41
+ require 'rom/sql/extensions/postgres/types/json'
42
+ require 'rom/sql/extensions/postgres/types/geometric'
43
+ require 'rom/sql/extensions/postgres/types/network'