mongery 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|