rom-sql 2.0.0.beta2 → 2.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/lib/rom/plugins/relation/sql/postgres/explain.rb +54 -0
- data/lib/rom/sql.rb +1 -1
- data/lib/rom/sql/attribute.rb +17 -18
- data/lib/rom/sql/errors.rb +3 -0
- data/lib/rom/sql/extensions/mysql.rb +1 -1
- data/lib/rom/sql/extensions/mysql/type_builder.rb +28 -0
- data/lib/rom/sql/extensions/postgres.rb +3 -1
- data/lib/rom/sql/extensions/postgres/commands.rb +30 -13
- data/lib/rom/sql/extensions/postgres/{attributes_inferrer.rb → type_builder.rb} +24 -28
- data/lib/rom/sql/extensions/postgres/type_serializer.rb +39 -0
- data/lib/rom/sql/extensions/postgres/types.rb +24 -477
- data/lib/rom/sql/extensions/postgres/types/array.rb +163 -0
- data/lib/rom/sql/extensions/postgres/types/geometric.rb +135 -0
- data/lib/rom/sql/extensions/postgres/types/json.rb +235 -0
- data/lib/rom/sql/extensions/postgres/types/network.rb +15 -0
- data/lib/rom/sql/extensions/sqlite.rb +1 -1
- data/lib/rom/sql/extensions/sqlite/{attributes_inferrer.rb → type_builder.rb} +5 -5
- data/lib/rom/sql/extensions/sqlite/types.rb +8 -3
- data/lib/rom/sql/foreign_key.rb +17 -0
- data/lib/rom/sql/function.rb +86 -8
- data/lib/rom/sql/gateway.rb +26 -26
- data/lib/rom/sql/index.rb +4 -0
- data/lib/rom/sql/migration.rb +3 -3
- data/lib/rom/sql/migration/inline_runner.rb +9 -83
- data/lib/rom/sql/migration/migrator.rb +35 -12
- data/lib/rom/sql/migration/recorder.rb +21 -0
- data/lib/rom/sql/migration/runner.rb +115 -0
- data/lib/rom/sql/migration/schema_diff.rb +108 -53
- data/lib/rom/sql/migration/writer.rb +61 -0
- data/lib/rom/sql/relation.rb +2 -1
- data/lib/rom/sql/relation/reading.rb +63 -3
- data/lib/rom/sql/relation/writing.rb +38 -0
- data/lib/rom/sql/schema.rb +9 -3
- data/lib/rom/sql/schema/attributes_inferrer.rb +3 -119
- data/lib/rom/sql/schema/inferrer.rb +99 -18
- data/lib/rom/sql/schema/type_builder.rb +94 -0
- data/lib/rom/sql/type_dsl.rb +30 -0
- data/lib/rom/sql/type_extensions.rb +11 -6
- data/lib/rom/sql/type_serializer.rb +46 -0
- data/lib/rom/sql/types.rb +12 -0
- data/lib/rom/sql/version.rb +1 -1
- metadata +26 -244
- data/.codeclimate.yml +0 -15
- data/.gitignore +0 -17
- data/.rspec +0 -3
- data/.travis.yml +0 -39
- data/.yardopts +0 -2
- data/Gemfile +0 -33
- data/Guardfile +0 -24
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -19
- data/circle.yml +0 -10
- data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +0 -10
- data/lib/rom/sql/relation/sequel_api.rb +0 -133
- data/log/.gitkeep +0 -0
- data/rom-sql.gemspec +0 -29
- data/spec/extensions/postgres/attribute_spec.rb +0 -217
- data/spec/extensions/postgres/integration_spec.rb +0 -59
- data/spec/extensions/postgres/types_spec.rb +0 -252
- data/spec/extensions/sqlite/types_spec.rb +0 -11
- data/spec/fixtures/migrations/20150403090603_create_carrots.rb +0 -8
- data/spec/integration/associations/many_to_many/custom_fks_spec.rb +0 -76
- data/spec/integration/associations/many_to_many/from_view_spec.rb +0 -88
- data/spec/integration/associations/many_to_many_spec.rb +0 -162
- data/spec/integration/associations/many_to_one/custom_fks_spec.rb +0 -64
- data/spec/integration/associations/many_to_one/from_view_spec.rb +0 -84
- data/spec/integration/associations/many_to_one/self_ref_spec.rb +0 -53
- data/spec/integration/associations/many_to_one_spec.rb +0 -117
- data/spec/integration/associations/one_to_many/custom_fks_spec.rb +0 -54
- data/spec/integration/associations/one_to_many/from_view_spec.rb +0 -57
- data/spec/integration/associations/one_to_many/self_ref_spec.rb +0 -54
- data/spec/integration/associations/one_to_many_spec.rb +0 -86
- data/spec/integration/associations/one_to_one_spec.rb +0 -69
- data/spec/integration/associations/one_to_one_through_spec.rb +0 -92
- data/spec/integration/auto_migrations/errors_spec.rb +0 -31
- data/spec/integration/auto_migrations/indexes_spec.rb +0 -253
- data/spec/integration/auto_migrations/managing_columns_spec.rb +0 -156
- data/spec/integration/auto_migrations/postgres/column_types_spec.rb +0 -63
- data/spec/integration/combine_with_spec.rb +0 -43
- data/spec/integration/commands/create_spec.rb +0 -304
- data/spec/integration/commands/delete_spec.rb +0 -84
- data/spec/integration/commands/update_spec.rb +0 -90
- data/spec/integration/commands/upsert_spec.rb +0 -83
- data/spec/integration/gateway_spec.rb +0 -107
- data/spec/integration/migration_spec.rb +0 -55
- data/spec/integration/plugins/associates/many_to_many_spec.rb +0 -69
- data/spec/integration/plugins/associates_spec.rb +0 -250
- data/spec/integration/plugins/auto_restrictions_spec.rb +0 -74
- data/spec/integration/relation_schema_spec.rb +0 -271
- data/spec/integration/schema/call_spec.rb +0 -24
- data/spec/integration/schema/inferrer/mysql_spec.rb +0 -45
- data/spec/integration/schema/inferrer/postgres_spec.rb +0 -203
- data/spec/integration/schema/inferrer/sqlite_spec.rb +0 -37
- data/spec/integration/schema/inferrer_spec.rb +0 -390
- data/spec/integration/schema/prefix_spec.rb +0 -16
- data/spec/integration/schema/qualified_spec.rb +0 -16
- data/spec/integration/schema/rename_spec.rb +0 -21
- data/spec/integration/schema/view_spec.rb +0 -29
- data/spec/integration/sequel_api_spec.rb +0 -36
- data/spec/integration/setup_spec.rb +0 -26
- data/spec/integration/support/active_support_notifications_spec.rb +0 -24
- data/spec/integration/support/rails_log_subscriber_spec.rb +0 -30
- data/spec/integration/wrap_spec.rb +0 -91
- data/spec/shared/accounts.rb +0 -48
- data/spec/shared/database_setup.rb +0 -70
- data/spec/shared/notes.rb +0 -23
- data/spec/shared/posts.rb +0 -34
- data/spec/shared/puppies.rb +0 -15
- data/spec/shared/relations.rb +0 -8
- data/spec/shared/users.rb +0 -32
- data/spec/shared/users_and_tasks.rb +0 -50
- data/spec/spec_helper.rb +0 -122
- data/spec/support/env_helper.rb +0 -25
- data/spec/support/helpers.rb +0 -24
- data/spec/support/oracle/create_users.sql +0 -7
- data/spec/support/oracle/set_sys_passwords.sql +0 -2
- data/spec/support/test_configuration.rb +0 -16
- data/spec/unit/attribute_spec.rb +0 -104
- data/spec/unit/function_spec.rb +0 -48
- data/spec/unit/gateway_spec.rb +0 -70
- data/spec/unit/logger_spec.rb +0 -14
- data/spec/unit/migration_tasks_spec.rb +0 -111
- data/spec/unit/migrator_spec.rb +0 -25
- data/spec/unit/order_dsl_spec.rb +0 -43
- data/spec/unit/plugin/associates_spec.rb +0 -94
- data/spec/unit/plugin/pagination_spec.rb +0 -91
- data/spec/unit/plugin/timestamp_spec.rb +0 -117
- data/spec/unit/projection_dsl_spec.rb +0 -110
- data/spec/unit/relation/assoc_spec.rb +0 -87
- data/spec/unit/relation/associations_spec.rb +0 -27
- data/spec/unit/relation/avg_spec.rb +0 -11
- data/spec/unit/relation/by_pk_spec.rb +0 -62
- data/spec/unit/relation/dataset_spec.rb +0 -50
- data/spec/unit/relation/distinct_spec.rb +0 -15
- data/spec/unit/relation/exclude_spec.rb +0 -11
- data/spec/unit/relation/exist_predicate_spec.rb +0 -25
- data/spec/unit/relation/exists_spec.rb +0 -18
- data/spec/unit/relation/fetch_spec.rb +0 -21
- data/spec/unit/relation/group_spec.rb +0 -61
- data/spec/unit/relation/having_spec.rb +0 -22
- data/spec/unit/relation/inner_join_spec.rb +0 -158
- data/spec/unit/relation/inspect_spec.rb +0 -11
- data/spec/unit/relation/instrument_spec.rb +0 -45
- data/spec/unit/relation/invert_spec.rb +0 -11
- data/spec/unit/relation/left_join_spec.rb +0 -55
- data/spec/unit/relation/lock_spec.rb +0 -93
- data/spec/unit/relation/map_spec.rb +0 -16
- data/spec/unit/relation/max_spec.rb +0 -11
- data/spec/unit/relation/min_spec.rb +0 -11
- data/spec/unit/relation/order_spec.rb +0 -51
- data/spec/unit/relation/pluck_spec.rb +0 -11
- data/spec/unit/relation/prefix_spec.rb +0 -29
- data/spec/unit/relation/primary_key_spec.rb +0 -27
- data/spec/unit/relation/project_spec.rb +0 -24
- data/spec/unit/relation/qualified_columns_spec.rb +0 -30
- data/spec/unit/relation/qualified_spec.rb +0 -25
- data/spec/unit/relation/read_spec.rb +0 -25
- data/spec/unit/relation/rename_spec.rb +0 -23
- data/spec/unit/relation/right_join_spec.rb +0 -57
- data/spec/unit/relation/select_append_spec.rb +0 -21
- data/spec/unit/relation/select_spec.rb +0 -40
- data/spec/unit/relation/sum_spec.rb +0 -11
- data/spec/unit/relation/union_spec.rb +0 -19
- data/spec/unit/relation/unique_predicate_spec.rb +0 -18
- data/spec/unit/relation/where_spec.rb +0 -133
- data/spec/unit/restriction_dsl_spec.rb +0 -34
- data/spec/unit/schema_spec.rb +0 -25
- data/spec/unit/types_spec.rb +0 -65
@@ -1,496 +1,43 @@
|
|
1
|
-
require '
|
2
|
-
require 'sequel'
|
3
|
-
require 'ipaddr'
|
1
|
+
require 'sequel/core'
|
4
2
|
|
5
3
|
require 'rom/sql/type_extensions'
|
6
4
|
|
7
|
-
Sequel.extension(
|
5
|
+
Sequel.extension(:pg_hstore)
|
8
6
|
|
9
7
|
module ROM
|
10
8
|
module SQL
|
11
|
-
module
|
12
|
-
module
|
13
|
-
|
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
|
-
|
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
|
-
|
457
|
-
|
458
|
-
type == :open
|
459
|
-
end
|
17
|
+
HStore = Type('hstore') do
|
18
|
+
read = SQL::Types.Constructor(Hash, &:to_hash)
|
460
19
|
|
461
|
-
|
462
|
-
|
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
|
-
|
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
|
-
|
485
|
-
points_joined = path.to_a.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
|
28
|
+
Money = Type('money', SQL::Types::Decimal)
|
486
29
|
|
487
|
-
|
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'
|