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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3aeb64347aabfea21e8a23c2160e10256404f948
4
- data.tar.gz: 60d53661a827f430c4dfe6bd34466deab7b1168f
3
+ metadata.gz: fe6385d3fabb1f17ebd5637f248fab8b776d7718
4
+ data.tar.gz: 1acfe3b40ce8de1d187fa43b7ad4277cc6cf534e
5
5
  SHA512:
6
- metadata.gz: 6e3a644c5a6c6409c2923f7c1a228fd5f287011f94134b460b4adcff86076fecc4ce990fd0d38e04263b61e6166627f739dbb73c558af6018371677eef40c858
7
- data.tar.gz: 2112b7028f0c874bc3e8024d668ae0b254e34116ca1464b8fe4fecc09c8ac5fd6ae33e61e3ef9f874218391f019fd328b7eae02f2321608b28cfeb24d1fa47c3
6
+ metadata.gz: 21a99f928bd828a80391a10d90a0db8c8bd2401cebc8538df8d5d309fddd5d4bddd96c870bb3c99a1464a59889c786887aad59536f67bbf042c96f6bcf47bde6
7
+ data.tar.gz: bb095b44a1482056496e3a209169f27f3d6c255f621717d065a9be4132cd060281723f8f390dd1368420010d32ca6fb5c049d1f6fd1681fdd53c22a9a8e6ead9
@@ -1,3 +1,6 @@
1
+ ## 1.0.4 (2015/01/19)
2
+ - Support custom operators
3
+
1
4
  ## 1.0.3 (2015/01/09)
2
5
  - Support index method to create expression indexes
3
6
 
@@ -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
- Query.new(table, schema, mapped_properties).where(*args)
28
+ build_query.where(*args)
27
29
  end
28
30
 
29
31
  def insert(*args)
30
- Query.new(table, schema, mapped_properties).insert(*args)
32
+ build_query.insert(*args)
31
33
  end
32
34
 
33
35
  def index(*args)
34
- Query.new(table, schema, mapped_properties).index(*args)
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 OPERATOR_MAP.key?(op)
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
- compare_schema(col, val, type, OPERATOR_MAP[op])
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).send(op, 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})").send(op, val)
300
+ operator(Arel.sql("(#{col})"), op, val)
316
301
  when "number", "integer"
317
- Arel.sql("(#{col})::numeric").send(op, val)
302
+ operator(Arel.sql("(#{col})::numeric"), op, val)
318
303
  else
319
304
  case val
320
305
  when Numeric
321
- Arel.sql("(#{col})").send(op, val.to_s)
306
+ operator(Arel.sql("(#{col})"), op, val.to_s)
322
307
  else
323
- Arel.sql("(#{col})").send(op, val)
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)}")
@@ -1,3 +1,3 @@
1
1
  module Mongery
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -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.3
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-09 00:00:00.000000000 Z
11
+ date: 2015-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: arel