clearly-query 0.3.1.pre
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 +7 -0
- data/.codeclimate.yml +8 -0
- data/.gitignore +42 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +43 -0
- data/Gemfile +7 -0
- data/Guardfile +19 -0
- data/LICENSE +22 -0
- data/README.md +102 -0
- data/Rakefile +7 -0
- data/SPEC.md +101 -0
- data/bin/guard +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/yard +16 -0
- data/clearly-query.gemspec +33 -0
- data/lib/clearly/query.rb +22 -0
- data/lib/clearly/query/cleaner.rb +63 -0
- data/lib/clearly/query/compose/comparison.rb +102 -0
- data/lib/clearly/query/compose/conditions.rb +215 -0
- data/lib/clearly/query/compose/core.rb +75 -0
- data/lib/clearly/query/compose/custom.rb +268 -0
- data/lib/clearly/query/compose/range.rb +114 -0
- data/lib/clearly/query/compose/special.rb +24 -0
- data/lib/clearly/query/compose/subset.rb +115 -0
- data/lib/clearly/query/composer.rb +269 -0
- data/lib/clearly/query/definition.rb +165 -0
- data/lib/clearly/query/errors.rb +27 -0
- data/lib/clearly/query/graph.rb +63 -0
- data/lib/clearly/query/helper.rb +50 -0
- data/lib/clearly/query/validate.rb +296 -0
- data/lib/clearly/query/version.rb +8 -0
- data/spec/lib/clearly/query/cleaner_spec.rb +42 -0
- data/spec/lib/clearly/query/compose/custom_spec.rb +77 -0
- data/spec/lib/clearly/query/composer_query_spec.rb +50 -0
- data/spec/lib/clearly/query/composer_spec.rb +422 -0
- data/spec/lib/clearly/query/definition_spec.rb +23 -0
- data/spec/lib/clearly/query/graph_spec.rb +81 -0
- data/spec/lib/clearly/query/helper_spec.rb +17 -0
- data/spec/lib/clearly/query/version_spec.rb +7 -0
- data/spec/spec_helper.rb +89 -0
- data/spec/support/db/migrate/001_db_create.rb +62 -0
- data/spec/support/models/customer.rb +63 -0
- data/spec/support/models/order.rb +66 -0
- data/spec/support/models/part.rb +63 -0
- data/spec/support/models/product.rb +67 -0
- data/spec/support/shared_setup.rb +13 -0
- data/tmp/.gitkeep +0 -0
- metadata +263 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Clearly
|
|
2
|
+
module Query
|
|
3
|
+
module Compose
|
|
4
|
+
|
|
5
|
+
# Provides 'and', and 'or' for composing queries.
|
|
6
|
+
module Core
|
|
7
|
+
include Clearly::Query::Validate
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Get the ActiveRecord::Relation that represents zero records.
|
|
12
|
+
# @param [ActiveRecord::Base] model
|
|
13
|
+
# @return [ActiveRecord::Relation] query that will get zero records
|
|
14
|
+
def relation_none(model)
|
|
15
|
+
validate_model(model)
|
|
16
|
+
model.none
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Get the ActiveRecord::Relation that represents all records.
|
|
20
|
+
# @param [ActiveRecord::Base] model
|
|
21
|
+
# @return [ActiveRecord::Relation] query that will get all records
|
|
22
|
+
def relation_all(model)
|
|
23
|
+
validate_model(model)
|
|
24
|
+
model.all
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get the Arel::Table for this model.
|
|
28
|
+
# @param [ActiveRecord::Base] model
|
|
29
|
+
# @return [Arel::Table] arel table
|
|
30
|
+
def relation_table(model)
|
|
31
|
+
validate_model(model)
|
|
32
|
+
model.arel_table
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Join conditions using or.
|
|
36
|
+
# @param [Arel::Nodes::Node] first_condition
|
|
37
|
+
# @param [Arel::Nodes::Node] second_condition
|
|
38
|
+
# @return [Arel::Nodes::Node] condition
|
|
39
|
+
def compose_or(first_condition, second_condition)
|
|
40
|
+
validate_condition(first_condition)
|
|
41
|
+
validate_condition(second_condition)
|
|
42
|
+
first_condition.or(second_condition)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Join conditions using and.
|
|
46
|
+
# @param [Arel::Nodes::Node] first_condition
|
|
47
|
+
# @param [Arel::Nodes::Node] second_condition
|
|
48
|
+
# @param [Array<Arel::Nodes::Node>] conditions
|
|
49
|
+
# @return [Arel::Nodes::Node] condition
|
|
50
|
+
def compose_and(first_condition, second_condition, *conditions)
|
|
51
|
+
validate_condition(first_condition)
|
|
52
|
+
validate_condition(second_condition)
|
|
53
|
+
combined = first_condition.and(second_condition)
|
|
54
|
+
|
|
55
|
+
unless conditions.blank?
|
|
56
|
+
conditions.each do |condition|
|
|
57
|
+
combined = combined.and(condition)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
combined
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Join conditions using not.
|
|
65
|
+
# @param [Arel::Nodes::Node] condition
|
|
66
|
+
# @return [Arel::Nodes::Node] condition
|
|
67
|
+
def compose_not(condition)
|
|
68
|
+
validate_condition(condition)
|
|
69
|
+
condition.not
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
module Clearly
|
|
2
|
+
module Query
|
|
3
|
+
module Compose
|
|
4
|
+
|
|
5
|
+
# Public class for creating custom queries.
|
|
6
|
+
class Custom
|
|
7
|
+
include Clearly::Query::Compose::Comparison
|
|
8
|
+
include Clearly::Query::Compose::Core
|
|
9
|
+
include Clearly::Query::Compose::Range
|
|
10
|
+
include Clearly::Query::Compose::Subset
|
|
11
|
+
include Clearly::Query::Compose::Special
|
|
12
|
+
include Clearly::Query::Validate
|
|
13
|
+
|
|
14
|
+
# Create equals condition.
|
|
15
|
+
# @param [Arel::Table] table
|
|
16
|
+
# @param [Symbol] column_name
|
|
17
|
+
# @param [Array<Symbol>] allowed
|
|
18
|
+
# @param [Object] value
|
|
19
|
+
# @return [Arel::Nodes::Node] condition
|
|
20
|
+
def compose_eq(table, column_name, allowed, value)
|
|
21
|
+
validate_table_column(table, column_name, allowed)
|
|
22
|
+
compose_eq_node(table[column_name], value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Create not equals condition.
|
|
26
|
+
# @param [Arel::Table] table
|
|
27
|
+
# @param [Symbol] column_name
|
|
28
|
+
# @param [Array<Symbol>] allowed
|
|
29
|
+
# @param [Object] value
|
|
30
|
+
# @return [Arel::Nodes::Node] condition
|
|
31
|
+
def compose_not_eq(table, column_name, allowed, value)
|
|
32
|
+
validate_table_column(table, column_name, allowed)
|
|
33
|
+
compose_not_eq_node(table[column_name], value)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Create less than condition.
|
|
37
|
+
# @param [Arel::Table] table
|
|
38
|
+
# @param [Symbol] column_name
|
|
39
|
+
# @param [Array<Symbol>] allowed
|
|
40
|
+
# @param [Object] value
|
|
41
|
+
# @return [Arel::Nodes::Node] condition
|
|
42
|
+
def compose_lt(table, column_name, allowed, value)
|
|
43
|
+
validate_table_column(table, column_name, allowed)
|
|
44
|
+
compose_lt_node(table[column_name], value)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Create not less than condition.
|
|
48
|
+
# @param [Arel::Table] table
|
|
49
|
+
# @param [Symbol] column_name
|
|
50
|
+
# @param [Array<Symbol>] allowed
|
|
51
|
+
# @param [Object] value
|
|
52
|
+
# @return [Arel::Nodes::Node] condition
|
|
53
|
+
def compose_not_lt(table, column_name, allowed, value)
|
|
54
|
+
compose_gteq(table, column_name, allowed, value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Create greater than condition.
|
|
58
|
+
# @param [Arel::Table] table
|
|
59
|
+
# @param [Symbol] column_name
|
|
60
|
+
# @param [Array<Symbol>] allowed
|
|
61
|
+
# @param [Object] value
|
|
62
|
+
# @return [Arel::Nodes::Node] condition
|
|
63
|
+
def compose_gt(table, column_name, allowed, value)
|
|
64
|
+
validate_table_column(table, column_name, allowed)
|
|
65
|
+
compose_gt_node(table[column_name], value)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Create not greater than condition.
|
|
69
|
+
# @param [Arel::Table] table
|
|
70
|
+
# @param [Symbol] column_name
|
|
71
|
+
# @param [Array<Symbol>] allowed
|
|
72
|
+
# @param [Object] value
|
|
73
|
+
# @return [Arel::Nodes::Node] condition
|
|
74
|
+
def compose_not_gt(table, column_name, allowed, value)
|
|
75
|
+
compose_lteq(table, column_name, allowed, value)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Create less than or equal condition.
|
|
79
|
+
# @param [Arel::Table] table
|
|
80
|
+
# @param [Symbol] column_name
|
|
81
|
+
# @param [Array<Symbol>] allowed
|
|
82
|
+
# @param [Object] value
|
|
83
|
+
# @return [Arel::Nodes::Node] condition
|
|
84
|
+
def compose_lteq(table, column_name, allowed, value)
|
|
85
|
+
validate_table_column(table, column_name, allowed)
|
|
86
|
+
compose_lteq_node(table[column_name], value)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Create not less than or equal condition.
|
|
90
|
+
# @param [Arel::Table] table
|
|
91
|
+
# @param [Symbol] column_name
|
|
92
|
+
# @param [Array<Symbol>] allowed
|
|
93
|
+
# @param [Object] value
|
|
94
|
+
# @return [Arel::Nodes::Node] condition
|
|
95
|
+
def compose_not_lteq(table, column_name, allowed, value)
|
|
96
|
+
compose_gt(table, column_name, allowed, value)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Create greater than or equal condition.
|
|
100
|
+
# @param [Arel::Table] table
|
|
101
|
+
# @param [Symbol] column_name
|
|
102
|
+
# @param [Array<Symbol>] allowed
|
|
103
|
+
# @param [Object] value
|
|
104
|
+
# @return [Arel::Nodes::Node] condition
|
|
105
|
+
def compose_gteq(table, column_name, allowed, value)
|
|
106
|
+
validate_table_column(table, column_name, allowed)
|
|
107
|
+
compose_gteq_node(table[column_name], value)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Create not greater than or equal condition.
|
|
111
|
+
# @param [Arel::Table] table
|
|
112
|
+
# @param [Symbol] column_name
|
|
113
|
+
# @param [Array<Symbol>] allowed
|
|
114
|
+
# @param [Object] value
|
|
115
|
+
# @return [Arel::Nodes::Node] condition
|
|
116
|
+
def compose_not_gteq(table, column_name, allowed, value)
|
|
117
|
+
compose_lt(table, column_name, allowed, value)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Create contains condition.
|
|
121
|
+
# @param [Arel::Table] table
|
|
122
|
+
# @param [Symbol] column_name
|
|
123
|
+
# @param [Array<Symbol>] allowed
|
|
124
|
+
# @param [Object] value
|
|
125
|
+
# @return [Arel::Nodes::Node] condition
|
|
126
|
+
def compose_contains(table, column_name, allowed, value)
|
|
127
|
+
validate_table_column(table, column_name, allowed)
|
|
128
|
+
compose_contains_node(table[column_name], value)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Create not contains condition.
|
|
132
|
+
# @param [Arel::Table] table
|
|
133
|
+
# @param [Symbol] column_name
|
|
134
|
+
# @param [Array<Symbol>] allowed
|
|
135
|
+
# @param [Object] value
|
|
136
|
+
# @return [Arel::Nodes::Node] condition
|
|
137
|
+
def compose_not_contains(table, column_name, allowed, value)
|
|
138
|
+
validate_table_column(table, column_name, allowed)
|
|
139
|
+
compose_not_contains_node(table[column_name], value)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Create starts_with condition.
|
|
143
|
+
# @param [Arel::Table] table
|
|
144
|
+
# @param [Symbol] column_name
|
|
145
|
+
# @param [Array<Symbol>] allowed
|
|
146
|
+
# @param [Object] value
|
|
147
|
+
# @return [Arel::Nodes::Node] condition
|
|
148
|
+
def compose_starts_with(table, column_name, allowed, value)
|
|
149
|
+
validate_table_column(table, column_name, allowed)
|
|
150
|
+
compose_starts_with_node(table[column_name], value)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Create not starts_with condition.
|
|
154
|
+
# @param [Arel::Table] table
|
|
155
|
+
# @param [Symbol] column_name
|
|
156
|
+
# @param [Array<Symbol>] allowed
|
|
157
|
+
# @param [Object] value
|
|
158
|
+
# @return [Arel::Nodes::Node] condition
|
|
159
|
+
def compose_not_starts_with(table, column_name, allowed, value)
|
|
160
|
+
validate_table_column(table, column_name, allowed)
|
|
161
|
+
compose_not_starts_with_node(table[column_name], value)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Create ends_with condition.
|
|
165
|
+
# @param [Arel::Table] table
|
|
166
|
+
# @param [Symbol] column_name
|
|
167
|
+
# @param [Array<Symbol>] allowed
|
|
168
|
+
# @param [Object] value
|
|
169
|
+
# @return [Arel::Nodes::Node] condition
|
|
170
|
+
def compose_ends_with(table, column_name, allowed, value)
|
|
171
|
+
validate_table_column(table, column_name, allowed)
|
|
172
|
+
compose_ends_with_node(table[column_name], value)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Create not ends_with condition.
|
|
176
|
+
# @param [Arel::Table] table
|
|
177
|
+
# @param [Symbol] column_name
|
|
178
|
+
# @param [Array<Symbol>] allowed
|
|
179
|
+
# @param [Object] value
|
|
180
|
+
# @return [Arel::Nodes::Node] condition
|
|
181
|
+
def compose_not_ends_with(table, column_name, allowed, value)
|
|
182
|
+
validate_table_column(table, column_name, allowed)
|
|
183
|
+
compose_not_ends_with_node(table[column_name], value)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Create IN condition.
|
|
187
|
+
# @param [Arel::Table] table
|
|
188
|
+
# @param [Symbol] column_name
|
|
189
|
+
# @param [Array<Symbol>] allowed
|
|
190
|
+
# @param [Array] values
|
|
191
|
+
# @return [Arel::Nodes::Node] condition
|
|
192
|
+
def compose_in(table, column_name, allowed, values)
|
|
193
|
+
validate_table_column(table, column_name, allowed)
|
|
194
|
+
compose_in_node(table[column_name], values)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Create NOT IN condition.
|
|
198
|
+
# @param [Arel::Table] table
|
|
199
|
+
# @param [Symbol] column_name
|
|
200
|
+
# @param [Array<Symbol>] allowed
|
|
201
|
+
# @param [Array] values
|
|
202
|
+
# @return [Arel::Nodes::Node] condition
|
|
203
|
+
def compose_not_in(table, column_name, allowed, values)
|
|
204
|
+
validate_table_column(table, column_name, allowed)
|
|
205
|
+
compose_not_in_node(table[column_name], values)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Create regular expression condition.
|
|
209
|
+
# @param [Arel::Table] table
|
|
210
|
+
# @param [Symbol] column_name
|
|
211
|
+
# @param [Array<Symbol>] allowed
|
|
212
|
+
# @param [Object] value
|
|
213
|
+
# @return [Arel::Nodes::Node] condition
|
|
214
|
+
def compose_regex(table, column_name, allowed, value)
|
|
215
|
+
validate_table_column(table, column_name, allowed)
|
|
216
|
+
compose_regex_node(table[column_name], value)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Create negated regular expression condition.
|
|
220
|
+
# Not available just now, maybe in Arel 6?
|
|
221
|
+
# @param [Arel::Table] table
|
|
222
|
+
# @param [Symbol] column_name
|
|
223
|
+
# @param [Array<Symbol>] allowed
|
|
224
|
+
# @param [Object] value
|
|
225
|
+
# @return [Arel::Nodes::Node] condition
|
|
226
|
+
def compose_not_regex(table, column_name, allowed, value)
|
|
227
|
+
validate_table_column(table, column_name, allowed)
|
|
228
|
+
compose_not_regex_node(table[column_name], value)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Create null comparison.
|
|
232
|
+
# @param [Arel::Table] table
|
|
233
|
+
# @param [Symbol] column_name
|
|
234
|
+
# @param [Array<Symbol>] allowed
|
|
235
|
+
# @param [Boolean] value
|
|
236
|
+
# @return [Arel::Nodes::Node] condition
|
|
237
|
+
def compose_null(table, column_name, allowed, value)
|
|
238
|
+
validate_table_column(table, column_name, allowed)
|
|
239
|
+
validate_boolean(value)
|
|
240
|
+
compose_null_node(table[column_name], value)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Create IN condition using from (inclusive) and to (exclusive).
|
|
244
|
+
# @param [Arel::Table] table
|
|
245
|
+
# @param [Symbol] column_name
|
|
246
|
+
# @param [Array<Symbol>] allowed
|
|
247
|
+
# @param [Object] value
|
|
248
|
+
# @return [Arel::Nodes::Node] condition
|
|
249
|
+
def compose_range(table, column_name, allowed, value)
|
|
250
|
+
validate_table_column(table, column_name, allowed)
|
|
251
|
+
compose_range_node(table[column_name], value)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Create NOT IN condition using from (inclusive) and to (exclusive).
|
|
255
|
+
# @param [Arel::Table] table
|
|
256
|
+
# @param [Symbol] column_name
|
|
257
|
+
# @param [Array<Symbol>] allowed
|
|
258
|
+
# @param [Object] value
|
|
259
|
+
# @return [Arel::Nodes::Node] condition
|
|
260
|
+
def compose_not_range(table, column_name, allowed, value)
|
|
261
|
+
validate_table_column(table, column_name, allowed)
|
|
262
|
+
compose_not_range_node(table[column_name], value)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Clearly
|
|
2
|
+
module Query
|
|
3
|
+
module Compose
|
|
4
|
+
|
|
5
|
+
# Methods for composing range queries.
|
|
6
|
+
module Range
|
|
7
|
+
include Clearly::Query::Validate
|
|
8
|
+
|
|
9
|
+
# Parse an interval.
|
|
10
|
+
# @param [String] value
|
|
11
|
+
# @return [Array<String>] captures
|
|
12
|
+
def parse_interval(value)
|
|
13
|
+
range_regex = /(\[|\()(.*),(.*)(\)|\])/i
|
|
14
|
+
matches = value.match(range_regex)
|
|
15
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
16
|
+
"range string must be in the form (|[.*,.*]|), got '#{value}'") unless matches
|
|
17
|
+
|
|
18
|
+
captures = matches.captures
|
|
19
|
+
{
|
|
20
|
+
start_include: captures[0] == '[',
|
|
21
|
+
start_value: captures[1],
|
|
22
|
+
end_value: captures[2],
|
|
23
|
+
end_include: captures[3] == ']'
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Validate a range.
|
|
28
|
+
# @param [Hash] hash
|
|
29
|
+
# @return [Hash]
|
|
30
|
+
def parse_range(hash)
|
|
31
|
+
unless hash.is_a?(Hash)
|
|
32
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
33
|
+
"range filter must be {'from': 'value', 'to': 'value'} " +
|
|
34
|
+
"or {'interval': '(|[.*,.*]|)'} got '#{hash}'", {hash: hash})
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
from = hash[:from]
|
|
39
|
+
to = hash[:to]
|
|
40
|
+
interval = hash[:interval]
|
|
41
|
+
|
|
42
|
+
if !from.blank? && !to.blank? && !interval.blank?
|
|
43
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
44
|
+
"range filter must use either ('from' and 'to') or ('interval'), not both", {hash: hash})
|
|
45
|
+
elsif from.blank? && !to.blank?
|
|
46
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
47
|
+
"range filter missing 'from'", {hash: hash})
|
|
48
|
+
elsif !from.blank? && to.blank?
|
|
49
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
50
|
+
"range filter missing 'to'", {hash: hash})
|
|
51
|
+
elsif !from.blank? && !to.blank?
|
|
52
|
+
parse_interval("[#{from},#{to})")
|
|
53
|
+
elsif !interval.blank?
|
|
54
|
+
parse_interval(interval)
|
|
55
|
+
else
|
|
56
|
+
fail Clearly::Query::QueryArgumentError.new(
|
|
57
|
+
"range filter did not contain ('from' and 'to') or ('interval'), got '#{hash}'", {hash: hash})
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Create IN condition using from (inclusive) and to (exclusive).
|
|
64
|
+
# @param [Arel::Nodes::Node, Arel::Attributes::Attribute, String] node
|
|
65
|
+
# @param [Object] value
|
|
66
|
+
# @return [Arel::Nodes::Node] condition
|
|
67
|
+
def compose_range_node(node, value)
|
|
68
|
+
validate_node_or_attribute(node)
|
|
69
|
+
range_info = parse_range(value)
|
|
70
|
+
|
|
71
|
+
# build using gt, lt, gteq, lteq
|
|
72
|
+
if range_info[:start_include]
|
|
73
|
+
start_condition = node.gteq(range_info[:start_value])
|
|
74
|
+
else
|
|
75
|
+
start_condition = node.gt(range_info[:start_value])
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
if range_info[:end_include]
|
|
79
|
+
end_condition = node.lteq(range_info[:end_value])
|
|
80
|
+
else
|
|
81
|
+
end_condition = node.lt(range_info[:end_value])
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
start_condition.and(end_condition)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Create NOT IN condition using from (inclusive) and to (exclusive).
|
|
88
|
+
# @param [Arel::Nodes::Node, Arel::Attributes::Attribute, String] node
|
|
89
|
+
# @param [Object] value
|
|
90
|
+
# @return [Arel::Nodes::Node] condition
|
|
91
|
+
def compose_not_range_node(node, value)
|
|
92
|
+
validate_node_or_attribute(node)
|
|
93
|
+
range_info = parse_range(value)
|
|
94
|
+
|
|
95
|
+
# build using gt, lt, gteq, lteq
|
|
96
|
+
if range_info[:start_include]
|
|
97
|
+
start_condition = node.lt(range_info[:start_value])
|
|
98
|
+
else
|
|
99
|
+
start_condition = node.lteq(range_info[:start_value])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if range_info[:end_include]
|
|
103
|
+
end_condition = node.gt(range_info[:end_value])
|
|
104
|
+
else
|
|
105
|
+
end_condition = node.gteq(range_info[:end_value])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
start_condition.or(end_condition)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|