mongery 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/mongery.rb +36 -42
- data/lib/mongery/version.rb +1 -1
- data/spec/mongery/builder_schema_spec.rb +10 -0
- data/spec/mongery/builder_spec.rb +10 -0
- data/spec/mongery/mapped_properties_spec.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6385d3fabb1f17ebd5637f248fab8b776d7718
|
4
|
+
data.tar.gz: 1acfe3b40ce8de1d187fa43b7ad4277cc6cf534e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21a99f928bd828a80391a10d90a0db8c8bd2401cebc8538df8d5d309fddd5d4bddd96c870bb3c99a1464a59889c786887aad59536f67bbf042c96f6bcf47bde6
|
7
|
+
data.tar.gz: bb095b44a1482056496e3a209169f27f3d6c255f621717d065a9be4132cd060281723f8f390dd1368420010d32ca6fb5c049d1f6fd1681fdd53c22a9a8e6ead9
|
data/CHANGELOG.md
CHANGED
data/lib/mongery.rb
CHANGED
@@ -5,12 +5,14 @@ require "arel"
|
|
5
5
|
module Mongery
|
6
6
|
class Builder
|
7
7
|
attr_reader :model, :table, :schema, :mapped_properties
|
8
|
+
attr_accessor :custom_operators
|
8
9
|
|
9
10
|
def initialize(model, engine = ActiveRecord::Base, schema = nil)
|
10
11
|
@model = model
|
11
12
|
@table = Arel::Table.new(model, engine)
|
12
13
|
@schema = Schema.new(schema) if schema
|
13
14
|
@mapped_properties = {}
|
15
|
+
@custom_operators = {}
|
14
16
|
end
|
15
17
|
|
16
18
|
def mapped_properties=(value)
|
@@ -23,25 +25,32 @@ module Mongery
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def find(*args)
|
26
|
-
|
28
|
+
build_query.where(*args)
|
27
29
|
end
|
28
30
|
|
29
31
|
def insert(*args)
|
30
|
-
|
32
|
+
build_query.insert(*args)
|
31
33
|
end
|
32
34
|
|
33
35
|
def index(*args)
|
34
|
-
|
36
|
+
build_query.index(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_query
|
42
|
+
Query.new(table, schema, mapped_properties, custom_operators)
|
35
43
|
end
|
36
44
|
end
|
37
45
|
|
38
46
|
class Query
|
39
|
-
attr_reader :table, :schema, :mapped_properties
|
47
|
+
attr_reader :table, :schema, :mapped_properties, :custom_operators
|
40
48
|
|
41
|
-
def initialize(table, schema, mapped_properties)
|
49
|
+
def initialize(table, schema, mapped_properties, custom_operators)
|
42
50
|
@table = table
|
43
51
|
@schema = schema
|
44
52
|
@mapped_properties = mapped_properties
|
53
|
+
@custom_operators = custom_operators
|
45
54
|
@condition = nil
|
46
55
|
end
|
47
56
|
|
@@ -179,7 +188,9 @@ module Mongery
|
|
179
188
|
when Hash
|
180
189
|
if has_operator?(value)
|
181
190
|
chain(:and, value.map {|op, val|
|
182
|
-
if
|
191
|
+
if custom_operators[op]
|
192
|
+
operator(col, custom_operators[op], val)
|
193
|
+
elsif OPERATOR_MAP.key?(op)
|
183
194
|
col.send(OPERATOR_MAP[op], val)
|
184
195
|
else
|
185
196
|
raise UnsupportedQuery, "Unknown operator #{op}"
|
@@ -193,36 +204,6 @@ module Mongery
|
|
193
204
|
end
|
194
205
|
end
|
195
206
|
|
196
|
-
def translate_value_dynamic(col, value)
|
197
|
-
case value
|
198
|
-
when String, TrueClass, FalseClass
|
199
|
-
compare(col, value.to_s, :eq)
|
200
|
-
when Numeric, NilClass
|
201
|
-
compare(col, value, :eq)
|
202
|
-
when Hash
|
203
|
-
if has_operator?(value)
|
204
|
-
chain(:and, value.map {|op, val|
|
205
|
-
case op
|
206
|
-
when "$in"
|
207
|
-
if val.all? {|v| v.is_a? Numeric }
|
208
|
-
wrap(col, val.first).in(val)
|
209
|
-
else
|
210
|
-
col.in(val.map(&:to_s))
|
211
|
-
end
|
212
|
-
when "$eq", "$ne", "$gt", "$gte", "$lt", "$lte"
|
213
|
-
compare(col, val, OPERATOR_MAP[op])
|
214
|
-
else
|
215
|
-
raise UnsupportedQuery, "Unknown operator #{op}"
|
216
|
-
end
|
217
|
-
})
|
218
|
-
else
|
219
|
-
col.eq(value.to_json)
|
220
|
-
end
|
221
|
-
else
|
222
|
-
col.eq(value.to_json)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
207
|
def translate_value_schema(column, col, value)
|
227
208
|
type = schema.column_type(column.to_s)
|
228
209
|
case value
|
@@ -237,8 +218,10 @@ module Mongery
|
|
237
218
|
else
|
238
219
|
compare_schema(col, val, type, :in)
|
239
220
|
end
|
221
|
+
when *(custom_operators.keys)
|
222
|
+
compare_schema(col, val, type, custom_operators[op])
|
240
223
|
when "$eq", "$ne", "$gt", "$gte", "$lt", "$lte"
|
241
|
-
|
224
|
+
compare_schema(col, val, type, OPERATOR_MAP[op])
|
242
225
|
else
|
243
226
|
raise UnsupportedQuery, "Unknown operator #{op}"
|
244
227
|
end
|
@@ -269,6 +252,8 @@ module Mongery
|
|
269
252
|
else
|
270
253
|
col.in(val.map(&:to_s))
|
271
254
|
end
|
255
|
+
when *(custom_operators.keys)
|
256
|
+
compare(col, val, custom_operators[op])
|
272
257
|
when "$eq", "$ne", "$gt", "$gte", "$lt", "$lte"
|
273
258
|
compare(col, val, OPERATOR_MAP[op])
|
274
259
|
else
|
@@ -288,7 +273,7 @@ module Mongery
|
|
288
273
|
end
|
289
274
|
|
290
275
|
def compare(col, val, op)
|
291
|
-
wrap(col, val)
|
276
|
+
operator(wrap(col, val), op, val)
|
292
277
|
end
|
293
278
|
|
294
279
|
def wrap(col, val)
|
@@ -312,19 +297,28 @@ module Mongery
|
|
312
297
|
def compare_schema(col, val, type, op)
|
313
298
|
case type
|
314
299
|
when "string"
|
315
|
-
Arel.sql("(#{col})")
|
300
|
+
operator(Arel.sql("(#{col})"), op, val)
|
316
301
|
when "number", "integer"
|
317
|
-
Arel.sql("(#{col})::numeric")
|
302
|
+
operator(Arel.sql("(#{col})::numeric"), op, val)
|
318
303
|
else
|
319
304
|
case val
|
320
305
|
when Numeric
|
321
|
-
Arel.sql("(#{col})")
|
306
|
+
operator(Arel.sql("(#{col})"), op, val.to_s)
|
322
307
|
else
|
323
|
-
Arel.sql("(#{col})")
|
308
|
+
operator(Arel.sql("(#{col})"), op, val)
|
324
309
|
end
|
325
310
|
end
|
326
311
|
end
|
327
312
|
|
313
|
+
def operator(col, op, val)
|
314
|
+
case op
|
315
|
+
when Symbol
|
316
|
+
col.send(op, val)
|
317
|
+
else
|
318
|
+
op.call(col, val)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
328
322
|
def sql_json_path(col)
|
329
323
|
paths = col.to_s.split('.')
|
330
324
|
Arel.sql("data#>>#{json_pathize(paths)}")
|
data/lib/mongery/version.rb
CHANGED
@@ -23,6 +23,10 @@ describe Mongery::Builder do
|
|
23
23
|
/WHERE \(data#>>'{height}'\) IN \('6\.1', '6\.2'\)$/ ],
|
24
24
|
[ { height: nil },
|
25
25
|
/WHERE \(data#>>'{height}'\) IS NULL$/ ],
|
26
|
+
[ { name: { "$as" => "miyagawa" } },
|
27
|
+
/WHERE \(data#>>'{name}'\) = 'miyagawa'$/ ],
|
28
|
+
[ { name: { "$land" => "foo" } },
|
29
|
+
/WHERE \(data#>>'{name}'\) && 'foo'$/ ],
|
26
30
|
]
|
27
31
|
|
28
32
|
schema = JsonSchema.parse!(JSON.parse(<<-EOF))
|
@@ -49,6 +53,12 @@ describe Mongery::Builder do
|
|
49
53
|
EOF
|
50
54
|
|
51
55
|
builder = Mongery::Builder.new(:test, ActiveRecord::Base, schema)
|
56
|
+
builder.custom_operators = {
|
57
|
+
"$as" => :eq,
|
58
|
+
"$land" => ->(col, val) {
|
59
|
+
Arel::Nodes::InfixOperation.new("&&", col, val)
|
60
|
+
}
|
61
|
+
}
|
52
62
|
|
53
63
|
queries.each do |query, sql|
|
54
64
|
context "with query #{query}" do
|
@@ -70,6 +70,10 @@ describe Mongery::Builder do
|
|
70
70
|
/WHERE data#>>'{bar}' = '{"foo":"bar","baz":\[1,2,3\]}'$/ ],
|
71
71
|
[ { "foo.bar" => true }, { },
|
72
72
|
/WHERE data#>>'{foo,bar}' = 'true'$/ ],
|
73
|
+
[ { bar: {"$as" => 1} }, { },
|
74
|
+
/WHERE \(data#>>'{bar}'\)::numeric = 1$/ ],
|
75
|
+
[ { bar: {"$land" => 'foo'} }, { },
|
76
|
+
/WHERE data#>>'{bar}' && 'foo'$/ ],
|
73
77
|
]
|
74
78
|
|
75
79
|
bad_queries = [
|
@@ -80,6 +84,12 @@ describe Mongery::Builder do
|
|
80
84
|
]
|
81
85
|
|
82
86
|
builder = Mongery::Builder.new(:test)
|
87
|
+
builder.custom_operators = {
|
88
|
+
"$as" => :eq,
|
89
|
+
"$land" => ->(col, val) {
|
90
|
+
Arel::Nodes::InfixOperation.new("&&", col, val)
|
91
|
+
}
|
92
|
+
}
|
83
93
|
|
84
94
|
queries.each do |query, condition, sql|
|
85
95
|
context "with query #{query}" do
|
@@ -4,6 +4,12 @@ describe "#mapped_properties" do
|
|
4
4
|
let(:builder) {
|
5
5
|
Mongery::Builder.new(:test).tap do |builder|
|
6
6
|
builder.mapped_properties = [:user_id, :created_at, :updated_at]
|
7
|
+
builder.custom_operators = {
|
8
|
+
"$as" => :eq,
|
9
|
+
"$land" => ->(col, val) {
|
10
|
+
Arel::Nodes::InfixOperation.new("&&", col, val)
|
11
|
+
}
|
12
|
+
}
|
7
13
|
end
|
8
14
|
}
|
9
15
|
|
@@ -31,4 +37,14 @@ describe "#mapped_properties" do
|
|
31
37
|
expect(builder.find("created_at" => {'$in' => ['2014-01-01', '2015-01-01']}, "foo" => "bar").to_sql)
|
32
38
|
.to match /WHERE "test"\."created_at" IN \('2014-01-01', '2015-01-01'\) AND data#>>'{foo}' = 'bar'/;
|
33
39
|
end
|
40
|
+
|
41
|
+
it 'does custom operators' do
|
42
|
+
expect(builder.find(user_id: { "$as" => 2 }).to_sql)
|
43
|
+
.to match /WHERE "test"\."user_id" = 2/;
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'does custom operators with proc' do
|
47
|
+
expect(builder.find(user_id: { "$land" => 'foo' }).to_sql)
|
48
|
+
.to match /WHERE "test"\."user_id" && 'foo'/;
|
49
|
+
end
|
34
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tatsuhiko Miyagawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: arel
|