mongory 0.6.2 → 0.6.3
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/lib/mongory/converters/converted.rb +2 -2
- data/lib/mongory/matchers/abstract_matcher.rb +4 -0
- data/lib/mongory/matchers/abstract_multi_matcher.rb +44 -0
- data/lib/mongory/matchers/and_matcher.rb +2 -23
- data/lib/mongory/matchers/array_record_matcher.rb +2 -23
- data/lib/mongory/matchers/elem_match_matcher.rb +4 -0
- data/lib/mongory/matchers/eq_matcher.rb +4 -0
- data/lib/mongory/matchers/every_matcher.rb +4 -0
- data/lib/mongory/matchers/exists_matcher.rb +4 -0
- data/lib/mongory/matchers/field_matcher.rb +4 -0
- data/lib/mongory/matchers/gt_matcher.rb +4 -0
- data/lib/mongory/matchers/gte_matcher.rb +4 -0
- data/lib/mongory/matchers/hash_condition_matcher.rb +2 -23
- data/lib/mongory/matchers/in_matcher.rb +13 -4
- data/lib/mongory/matchers/literal_matcher.rb +4 -0
- data/lib/mongory/matchers/lt_matcher.rb +4 -0
- data/lib/mongory/matchers/lte_matcher.rb +4 -0
- data/lib/mongory/matchers/ne_matcher.rb +4 -0
- data/lib/mongory/matchers/nin_matcher.rb +14 -5
- data/lib/mongory/matchers/not_matcher.rb +4 -0
- data/lib/mongory/matchers/or_matcher.rb +2 -23
- data/lib/mongory/matchers/present_matcher.rb +4 -0
- data/lib/mongory/matchers/regex_matcher.rb +4 -0
- data/lib/mongory/matchers/size_matcher.rb +4 -0
- data/lib/mongory/utils.rb +1 -1
- data/lib/mongory/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78a3d73e3c078b41aeeeb727445229e4edce85ff089de2d7412c9e64bfc613c0
|
4
|
+
data.tar.gz: d7a9191a78a75b00f7a3ef7aa5d0b8e5ed8e8cb53e6a839e0873548da341849f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cc1387d67ccf0559a5f12d2140b2f0349a16b8461ae3e6992a3ba199a1824b178236d91cd8fe31bdbd73a85d056074efac32440ef8827bb31e9aebb6fd544bf
|
7
|
+
data.tar.gz: 8f34cab007b5c692b48634686aa2931036b3f928da72004512b7e0de744dbe009656cac108f9f2d6d3d59b8d6d7e997b1b1b3f3a5865998bc83168c2dce60ea0
|
@@ -75,6 +75,50 @@ module Mongory
|
|
75
75
|
matcher.render_tree(new_prefix, is_last: index == last_index)
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
def priority
|
80
|
+
1 + matchers.sum(&:priority)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Recursively combines multiple matcher procs with AND logic.
|
86
|
+
# This method optimizes the combination of multiple matchers by building
|
87
|
+
# a balanced tree of AND operations.
|
88
|
+
#
|
89
|
+
# @param left [Proc] The left matcher proc to combine
|
90
|
+
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
91
|
+
# @return [Proc] A new proc that combines all matchers with AND logic
|
92
|
+
# @example
|
93
|
+
# combine_procs_with_and(proc1, proc2, proc3)
|
94
|
+
# #=> proc { |record| proc1.call(record) && proc2.call(record) && proc3.call(record) }
|
95
|
+
def combine_procs_with_and(left = TRUE_PROC, *rest)
|
96
|
+
return left if rest.empty?
|
97
|
+
|
98
|
+
right = combine_procs_with_and(*rest)
|
99
|
+
Proc.new do |record|
|
100
|
+
left.call(record) && right.call(record)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Recursively combines multiple matcher procs with OR logic.
|
105
|
+
# This method optimizes the combination of multiple matchers by building
|
106
|
+
# a balanced tree of OR operations.
|
107
|
+
#
|
108
|
+
# @param left [Proc] The left matcher proc to combine
|
109
|
+
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
110
|
+
# @return [Proc] A new proc that combines all matchers with OR logic
|
111
|
+
# @example
|
112
|
+
# combine_procs_with_or(proc1, proc2, proc3)
|
113
|
+
# #=> proc { |record| proc1.call(record) || proc2.call(record) || proc3.call(record) }
|
114
|
+
def combine_procs_with_or(left = FALSE_PROC, *rest)
|
115
|
+
return left if rest.empty?
|
116
|
+
|
117
|
+
right = combine_procs_with_or(*rest)
|
118
|
+
Proc.new do |record|
|
119
|
+
left.call(record) || right.call(record)
|
120
|
+
end
|
121
|
+
end
|
78
122
|
end
|
79
123
|
end
|
80
124
|
end
|
@@ -36,28 +36,7 @@ module Mongory
|
|
36
36
|
#
|
37
37
|
# @return [Proc] a Proc that performs the AND operation
|
38
38
|
def raw_proc
|
39
|
-
|
40
|
-
|
41
|
-
combine_procs(*matchers.map(&:to_proc))
|
42
|
-
end
|
43
|
-
|
44
|
-
# Recursively combines multiple matcher procs with AND logic.
|
45
|
-
# This method optimizes the combination of multiple matchers by building
|
46
|
-
# a balanced tree of AND operations.
|
47
|
-
#
|
48
|
-
# @param left [Proc] The left matcher proc to combine
|
49
|
-
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
50
|
-
# @return [Proc] A new proc that combines all matchers with AND logic
|
51
|
-
# @example
|
52
|
-
# combine_procs(proc1, proc2, proc3)
|
53
|
-
# #=> proc { |record| proc1.call(record) && proc2.call(record) && proc3.call(record) }
|
54
|
-
def combine_procs(left, *rest)
|
55
|
-
return left if rest.empty?
|
56
|
-
|
57
|
-
right = combine_procs(*rest)
|
58
|
-
Proc.new do |record|
|
59
|
-
left.call(record) && right.call(record)
|
60
|
-
end
|
39
|
+
combine_procs_with_and(*matchers.map(&:to_proc))
|
61
40
|
end
|
62
41
|
|
63
42
|
# Returns the flattened list of all matchers from each subcondition.
|
@@ -70,7 +49,7 @@ module Mongory
|
|
70
49
|
define_instance_cache_method(:matchers) do
|
71
50
|
@condition.flat_map do |condition|
|
72
51
|
HashConditionMatcher.new(condition, context: @context).matchers
|
73
|
-
end.uniq(&:uniq_key)
|
52
|
+
end.uniq(&:uniq_key).sort_by(&:priority)
|
74
53
|
end
|
75
54
|
|
76
55
|
# Ensures the condition is an array of hashes.
|
@@ -34,28 +34,7 @@ module Mongory
|
|
34
34
|
#
|
35
35
|
# @return [Proc] a Proc that performs the array matching operation
|
36
36
|
def raw_proc
|
37
|
-
|
38
|
-
|
39
|
-
combine_procs(*matchers.map(&:to_proc))
|
40
|
-
end
|
41
|
-
|
42
|
-
# Recursively combines multiple matcher procs with OR logic.
|
43
|
-
# This method optimizes the combination of multiple matchers by building
|
44
|
-
# a balanced tree of OR operations.
|
45
|
-
#
|
46
|
-
# @param left [Proc] The left matcher proc to combine
|
47
|
-
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
48
|
-
# @return [Proc] A new proc that combines all matchers with OR logic
|
49
|
-
# @example
|
50
|
-
# combine_procs(proc1, proc2, proc3)
|
51
|
-
# #=> proc { |record| proc1.call(record) || proc2.call(record) || proc3.call(record) }
|
52
|
-
def combine_procs(left, *rest)
|
53
|
-
return left if rest.empty?
|
54
|
-
|
55
|
-
right = combine_procs(*rest)
|
56
|
-
Proc.new do |record|
|
57
|
-
left.call(record) || right.call(record)
|
58
|
-
end
|
37
|
+
combine_procs_with_or(*matchers.map(&:to_proc))
|
59
38
|
end
|
60
39
|
|
61
40
|
# Builds an array of matchers to evaluate the given condition against an array record.
|
@@ -77,7 +56,7 @@ module Mongory
|
|
77
56
|
else
|
78
57
|
ElemMatchMatcher.build({ '$eq' => @condition }, context: @context)
|
79
58
|
end
|
80
|
-
result
|
59
|
+
result.sort_by(&:priority)
|
81
60
|
end
|
82
61
|
|
83
62
|
private
|
@@ -32,28 +32,7 @@ module Mongory
|
|
32
32
|
#
|
33
33
|
# @return [Proc] a Proc that performs the hash condition matching operation
|
34
34
|
def raw_proc
|
35
|
-
|
36
|
-
|
37
|
-
combine_procs(*matchers.map(&:to_proc))
|
38
|
-
end
|
39
|
-
|
40
|
-
# Recursively combines multiple matcher procs with AND logic.
|
41
|
-
# This method optimizes the combination of multiple matchers by building
|
42
|
-
# a balanced tree of AND operations.
|
43
|
-
#
|
44
|
-
# @param left [Proc] The left matcher proc to combine
|
45
|
-
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
46
|
-
# @return [Proc] A new proc that combines all matchers with AND logic
|
47
|
-
# @example
|
48
|
-
# combine_procs(proc1, proc2, proc3)
|
49
|
-
# #=> proc { |record| proc1.call(record) && proc2.call(record) && proc3.call(record) }
|
50
|
-
def combine_procs(left, *rest)
|
51
|
-
return left if rest.empty?
|
52
|
-
|
53
|
-
right = combine_procs(*rest)
|
54
|
-
Proc.new do |record|
|
55
|
-
left.call(record) && right.call(record)
|
56
|
-
end
|
35
|
+
combine_procs_with_and(*matchers.map(&:to_proc))
|
57
36
|
end
|
58
37
|
|
59
38
|
# Returns the list of matchers for each key-value pair in the condition.
|
@@ -70,7 +49,7 @@ module Mongory
|
|
70
49
|
else
|
71
50
|
FieldMatcher.build(key, value, context: @context)
|
72
51
|
end
|
73
|
-
end
|
52
|
+
end.sort_by(&:priority)
|
74
53
|
end
|
75
54
|
|
76
55
|
def check_validity!
|
@@ -24,17 +24,23 @@ module Mongory
|
|
24
24
|
#
|
25
25
|
# @see AbstractMatcher
|
26
26
|
class InMatcher < AbstractMatcher
|
27
|
+
def self.build(condition, *args)
|
28
|
+
return super unless condition.is_a?(Range)
|
29
|
+
|
30
|
+
end_op = condition.exclude_end? ? '$lt' : '$lte'
|
31
|
+
head, tail = [condition.first, condition.last].sort
|
32
|
+
AndMatcher.build([{ '$gte' => head }, { end_op => tail }], *args)
|
33
|
+
end
|
34
|
+
|
27
35
|
# Creates a raw Proc that performs the in-matching operation.
|
28
36
|
# The Proc checks if any element of the record is in the condition array.
|
29
37
|
#
|
30
38
|
# @return [Proc] a Proc that performs the in-matching operation
|
31
39
|
def raw_proc
|
32
|
-
condition = @condition
|
40
|
+
condition = Set.new(@condition)
|
33
41
|
|
34
42
|
Proc.new do |record|
|
35
43
|
if record.is_a?(Array)
|
36
|
-
return false if condition.is_a?(Range)
|
37
|
-
|
38
44
|
is_present?(condition & record)
|
39
45
|
else
|
40
46
|
condition.include?(record)
|
@@ -42,13 +48,16 @@ module Mongory
|
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
51
|
+
def priority
|
52
|
+
1 + Math.log(@condition.size + 1, 1.5)
|
53
|
+
end
|
54
|
+
|
45
55
|
# Ensures the condition is an array or range.
|
46
56
|
#
|
47
57
|
# @raise [TypeError] if condition is not an array nor a range
|
48
58
|
# @return [void]
|
49
59
|
def check_validity!
|
50
60
|
return if @condition.is_a?(Array)
|
51
|
-
return if @condition.is_a?(Range)
|
52
61
|
|
53
62
|
raise TypeError, '$in needs an array or range'
|
54
63
|
end
|
@@ -48,6 +48,10 @@ module Mongory
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
def priority
|
52
|
+
1 + dispatched_matcher.priority
|
53
|
+
end
|
54
|
+
|
51
55
|
# Selects and returns the appropriate matcher instance for a given literal condition.
|
52
56
|
#
|
53
57
|
# This method analyzes the type of the raw condition (e.g., Hash, Regexp, nil)
|
@@ -24,17 +24,23 @@ module Mongory
|
|
24
24
|
#
|
25
25
|
# @see AbstractMatcher
|
26
26
|
class NinMatcher < AbstractMatcher
|
27
|
+
def self.build(condition, *args)
|
28
|
+
return super unless condition.is_a?(Range)
|
29
|
+
|
30
|
+
end_op = condition.exclude_end? ? '$gte' : '$gt'
|
31
|
+
head, tail = [condition.first, condition.last].sort
|
32
|
+
OrMatcher.build([{ '$lt' => head }, { end_op => tail }], *args)
|
33
|
+
end
|
34
|
+
|
27
35
|
# Creates a raw Proc that performs the not-in matching operation.
|
28
36
|
# The Proc checks if the record has no elements in common with the condition array.
|
29
37
|
#
|
30
38
|
# @return [Proc] A proc that performs not-in matching
|
31
39
|
def raw_proc
|
32
|
-
condition = @condition
|
40
|
+
condition = Set.new(@condition)
|
33
41
|
|
34
42
|
Proc.new do |record|
|
35
43
|
if record.is_a?(Array)
|
36
|
-
return true if condition.is_a?(Range)
|
37
|
-
|
38
44
|
is_blank?(condition & record)
|
39
45
|
else
|
40
46
|
!condition.include?(record)
|
@@ -42,15 +48,18 @@ module Mongory
|
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
51
|
+
def priority
|
52
|
+
1 + Math.log(@condition.size + 1, 1.5)
|
53
|
+
end
|
54
|
+
|
45
55
|
# Ensures the condition is a valid array or range.
|
46
56
|
#
|
47
57
|
# @raise [TypeError] if the condition is not an array nor a range
|
48
58
|
# @return [void]
|
49
59
|
def check_validity!
|
50
60
|
return if @condition.is_a?(Array)
|
51
|
-
return if @condition.is_a?(Range)
|
52
61
|
|
53
|
-
raise TypeError, '$nin needs an array'
|
62
|
+
raise TypeError, '$nin needs an array or range'
|
54
63
|
end
|
55
64
|
end
|
56
65
|
|
@@ -35,28 +35,7 @@ module Mongory
|
|
35
35
|
#
|
36
36
|
# @return [Proc] a Proc that performs the or-matching operation
|
37
37
|
def raw_proc
|
38
|
-
|
39
|
-
|
40
|
-
combine_procs(*matchers.map(&:to_proc))
|
41
|
-
end
|
42
|
-
|
43
|
-
# Recursively combines multiple matcher procs with OR logic.
|
44
|
-
# This method optimizes the combination of multiple matchers by building
|
45
|
-
# a balanced tree of OR operations.
|
46
|
-
#
|
47
|
-
# @param left [Proc] The left matcher proc to combine
|
48
|
-
# @param rest [Array<Proc>] The remaining matcher procs to combine
|
49
|
-
# @return [Proc] A new proc that combines all matchers with OR logic
|
50
|
-
# @example
|
51
|
-
# combine_procs(proc1, proc2, proc3)
|
52
|
-
# #=> proc { |record| proc1.call(record) || proc2.call(record) || proc3.call(record) }
|
53
|
-
def combine_procs(left, *rest)
|
54
|
-
return left if rest.empty?
|
55
|
-
|
56
|
-
right = combine_procs(*rest)
|
57
|
-
Proc.new do |record|
|
58
|
-
left.call(record) || right.call(record)
|
59
|
-
end
|
38
|
+
combine_procs_with_or(*matchers.map(&:to_proc))
|
60
39
|
end
|
61
40
|
|
62
41
|
# Builds an array of matchers from the subconditions.
|
@@ -66,7 +45,7 @@ module Mongory
|
|
66
45
|
define_instance_cache_method(:matchers) do
|
67
46
|
@condition.map do |condition|
|
68
47
|
HashConditionMatcher.build(condition, context: @context)
|
69
|
-
end
|
48
|
+
end.sort_by(&:priority)
|
70
49
|
end
|
71
50
|
|
72
51
|
# Ensures the condition is an array of hashes.
|
data/lib/mongory/utils.rb
CHANGED
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- koten0224
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A Mongo-like in-memory query DSL for Ruby
|
14
14
|
email:
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
105
|
+
rubygems_version: 3.1.6
|
106
106
|
signing_key:
|
107
107
|
specification_version: 4
|
108
108
|
summary: MongoDB-like in-memory query DSL for Ruby
|