rasti-db 2.0.0 → 2.3.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/README.md +11 -3
- data/lib/rasti/db.rb +11 -1
- data/lib/rasti/db/collection.rb +10 -1
- data/lib/rasti/db/computed_attribute.rb +22 -0
- data/lib/rasti/db/nql/filter_condition_strategies/base.rb +17 -0
- data/lib/rasti/db/nql/filter_condition_strategies/postgres.rb +21 -0
- data/lib/rasti/db/nql/filter_condition_strategies/sqlite.rb +21 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/generic.rb +49 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/pg_array.rb +32 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/sqlite_array.rb +34 -0
- data/lib/rasti/db/nql/filter_condition_strategies/unsupported_type_comparison.rb +22 -0
- data/lib/rasti/db/nql/nodes/array_content.rb +21 -0
- data/lib/rasti/db/nql/nodes/attribute.rb +37 -0
- data/lib/rasti/db/nql/nodes/binary_node.rb +4 -0
- data/lib/rasti/db/nql/nodes/comparisons/base.rb +15 -1
- data/lib/rasti/db/nql/nodes/comparisons/equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/greater_than.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/include.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/less_than.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/like.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/not_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/not_include.rb +0 -4
- data/lib/rasti/db/nql/nodes/conjunction.rb +2 -2
- data/lib/rasti/db/nql/nodes/constants/array.rb +17 -0
- data/lib/rasti/db/nql/nodes/constants/base.rb +17 -0
- data/lib/rasti/db/nql/nodes/constants/false.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/float.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/integer.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/literal_string.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/string.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/time.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/true.rb +1 -1
- data/lib/rasti/db/nql/nodes/disjunction.rb +2 -2
- data/lib/rasti/db/nql/nodes/parenthesis_sentence.rb +6 -2
- data/lib/rasti/db/nql/nodes/sentence.rb +6 -2
- data/lib/rasti/db/nql/syntax.rb +262 -44
- data/lib/rasti/db/nql/syntax.treetop +27 -14
- data/lib/rasti/db/query.rb +42 -14
- data/lib/rasti/db/type_converters/postgres.rb +32 -36
- data/lib/rasti/db/type_converters/postgres_types/array.rb +11 -9
- data/lib/rasti/db/type_converters/postgres_types/hstore.rb +10 -9
- data/lib/rasti/db/type_converters/postgres_types/json.rb +17 -14
- data/lib/rasti/db/type_converters/postgres_types/jsonb.rb +17 -14
- data/lib/rasti/db/type_converters/sqlite.rb +62 -0
- data/lib/rasti/db/type_converters/sqlite_types/array.rb +34 -0
- data/lib/rasti/db/version.rb +1 -1
- data/rasti-db.gemspec +1 -0
- data/spec/collection_spec.rb +19 -11
- data/spec/computed_attribute_spec.rb +32 -0
- data/spec/minitest_helper.rb +32 -5
- data/spec/model_spec.rb +1 -1
- data/spec/nql/computed_attributes_spec.rb +29 -0
- data/spec/nql/filter_condition_spec.rb +23 -4
- data/spec/nql/filter_condition_strategies_spec.rb +112 -0
- data/spec/nql/syntax_parser_spec.rb +36 -5
- data/spec/query_spec.rb +254 -39
- data/spec/type_converters/sqlite_spec.rb +66 -0
- metadata +38 -3
- data/lib/rasti/db/nql/nodes/field.rb +0 -23
@@ -31,7 +31,7 @@ describe 'NQL::SyntaxParser' do
|
|
31
31
|
proposition = tree.proposition
|
32
32
|
proposition.must_be_instance_of node_class
|
33
33
|
proposition.comparator.text_value.must_equal comparator
|
34
|
-
proposition.
|
34
|
+
proposition.attribute.text_value.must_equal 'column'
|
35
35
|
proposition.argument.text_value.must_equal 'value'
|
36
36
|
end
|
37
37
|
end
|
@@ -44,7 +44,7 @@ describe 'NQL::SyntaxParser' do
|
|
44
44
|
proposition = tree.proposition
|
45
45
|
proposition.must_be_instance_of Rasti::DB::NQL::Nodes::Comparisons::Equal
|
46
46
|
proposition.comparator.text_value.must_equal '='
|
47
|
-
proposition.
|
47
|
+
proposition.attribute.text_value.must_equal 'column'
|
48
48
|
proposition.argument.text_value.must_equal 'value'
|
49
49
|
end
|
50
50
|
|
@@ -128,12 +128,19 @@ describe 'NQL::SyntaxParser' do
|
|
128
128
|
|
129
129
|
end
|
130
130
|
|
131
|
-
it 'must parse expression with
|
131
|
+
it 'must parse expression with attribute with tables' do
|
132
132
|
tree = parse 'relation_table_one.relation_table_two.column = 1'
|
133
133
|
|
134
|
-
left_hand_operand = tree.proposition.
|
134
|
+
left_hand_operand = tree.proposition.attribute
|
135
135
|
left_hand_operand.tables.must_equal ['relation_table_one', 'relation_table_two']
|
136
|
-
left_hand_operand.column.must_equal
|
136
|
+
left_hand_operand.column.must_equal :column
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'must parse expression with computed attribute' do
|
140
|
+
tree = parse 'comments_count = 1'
|
141
|
+
computed = tree.proposition.attribute
|
142
|
+
computed.tables.must_equal []
|
143
|
+
computed.computed_attributes(Users).must_equal [:comments_count]
|
137
144
|
end
|
138
145
|
|
139
146
|
end
|
@@ -206,4 +213,28 @@ describe 'NQL::SyntaxParser' do
|
|
206
213
|
|
207
214
|
end
|
208
215
|
|
216
|
+
describe 'Array' do
|
217
|
+
|
218
|
+
it 'must parse array with one element' do
|
219
|
+
tree = parse 'column = [ a ]'
|
220
|
+
tree.proposition.argument.value.must_equal ['a']
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'must parse array with many elements' do
|
224
|
+
tree = parse 'column = [ a, b, c ]'
|
225
|
+
tree.proposition.argument.value.must_equal ['a', 'b', 'c']
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'must parse array respecting content types' do
|
229
|
+
tree = parse 'column = [ true, 12:00, 1.1, 1, "literal string", string ]'
|
230
|
+
tree.proposition.argument.value.must_equal [true, Timing::TimeInZone.parse('12:00').to_s, 1.1, 1, "literal string", 'string']
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'must parse array with literal string allowing reserved characters in conflict with array' do
|
234
|
+
tree = parse 'column = [ ",", "[", "]", "[,", "],", "[,]", "simple literal" ]'
|
235
|
+
tree.proposition.argument.value.must_equal [ ',', '[', ']', '[,', '],', '[,]', 'simple literal' ]
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
209
240
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -5,13 +5,13 @@ describe 'Query' do
|
|
5
5
|
before do
|
6
6
|
custom_db[:languages].insert name: 'Spanish'
|
7
7
|
|
8
|
-
1.upto(10) do |i|
|
8
|
+
1.upto(10) do |i|
|
9
9
|
db[:users].insert name: "User #{i}"
|
10
10
|
|
11
|
-
db[:people].insert user_id: i,
|
12
|
-
document_number: "document_#{i}",
|
13
|
-
first_name: "Name #{i}",
|
14
|
-
last_name: "Last Name #{i}",
|
11
|
+
db[:people].insert user_id: i,
|
12
|
+
document_number: "document_#{i}",
|
13
|
+
first_name: "Name #{i}",
|
14
|
+
last_name: "Last Name #{i}",
|
15
15
|
birth_date: Date.parse('2020-04-24')
|
16
16
|
|
17
17
|
db[:languages_people].insert language_id: 1, document_number: "document_#{i}"
|
@@ -22,7 +22,7 @@ describe 'Query' do
|
|
22
22
|
db[:posts].insert user_id: 4, title: 'Best post', body: '...', language_id: 1
|
23
23
|
|
24
24
|
1.upto(3) { |i| db[:categories].insert name: "Category #{i}" }
|
25
|
-
|
25
|
+
|
26
26
|
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 1'
|
27
27
|
db[:comments].insert post_id: 1, user_id: 7, text: 'Comment 2'
|
28
28
|
db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3'
|
@@ -35,11 +35,13 @@ describe 'Query' do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
let(:users_query) { Rasti::DB::Query.new collection_class: Users, dataset: db[:users], environment: environment }
|
38
|
-
|
38
|
+
|
39
39
|
let(:posts_query) { Rasti::DB::Query.new collection_class: Posts, dataset: db[:posts], environment: environment }
|
40
|
-
|
40
|
+
|
41
41
|
let(:comments_query) { Rasti::DB::Query.new collection_class: Comments, dataset: db[:comments], environment: environment }
|
42
42
|
|
43
|
+
let(:people_query) { Rasti::DB::Query.new collection_class: People, dataset: db[:people], environment: environment }
|
44
|
+
|
43
45
|
let(:languages_query) { Rasti::DB::Query.new collection_class: Languages, dataset: custom_db[:languages], environment: environment }
|
44
46
|
|
45
47
|
it 'Count' do
|
@@ -87,8 +89,8 @@ describe 'Query' do
|
|
87
89
|
post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
|
88
90
|
|
89
91
|
selected_attributes = {
|
90
|
-
user: [:id],
|
91
|
-
'user.person' => [:document_number, :user_id],
|
92
|
+
user: [:id],
|
93
|
+
'user.person' => [:document_number, :user_id],
|
92
94
|
'user.person.languages' => [:id],
|
93
95
|
categories: [:id]
|
94
96
|
}
|
@@ -99,7 +101,7 @@ describe 'Query' do
|
|
99
101
|
.all
|
100
102
|
.must_equal [post]
|
101
103
|
end
|
102
|
-
|
104
|
+
|
103
105
|
it 'Exclude graph attributes' do
|
104
106
|
language = Language.new custom_db[:languages].where(id: 1).select(:id).first
|
105
107
|
|
@@ -112,8 +114,8 @@ describe 'Query' do
|
|
112
114
|
post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
|
113
115
|
|
114
116
|
excluded_attributes = {
|
115
|
-
user: [:name],
|
116
|
-
'user.person' => [:first_name, :last_name, :birth_date],
|
117
|
+
user: [:name],
|
118
|
+
'user.person' => [:first_name, :last_name, :birth_date],
|
117
119
|
'user.person.languages' => [:name],
|
118
120
|
categories: [:name]
|
119
121
|
}
|
@@ -124,7 +126,7 @@ describe 'Query' do
|
|
124
126
|
.all
|
125
127
|
.must_equal [post]
|
126
128
|
end
|
127
|
-
|
129
|
+
|
128
130
|
it 'All graph attributes' do
|
129
131
|
person = Person.new db[:people].where(document_number: 'document_2').first
|
130
132
|
|
@@ -140,6 +142,30 @@ describe 'Query' do
|
|
140
142
|
.must_equal [post]
|
141
143
|
end
|
142
144
|
|
145
|
+
describe 'Select computed attributes' do
|
146
|
+
it 'With join' do
|
147
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
|
148
|
+
users_query.select_computed_attributes(:comments_count)
|
149
|
+
.where(id: 5)
|
150
|
+
.all
|
151
|
+
.must_equal [User.new(id: 5, name: 'User 5', comments_count: 2)]
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'Without join' do
|
155
|
+
person_expected = Person.new user_id: 1,
|
156
|
+
document_number: 'document_1',
|
157
|
+
first_name: 'Name 1',
|
158
|
+
last_name: 'Last Name 1',
|
159
|
+
birth_date: Date.parse('2020-04-24'),
|
160
|
+
full_name: 'Name 1 Last Name 1'
|
161
|
+
|
162
|
+
people_query.select_computed_attributes(:full_name)
|
163
|
+
.where(document_number: 'document_1')
|
164
|
+
.all
|
165
|
+
.must_equal [person_expected]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
143
169
|
it 'Map' do
|
144
170
|
users_query.map(&:name).must_equal db[:users].map(:name)
|
145
171
|
end
|
@@ -148,45 +174,88 @@ describe 'Query' do
|
|
148
174
|
users_query.detect(id: 3).must_equal User.new(id: 3, name: 'User 3')
|
149
175
|
end
|
150
176
|
|
177
|
+
describe 'Each' do
|
178
|
+
|
179
|
+
it 'without size' do
|
180
|
+
users = []
|
181
|
+
|
182
|
+
users_query.each do |user|
|
183
|
+
users << user
|
184
|
+
end
|
185
|
+
|
186
|
+
users.size.must_equal 10
|
187
|
+
users.each_with_index do |user, i|
|
188
|
+
user.must_equal User.new(id: i+1, name: "User #{i+1}")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'with size' do
|
193
|
+
users = []
|
194
|
+
users_query.each(batch_size: 2) do |user|
|
195
|
+
users << user
|
196
|
+
end
|
197
|
+
|
198
|
+
users.size.must_equal 10
|
199
|
+
users.each_with_index do |user, i|
|
200
|
+
user.must_equal User.new(id: i+1, name: "User #{i+1}")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'Each batch' do
|
207
|
+
users_batch = []
|
208
|
+
users_query.each_batch(size: 2) do |page|
|
209
|
+
users_batch << page
|
210
|
+
end
|
211
|
+
|
212
|
+
users_batch.size.must_equal 5
|
213
|
+
i = 1
|
214
|
+
users_batch.each do |user_page|
|
215
|
+
user_page.must_equal [User.new(id: i, name: "User #{i}"), User.new(id: i+1, name: "User #{i+1}")]
|
216
|
+
i += 2
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
151
220
|
it 'Where' do
|
152
221
|
users_query.where(id: 3).all.must_equal [User.new(id: 3, name: 'User 3')]
|
153
222
|
end
|
154
|
-
|
223
|
+
|
155
224
|
it 'Exclude' do
|
156
225
|
users_query.exclude(id: [1,2,3,4,5,6,7,8,9]).all.must_equal [User.new(id: 10, name: 'User 10')]
|
157
226
|
end
|
158
|
-
|
227
|
+
|
159
228
|
it 'And' do
|
160
229
|
users_query.where(id: [1,2]).where(name: 'User 2').all.must_equal [User.new(id: 2, name: 'User 2')]
|
161
230
|
end
|
162
|
-
|
231
|
+
|
163
232
|
it 'Or' do
|
164
233
|
users_query.where(id: 1).or(name: 'User 2').all.must_equal [
|
165
|
-
User.new(id: 1, name: 'User 1'),
|
234
|
+
User.new(id: 1, name: 'User 1'),
|
166
235
|
User.new(id: 2, name: 'User 2')
|
167
236
|
]
|
168
237
|
end
|
169
|
-
|
238
|
+
|
170
239
|
it 'Order' do
|
171
240
|
posts_query.order(:title).all.must_equal [
|
172
|
-
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
|
173
|
-
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
241
|
+
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
|
242
|
+
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
174
243
|
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1)
|
175
244
|
]
|
176
245
|
end
|
177
|
-
|
246
|
+
|
178
247
|
it 'Reverse order' do
|
179
248
|
posts_query.reverse_order(:title).all.must_equal [
|
180
249
|
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1),
|
181
|
-
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
250
|
+
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
182
251
|
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1)
|
183
252
|
]
|
184
253
|
end
|
185
|
-
|
254
|
+
|
186
255
|
it 'Limit and offset' do
|
187
256
|
users_query.limit(1).offset(1).all.must_equal [User.new(id: 2, name: 'User 2')]
|
188
257
|
end
|
189
|
-
|
258
|
+
|
190
259
|
it 'First' do
|
191
260
|
users_query.first.must_equal User.new(id: 1, name: 'User 1')
|
192
261
|
end
|
@@ -203,21 +272,21 @@ describe 'Query' do
|
|
203
272
|
language = Language.new id: 1, name: 'Spanish'
|
204
273
|
|
205
274
|
person = Person.new user_id: 2,
|
206
|
-
document_number: 'document_2',
|
207
|
-
first_name: 'Name 2',
|
208
|
-
last_name: 'Last Name 2',
|
275
|
+
document_number: 'document_2',
|
276
|
+
first_name: 'Name 2',
|
277
|
+
last_name: 'Last Name 2',
|
209
278
|
birth_date: Date.parse('2020-04-24'),
|
210
279
|
languages: [language]
|
211
280
|
|
212
|
-
user = User.new id: 2,
|
281
|
+
user = User.new id: 2,
|
213
282
|
name: 'User 2',
|
214
283
|
person: person
|
215
284
|
|
216
|
-
post = Post.new id: 1,
|
217
|
-
user_id: 2,
|
285
|
+
post = Post.new id: 1,
|
286
|
+
user_id: 2,
|
218
287
|
user: user,
|
219
|
-
title: 'Sample post',
|
220
|
-
body: '...',
|
288
|
+
title: 'Sample post',
|
289
|
+
body: '...',
|
221
290
|
language_id: 1,
|
222
291
|
language: language
|
223
292
|
|
@@ -237,7 +306,7 @@ describe 'Query' do
|
|
237
306
|
end
|
238
307
|
|
239
308
|
it 'To String' do
|
240
|
-
users_query.where(id: [1,2,3]).order(:name).to_s.must_equal '#<Rasti::DB::Query: "SELECT
|
309
|
+
users_query.where(id: [1,2,3]).order(:name).to_s.must_equal '#<Rasti::DB::Query: "SELECT `users`.* FROM `users` WHERE (`users`.`id` IN (1, 2, 3)) ORDER BY `users`.`name`">'
|
241
310
|
end
|
242
311
|
|
243
312
|
describe 'Named queries' do
|
@@ -257,19 +326,19 @@ describe 'Query' do
|
|
257
326
|
describe 'Join' do
|
258
327
|
|
259
328
|
it 'One to Many' do
|
260
|
-
users_query.join(:posts).where(title
|
329
|
+
users_query.join(:posts).where(Sequel[:posts][:title] => 'Sample post').all.must_equal [User.new(id: 2, name: 'User 2')]
|
261
330
|
end
|
262
331
|
|
263
332
|
it 'Many to One' do
|
264
|
-
posts_query.join(:user).where(name
|
333
|
+
posts_query.join(:user).where(Sequel[:user][:name] => 'User 4').all.must_equal [Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1)]
|
265
334
|
end
|
266
335
|
|
267
336
|
it 'One to One' do
|
268
|
-
users_query.join(:person).where(document_number
|
337
|
+
users_query.join(:person).where(Sequel[:person][:document_number] => 'document_1').all.must_equal [User.new(id: 1, name: 'User 1')]
|
269
338
|
end
|
270
339
|
|
271
340
|
it 'Many to Many' do
|
272
|
-
posts_query.join(:categories).where(name
|
341
|
+
posts_query.join(:categories).where(Sequel[:categories][:name] => 'Category 3').order(:id).all.must_equal [
|
273
342
|
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
|
274
343
|
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
275
344
|
]
|
@@ -283,6 +352,20 @@ describe 'Query' do
|
|
283
352
|
.must_equal [Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1)]
|
284
353
|
end
|
285
354
|
|
355
|
+
it 'Excluded attributes permanents excluded when join' do
|
356
|
+
posts_query.join(:user)
|
357
|
+
.exclude_attributes(:body)
|
358
|
+
.where(Sequel[:user][:name] => 'User 4')
|
359
|
+
.all
|
360
|
+
.must_equal [Post.new(id: 3, title: 'Best post', user_id: 4, language_id: 1)]
|
361
|
+
|
362
|
+
posts_query.exclude_attributes(:body)
|
363
|
+
.join(:user)
|
364
|
+
.where(Sequel[:user][:name] => 'User 4')
|
365
|
+
.all
|
366
|
+
.must_equal [Post.new(id: 3, title: 'Best post', user_id: 4, language_id: 1)]
|
367
|
+
end
|
368
|
+
|
286
369
|
describe 'Multiple data sources' do
|
287
370
|
|
288
371
|
it 'One to Many' do
|
@@ -309,7 +392,7 @@ describe 'Query' do
|
|
309
392
|
error = proc { posts_query.nql('a + b') }.must_raise Rasti::DB::NQL::InvalidExpressionError
|
310
393
|
error.message.must_equal 'Invalid filter expression: a + b'
|
311
394
|
end
|
312
|
-
|
395
|
+
|
313
396
|
it 'Filter to self table' do
|
314
397
|
posts_query.nql('user_id > 1')
|
315
398
|
.pluck(:user_id)
|
@@ -336,6 +419,138 @@ describe 'Query' do
|
|
336
419
|
.must_equal [2]
|
337
420
|
end
|
338
421
|
|
422
|
+
describe 'Computed Attributes' do
|
423
|
+
|
424
|
+
it 'Filter relation computed attribute' do
|
425
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
|
426
|
+
users_query.nql('comments_count = 2').all.must_equal [User.new(id: 5, name: 'User 5')]
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'Filter with relation computed attribute with "and" combined' do
|
430
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
|
431
|
+
db[:comments].insert post_id: 1, user_id: 4, text: 'Comment 3'
|
432
|
+
users_query.nql('(comments_count > 1) & (id = 5)').all.must_equal [User.new(id: 5, name: 'User 5')]
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'Filter relation computed attribute with "or" combined' do
|
436
|
+
db[:comments].insert post_id: 1, user_id: 2, text: 'Comment 3'
|
437
|
+
users_query.nql('(comments_count = 2) | (id = 5)')
|
438
|
+
.order(:id)
|
439
|
+
.all
|
440
|
+
.must_equal [ User.new(id: 2, name: 'User 2'), User.new(id: 5, name: 'User 5') ]
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'Filter relation computed attribute with "and" and "or" combined' do
|
444
|
+
db[:comments].insert post_id: 1, user_id: 2, text: 'Comment 3'
|
445
|
+
users_query.nql('((comments_count = 2) | (id = 5)) & (name: User 5)')
|
446
|
+
.order(:id)
|
447
|
+
.all
|
448
|
+
.must_equal [ User.new(id: 5, name: 'User 5') ]
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'Filter simple computed attribute' do
|
452
|
+
person_expected = Person.new user_id: 1,
|
453
|
+
document_number: 'document_1',
|
454
|
+
first_name: 'Name 1',
|
455
|
+
last_name: 'Last Name 1',
|
456
|
+
birth_date: Date.parse('2020-04-24')
|
457
|
+
|
458
|
+
people_query.nql('full_name = Name 1 Last Name 1')
|
459
|
+
.all
|
460
|
+
.must_equal [person_expected]
|
461
|
+
end
|
462
|
+
|
463
|
+
end
|
464
|
+
|
465
|
+
describe 'Filter Array' do
|
466
|
+
|
467
|
+
def filter_condition_must_raise(comparison_symbol, comparison_name)
|
468
|
+
error = proc { comments_query.nql("tags #{comparison_symbol} [fake, notice]") }.must_raise Rasti::DB::NQL::FilterConditionStrategies::UnsupportedTypeComparison
|
469
|
+
error.argument_type.must_equal Rasti::DB::NQL::FilterConditionStrategies::Types::SQLiteArray
|
470
|
+
error.comparison_name.must_equal comparison_name
|
471
|
+
error.message.must_equal "Unsupported comparison #{comparison_name} for Rasti::DB::NQL::FilterConditionStrategies::Types::SQLiteArray"
|
472
|
+
end
|
473
|
+
|
474
|
+
it 'Must raise exception from not supported methods' do
|
475
|
+
comparisons = {
|
476
|
+
greater_than: '>',
|
477
|
+
greater_than_or_equal: '>=',
|
478
|
+
less_than: '<',
|
479
|
+
less_than_or_equal: '<='
|
480
|
+
}
|
481
|
+
|
482
|
+
comparisons.each do |name, symbol|
|
483
|
+
filter_condition_must_raise symbol, name
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'Included any of these elements' do
|
488
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
|
489
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 2', tags: '["notice"]'
|
490
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 3', tags: '["fake_notice"]'
|
491
|
+
expected_comments = [
|
492
|
+
Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1),
|
493
|
+
Comment.new(id: 5, text: 'fake notice 2', tags: ['notice'], user_id: 5, post_id: 1)
|
494
|
+
]
|
495
|
+
|
496
|
+
comments_query.nql('tags: [ fake, notice ]')
|
497
|
+
.all
|
498
|
+
.must_equal expected_comments
|
499
|
+
end
|
500
|
+
|
501
|
+
it 'Included exactly all these elements' do
|
502
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
|
503
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 2', tags: '["notice"]'
|
504
|
+
comments_query.nql('tags = [fake, notice]')
|
505
|
+
.all
|
506
|
+
.must_equal [Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1)]
|
507
|
+
end
|
508
|
+
|
509
|
+
it 'Not included anyone of these elements' do
|
510
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
|
511
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Good notice!', tags: '["good"]'
|
512
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake"]'
|
513
|
+
expected_comments = [
|
514
|
+
Comment.new(id: 1, text: 'Comment 1', tags: [], user_id: 5, post_id: 1),
|
515
|
+
Comment.new(id: 2, text: 'Comment 2', tags: [], user_id: 7, post_id: 1),
|
516
|
+
Comment.new(id: 3, text: 'Comment 3', tags: [], user_id: 2, post_id: 2),
|
517
|
+
Comment.new(id: 5, text: 'Good notice!', tags: ['good'], user_id: 5, post_id: 1)
|
518
|
+
]
|
519
|
+
comments_query.nql('tags !: [fake, notice]')
|
520
|
+
.all
|
521
|
+
.must_equal expected_comments
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'Not include any of these elements' do
|
525
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
|
526
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Good notice!', tags: '["good"]'
|
527
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake"]'
|
528
|
+
expected_comments = [
|
529
|
+
Comment.new(id: 1, text: 'Comment 1', tags: '[]', user_id: 5, post_id: 1),
|
530
|
+
Comment.new(id: 2, text: 'Comment 2', tags: '[]', user_id: 7, post_id: 1),
|
531
|
+
Comment.new(id: 3, text: 'Comment 3', tags: '[]', user_id: 2, post_id: 2),
|
532
|
+
Comment.new(id: 5, text: 'Good notice!', tags: ['good'], user_id: 5, post_id: 1),
|
533
|
+
Comment.new(id: 6, text: 'fake notice', tags: ['fake'], user_id: 5, post_id: 1)
|
534
|
+
]
|
535
|
+
comments_query.nql('tags != [fake, notice]')
|
536
|
+
.all
|
537
|
+
.must_equal expected_comments
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'Include any like these elements' do
|
541
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
|
542
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'this is a fake notice!', tags: '["fake_notice"]'
|
543
|
+
expected_comments = [
|
544
|
+
Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1),
|
545
|
+
Comment.new(id: 5, text: 'this is a fake notice!', tags: ['fake_notice'], user_id: 5, post_id: 1)
|
546
|
+
]
|
547
|
+
comments_query.nql('tags ~ [fake]')
|
548
|
+
.all
|
549
|
+
.must_equal expected_comments
|
550
|
+
end
|
551
|
+
|
552
|
+
end
|
553
|
+
|
339
554
|
end
|
340
555
|
|
341
556
|
end
|