mongory 0.6.0 → 0.6.1
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 +7 -0
- data/lib/mongory/converters/condition_converter.rb +5 -18
- data/lib/mongory/converters/converted.rb +81 -0
- data/lib/mongory/converters/value_converter.rb +2 -2
- data/lib/mongory/converters.rb +1 -0
- data/lib/mongory/matchers/hash_condition_matcher.rb +6 -0
- data/lib/mongory/matchers/in_matcher.rb +8 -3
- data/lib/mongory/matchers/nin_matcher.rb +8 -3
- data/lib/mongory/matchers/size_matcher.rb +50 -0
- data/lib/mongory/matchers.rb +1 -0
- data/lib/mongory/query_builder.rb +1 -1
- data/lib/mongory/query_matcher.rb +1 -1
- data/lib/mongory/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2e272e3c249c11059ecf96ad8eb0659d5e0fb0157050e7d69b6e272e16f874a
|
4
|
+
data.tar.gz: 84316343470d975672edbed9e590661bf555af5aa6ceb862d4e850efac0f5266
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0709d9abd1a769c111cc27b73a25f1d79b2af931de122fad4538259b97eccd5a8bb26336fab68d8affbba830ffa9a8af3bf07323f17051f588c633938a43b75
|
7
|
+
data.tar.gz: 292d65f888d36af1d22a9e4d7973ee8995c055c37abc837b1fdca161f5d4b37ed285c253da7a6019172848cb89d35e76e5ce0fa7b88725272ecdc46718d23968
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
# Changelog
|
2
|
+
## [0.6.1] - 2025-04-24
|
3
|
+
|
4
|
+
### Major Changes
|
5
|
+
- Add size matcher
|
6
|
+
- $in and $nin supports range condition
|
7
|
+
- Query matcher inherits from Hash condition matcher to accept hash condition only
|
8
|
+
- Introduced Converted to mark converted data and prevent double convert
|
2
9
|
|
3
10
|
## [0.6.0] - 2025-04-23
|
4
11
|
|
@@ -21,28 +21,16 @@ module Mongory
|
|
21
21
|
# @param condition [Hash] the flat condition hash to convert
|
22
22
|
# @return [Hash] the transformed nested condition
|
23
23
|
def convert(condition)
|
24
|
-
|
24
|
+
return condition if condition.is_a?(Converted)
|
25
|
+
|
26
|
+
result = Converted::Hash.new
|
25
27
|
condition.each_pair do |k, v|
|
26
28
|
converted_value = value_converter.convert(v)
|
27
29
|
converted_pair = key_converter.convert(k, converted_value)
|
28
|
-
result.
|
30
|
+
result.deep_merge!(converted_pair)
|
29
31
|
end
|
30
|
-
result
|
31
|
-
end
|
32
32
|
|
33
|
-
|
34
|
-
# When both values are hashes, recursively merges them.
|
35
|
-
# Otherwise, uses the second value.
|
36
|
-
#
|
37
|
-
# @return [Proc] a block for deep merging hash values
|
38
|
-
def deep_merge_block
|
39
|
-
@deep_merge_block ||= Proc.new do |_, a, b|
|
40
|
-
if a.is_a?(Hash) && b.is_a?(Hash)
|
41
|
-
a.merge(b, &deep_merge_block)
|
42
|
-
else
|
43
|
-
b
|
44
|
-
end
|
45
|
-
end
|
33
|
+
result
|
46
34
|
end
|
47
35
|
|
48
36
|
# @note Singleton instance, not configurable after initialization
|
@@ -65,7 +53,6 @@ module Mongory
|
|
65
53
|
#
|
66
54
|
# @return [void]
|
67
55
|
def freeze
|
68
|
-
deep_merge_block
|
69
56
|
super
|
70
57
|
key_converter.freeze
|
71
58
|
value_converter.freeze
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongory
|
4
|
+
module Converters
|
5
|
+
# Converted is a module that provides conversion structures marked as
|
6
|
+
# Converted. It is used to convert various types of data into a
|
7
|
+
# standardized form for MongoDB queries. The module includes
|
8
|
+
# classes for converting hashes and arrays into nested structures.
|
9
|
+
# It is used internally by the ConditionConverter and ValueConverter
|
10
|
+
# to handle the conversion of complex data types into a format
|
11
|
+
# suitable for MongoDB queries.
|
12
|
+
module Converted
|
13
|
+
def instance_convert(other)
|
14
|
+
return other if other.is_a?(Converted)
|
15
|
+
|
16
|
+
case other
|
17
|
+
when Hash
|
18
|
+
Converted::Hash.new(other)
|
19
|
+
when Array
|
20
|
+
Converted::Array.new(other)
|
21
|
+
else
|
22
|
+
other
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Converts a flat condition hash into a nested structure.
|
27
|
+
# Applies value conversion to each element.
|
28
|
+
# This is used for conditions that are hashes of values.
|
29
|
+
# It is used internally by the ConditionConverter and ValueConverter
|
30
|
+
# to handle the conversion of complex data types into a format
|
31
|
+
# suitable for MongoDB queries.
|
32
|
+
class Hash < ::Hash
|
33
|
+
include Converted
|
34
|
+
|
35
|
+
def initialize(other = {})
|
36
|
+
super()
|
37
|
+
other.each_pair do |k, v|
|
38
|
+
self[k] = instance_convert(v)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def deep_merge(other)
|
43
|
+
dup.deep_merge!(Hash.new(other))
|
44
|
+
end
|
45
|
+
|
46
|
+
def deep_merge!(other)
|
47
|
+
_deep_merge!(self, Hash.new(other))
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def _deep_merge!(left, right)
|
53
|
+
left.merge!(right) do |_, a, b|
|
54
|
+
if a.is_a?(::Hash) && b.is_a?(::Hash)
|
55
|
+
_deep_merge!(a.dup, b)
|
56
|
+
else
|
57
|
+
b
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Converts a flat condition array into a nested structure.
|
64
|
+
# Applies value conversion to each element.
|
65
|
+
# This is used for conditions that are arrays of values.
|
66
|
+
# It is used internally by the ConditionConverter and ValueConverter
|
67
|
+
# to handle the conversion of complex data types into a format
|
68
|
+
# suitable for MongoDB queries.
|
69
|
+
class Array < ::Array
|
70
|
+
include Converted
|
71
|
+
|
72
|
+
def initialize(other)
|
73
|
+
super()
|
74
|
+
other.each do |v|
|
75
|
+
self << instance_convert(v)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -26,10 +26,10 @@ module Mongory
|
|
26
26
|
# @return [Object] the converted value
|
27
27
|
def convert(target)
|
28
28
|
case target
|
29
|
-
when String, Integer, Regexp
|
29
|
+
when String, Integer, Regexp, Converted
|
30
30
|
target
|
31
31
|
when Array
|
32
|
-
target.map { |x| convert(x) }
|
32
|
+
Converted::Array.new(target.map { |x| convert(x) })
|
33
33
|
when Hash
|
34
34
|
condition_converter.convert(target)
|
35
35
|
else
|
data/lib/mongory/converters.rb
CHANGED
@@ -33,6 +33,8 @@ module Mongory
|
|
33
33
|
|
34
34
|
Proc.new do |record|
|
35
35
|
if record.is_a?(Array)
|
36
|
+
return false if condition.is_a?(Range)
|
37
|
+
|
36
38
|
is_present?(condition & record)
|
37
39
|
else
|
38
40
|
condition.include?(record)
|
@@ -40,12 +42,15 @@ module Mongory
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
# Ensures the condition is an array.
|
45
|
+
# Ensures the condition is an array or range.
|
44
46
|
#
|
45
|
-
# @raise [TypeError] if condition is not an array
|
47
|
+
# @raise [TypeError] if condition is not an array nor a range
|
46
48
|
# @return [void]
|
47
49
|
def check_validity!
|
48
|
-
|
50
|
+
return if @condition.is_a?(Array)
|
51
|
+
return if @condition.is_a?(Range)
|
52
|
+
|
53
|
+
raise TypeError, '$in needs an array or range'
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -33,6 +33,8 @@ module Mongory
|
|
33
33
|
|
34
34
|
Proc.new do |record|
|
35
35
|
if record.is_a?(Array)
|
36
|
+
return true if condition.is_a?(Range)
|
37
|
+
|
36
38
|
is_blank?(condition & record)
|
37
39
|
else
|
38
40
|
!condition.include?(record)
|
@@ -40,12 +42,15 @@ module Mongory
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
# Ensures the condition is a valid array.
|
45
|
+
# Ensures the condition is a valid array or range.
|
44
46
|
#
|
45
|
-
# @raise [TypeError] if the condition is not an array
|
47
|
+
# @raise [TypeError] if the condition is not an array nor a range
|
46
48
|
# @return [void]
|
47
49
|
def check_validity!
|
48
|
-
|
50
|
+
return if @condition.is_a?(Array)
|
51
|
+
return if @condition.is_a?(Range)
|
52
|
+
|
53
|
+
raise TypeError, '$nin needs an array'
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongory
|
4
|
+
module Matchers
|
5
|
+
# Matcher for the `$size` operator.
|
6
|
+
#
|
7
|
+
# This matcher expects the input to be an array, and delegates the comparison
|
8
|
+
# to a literal matcher using the array's size as the value.
|
9
|
+
#
|
10
|
+
# For example, the condition `{ tags: { '$size' => 3 } }` will match any
|
11
|
+
# document where `tags` is an array of length 3.
|
12
|
+
#
|
13
|
+
# ### Supported compound usages:
|
14
|
+
#
|
15
|
+
# ```ruby
|
16
|
+
# Mongory.where(tags: { '$size' => 3 }) # exactly 3 elements
|
17
|
+
# Mongory.where(tags: { '$size' => { '$gt' => 1 } }) # more than 1
|
18
|
+
# Mongory.where(comments: { '$size' => { '$gt' => 1, '$lte' => 5 } }) # more than 1, up to 5 elements
|
19
|
+
# Mongory.where(tags: { '$size' => { '$in' => [1, 2, 3] } }) # 1, 2, or 3 elements
|
20
|
+
# ```
|
21
|
+
#
|
22
|
+
# @see LiteralMatcher
|
23
|
+
#
|
24
|
+
# @note Ruby's Symbol class already defines a `#size` method,
|
25
|
+
# that will return the size of the symbol object.
|
26
|
+
# So, this is the only operator that cannot be used with
|
27
|
+
# the symbol snippet syntax (e.g. `:tags.size`).
|
28
|
+
#
|
29
|
+
# Use string key syntax instead: `:"tags.$size" => ...`
|
30
|
+
class SizeMatcher < LiteralMatcher
|
31
|
+
# Creates a raw Proc that performs the size matching operation.
|
32
|
+
#
|
33
|
+
# The returned Proc checks if the input is an Array. If so, it calculates
|
34
|
+
# the array's size and passes it to the wrapped literal matcher Proc.
|
35
|
+
#
|
36
|
+
# @return [Proc] A proc that performs size-based matching
|
37
|
+
def raw_proc
|
38
|
+
super_proc = super
|
39
|
+
|
40
|
+
Proc.new do |record|
|
41
|
+
next false unless record.is_a?(Array)
|
42
|
+
|
43
|
+
super_proc.call(record.size)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
register(:size, '$size', SizeMatcher)
|
49
|
+
end
|
50
|
+
end
|
data/lib/mongory/matchers.rb
CHANGED
@@ -228,7 +228,7 @@ module Mongory
|
|
228
228
|
# @param conditions [Array<Hash>] the conditions to add
|
229
229
|
# @return [void]
|
230
230
|
def add_conditions(key, conditions)
|
231
|
-
condition_dup = @matcher.condition
|
231
|
+
condition_dup = {}.merge!(@matcher.condition)
|
232
232
|
condition_dup[key] ||= []
|
233
233
|
condition_dup[key] += conditions
|
234
234
|
set_matcher(condition_dup)
|
@@ -28,7 +28,7 @@ module Mongory
|
|
28
28
|
#
|
29
29
|
# @see Matchers::LiteralMatcher
|
30
30
|
# @see Converters::ConditionConverter
|
31
|
-
class QueryMatcher < Matchers::
|
31
|
+
class QueryMatcher < Matchers::HashConditionMatcher
|
32
32
|
# Initializes a new query matcher with the given condition.
|
33
33
|
# The condition is converted using Mongory.condition_converter
|
34
34
|
# before being passed to the parent matcher.
|
data/lib/mongory/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- koten0224
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A Mongo-like in-memory query DSL for Ruby
|
14
14
|
email:
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- lib/mongory/converters.rb
|
38
38
|
- lib/mongory/converters/abstract_converter.rb
|
39
39
|
- lib/mongory/converters/condition_converter.rb
|
40
|
+
- lib/mongory/converters/converted.rb
|
40
41
|
- lib/mongory/converters/data_converter.rb
|
41
42
|
- lib/mongory/converters/key_converter.rb
|
42
43
|
- lib/mongory/converters/value_converter.rb
|
@@ -63,6 +64,7 @@ files:
|
|
63
64
|
- lib/mongory/matchers/or_matcher.rb
|
64
65
|
- lib/mongory/matchers/present_matcher.rb
|
65
66
|
- lib/mongory/matchers/regex_matcher.rb
|
67
|
+
- lib/mongory/matchers/size_matcher.rb
|
66
68
|
- lib/mongory/mongoid.rb
|
67
69
|
- lib/mongory/query_builder.rb
|
68
70
|
- lib/mongory/query_matcher.rb
|