v / vlib / orm / orm_dynamic_test.v
505 lines · 440 sloc · 8.49 KB · 27f394507e26c13f3d1bd3a8868f7b649038e2fd
Raw
1// vtest retry: 3
2import db.sqlite
3
4@[table: 'dynamic_members']
5struct DynamicMember {
6mut:
7 id int @[primary; sql: serial]
8 name string
9 email string
10 age int
11 status string
12}
13
14struct DynamicMemberFilter {
15 name ?string
16}
17
18@[table: 'dynamic_cast_members']
19struct DynamicCastMember {
20mut:
21 id int @[primary; sql: serial]
22 name string
23 is_required u8
24}
25
26@[table: 'dynamic_or_members']
27struct DynamicOrMember {
28mut:
29 id int @[primary]
30 tenant_id int
31 name string
32 status string
33}
34
35fn test_dynamic_select_with_inline_where_block() {
36 mut db := sqlite.connect(':memory:')!
37 defer {
38 db.close() or { panic(err) }
39 }
40
41 sql db {
42 create table DynamicMember
43 }!
44
45 first := DynamicMember{
46 name: 'Alice'
47 email: '[email protected]'
48 age: 31
49 status: 'active'
50 }
51 second := DynamicMember{
52 name: 'Bob'
53 email: '[email protected]'
54 age: 24
55 status: 'pending'
56 }
57 third := DynamicMember{
58 name: 'Alice'
59 email: '[email protected]'
60 age: 19
61 status: 'inactive'
62 }
63
64 sql db {
65 insert first into DynamicMember
66 insert second into DynamicMember
67 insert third into DynamicMember
68 }!
69
70 name_filter := 'Alice'
71 min_age := 30
72 status_filter := ''
73
74 rows := sql db {
75 dynamic select from DynamicMember where {
76 if name_filter != '' {
77 name == name_filter
78 },
79 if min_age > 0 {
80 age >= min_age
81 },
82 if status_filter != '' {
83 status == status_filter
84 }
85 } order by id
86 }!
87
88 assert rows.len == 1
89 assert rows[0].name == 'Alice'
90 assert rows[0].email == '[email protected]'
91 assert rows[0].age == 31
92
93 filter := DynamicMemberFilter{
94 name: 'Alice'
95 }
96 where_expr := {
97 if name := filter.name {
98 name == name
99 }
100 }
101
102 guard_rows := sql db {
103 dynamic select from DynamicMember where where_expr
104 }!
105
106 assert guard_rows.len == 2
107}
108
109fn test_dynamic_update_with_alias_set_block() {
110 mut db := sqlite.connect(':memory:')!
111 defer {
112 db.close() or { panic(err) }
113 }
114
115 sql db {
116 create table DynamicMember
117 }!
118
119 member := DynamicMember{
120 name: 'Alice'
121 email: '[email protected]'
122 age: 31
123 status: 'active'
124 }
125
126 sql db {
127 insert member into DynamicMember
128 }!
129
130 id := db.last_id()
131 next_name := 'Alicia'
132 next_email := ''
133 next_status := 'inactive'
134 update_expr := {
135 if next_name != '' {
136 name == next_name
137 },
138 if next_email != '' {
139 email == next_email
140 },
141 status == next_status
142 }
143
144 sql db {
145 dynamic update DynamicMember set update_expr where id == id
146 }!
147
148 rows := sql db {
149 select from DynamicMember where id == id
150 }!
151
152 assert rows.len == 1
153 assert rows[0].name == next_name
154 assert rows[0].email == '[email protected]'
155 assert rows[0].status == next_status
156}
157
158fn test_dynamic_update_with_alias_set_block_cast_expr() {
159 mut db := sqlite.connect(':memory:')!
160 defer {
161 db.close() or { panic(err) }
162 }
163
164 sql db {
165 create table DynamicCastMember
166 }!
167
168 member := DynamicCastMember{
169 name: 'Alice'
170 is_required: 0
171 }
172
173 sql db {
174 insert member into DynamicCastMember
175 }!
176
177 id := db.last_id()
178 next_name := 'Alicia'
179 next_required := true
180 filter := DynamicMemberFilter{
181 name: next_name
182 }
183 update_expr := {
184 if name := filter.name {
185 name == name
186 },
187 is_required == u8(if next_required { 1 } else { 0 })
188 }
189
190 sql db {
191 dynamic update DynamicCastMember set update_expr where id == id
192 }!
193
194 rows := sql db {
195 select from DynamicCastMember where id == id
196 }!
197
198 assert rows.len == 1
199 assert rows[0].name == next_name
200 assert rows[0].is_required == 1
201}
202
203fn test_dynamic_select_with_in_operator_and_additional_condition() {
204 mut db := sqlite.connect(':memory:')!
205 defer {
206 db.close() or { panic(err) }
207 }
208
209 sql db {
210 create table DynamicMember
211 }!
212
213 members := [
214 DynamicMember{
215 name: 'Alice'
216 email: '[email protected]'
217 age: 31
218 status: 'active'
219 },
220 DynamicMember{
221 name: 'Bob'
222 email: '[email protected]'
223 age: 24
224 status: 'pending'
225 },
226 DynamicMember{
227 name: 'Charlie'
228 email: '[email protected]'
229 age: 29
230 status: 'active'
231 },
232 DynamicMember{
233 name: 'Diana'
234 email: '[email protected]'
235 age: 35
236 status: 'inactive'
237 },
238 DynamicMember{
239 name: 'Eve'
240 email: '[email protected]'
241 age: 22
242 status: 'pending'
243 },
244 ]
245
246 for member in members {
247 sql db {
248 insert member into DynamicMember
249 }!
250 }
251
252 valid_names := ['Alice', 'Charlie', 'Eve']
253 min_age := 25
254
255 rows := sql db {
256 dynamic select from DynamicMember where {
257 if valid_names.len > 0 {
258 name in valid_names
259 },
260 if min_age > 0 {
261 age >= min_age
262 }
263 } order by id
264 }!
265
266 assert rows.len == 2
267 assert rows[0].name == 'Alice'
268 assert rows[0].age == 31
269 assert rows[1].name == 'Charlie'
270 assert rows[1].age == 29
271}
272
273fn test_dynamic_select_with_explicit_order_by_asc() {
274 mut db := sqlite.connect(':memory:')!
275 defer {
276 db.close() or { panic(err) }
277 }
278
279 sql db {
280 create table DynamicMember
281 }!
282
283 members := [
284 DynamicMember{
285 name: 'Alice'
286 email: '[email protected]'
287 age: 31
288 status: 'active'
289 },
290 DynamicMember{
291 name: 'Bob'
292 email: '[email protected]'
293 age: 19
294 status: 'pending'
295 },
296 DynamicMember{
297 name: 'Charlie'
298 email: '[email protected]'
299 age: 44
300 status: 'inactive'
301 },
302 ]
303
304 for member in members {
305 sql db {
306 insert member into DynamicMember
307 }!
308 }
309
310 min_age := 19
311 // vfmt off
312 rows := sql db {
313 dynamic select from DynamicMember where {
314 if min_age > 0 {
315 age >= min_age
316 }
317 } order by age asc limit 2
318 }!
319 // vfmt on
320
321 assert rows.len == 2
322 assert rows[0].name == 'Bob'
323 assert rows[0].age == 19
324 assert rows[1].name == 'Alice'
325 assert rows[1].age == 31
326}
327
328fn test_dynamic_select_where_block_with_or_expression() {
329 mut db := sqlite.connect(':memory:')!
330 defer {
331 db.close() or { panic(err) }
332 }
333
334 sql db {
335 create table DynamicOrMember
336 }!
337
338 members := [
339 DynamicOrMember{
340 id: 1
341 tenant_id: 1
342 name: 'Alice'
343 status: 'active'
344 },
345 DynamicOrMember{
346 id: 2
347 tenant_id: 2
348 name: 'Bob'
349 status: 'active'
350 },
351 DynamicOrMember{
352 id: 3
353 tenant_id: 2
354 name: 'Charlie'
355 status: 'pending'
356 },
357 DynamicOrMember{
358 id: 4
359 tenant_id: 3
360 name: 'Diana'
361 status: 'active'
362 },
363 ]
364
365 for member in members {
366 sql db {
367 insert member into DynamicOrMember
368 }!
369 }
370
371 active := 'active'
372 tenant_id := 2
373 rows := sql db {
374 dynamic select from DynamicOrMember where {
375 status == active && (name == 'Alice' || tenant_id == tenant_id)
376 } order by id
377 }!
378
379 assert rows.map(it.name) == ['Alice', 'Bob']
380
381 grouped_rows := sql db {
382 dynamic select from DynamicOrMember where {
383 (name == 'Alice' || status == active) && tenant_id == tenant_id
384 } order by id
385 }!
386
387 assert grouped_rows.map(it.name) == ['Bob']
388}
389
390fn test_dynamic_select_where_block_with_or_expression_and_comma_filter() {
391 mut db := sqlite.connect(':memory:')!
392 defer {
393 db.close() or { panic(err) }
394 }
395
396 sql db {
397 create table DynamicOrMember
398 }!
399
400 members := [
401 DynamicOrMember{
402 id: 1
403 tenant_id: 1
404 name: 'Alice'
405 status: 'active'
406 },
407 DynamicOrMember{
408 id: 2
409 tenant_id: 2
410 name: 'Bob'
411 status: 'active'
412 },
413 DynamicOrMember{
414 id: 3
415 tenant_id: 2
416 name: 'Charlie'
417 status: 'pending'
418 },
419 DynamicOrMember{
420 id: 4
421 tenant_id: 3
422 name: 'Diana'
423 status: 'active'
424 },
425 ]
426
427 for member in members {
428 sql db {
429 insert member into DynamicOrMember
430 }!
431 }
432
433 tenant_id := 2
434 rows := sql db {
435 dynamic select from DynamicOrMember where {
436 tenant_id == tenant_id,
437 name == 'Alice' || status == 'active'
438 } order by id
439 }!
440
441 assert rows.map(it.name) == ['Bob']
442}
443
444fn test_dynamic_update_where_block_with_or_expression() {
445 mut db := sqlite.connect(':memory:')!
446 defer {
447 db.close() or { panic(err) }
448 }
449
450 sql db {
451 create table DynamicOrMember
452 }!
453
454 members := [
455 DynamicOrMember{
456 id: 1
457 tenant_id: 1
458 name: 'Alice'
459 status: 'active'
460 },
461 DynamicOrMember{
462 id: 2
463 tenant_id: 2
464 name: 'Bob'
465 status: 'active'
466 },
467 DynamicOrMember{
468 id: 3
469 tenant_id: 2
470 name: 'Charlie'
471 status: 'pending'
472 },
473 DynamicOrMember{
474 id: 4
475 tenant_id: 3
476 name: 'Diana'
477 status: 'active'
478 },
479 ]
480
481 for member in members {
482 sql db {
483 insert member into DynamicOrMember
484 }!
485 }
486
487 next_status := 'archived'
488 update_expr := {
489 status == next_status
490 }
491 user_id := 1
492 tenant_id := 2
493
494 sql db {
495 dynamic update DynamicOrMember set update_expr where {
496 id == user_id || tenant_id == tenant_id
497 }
498 }!
499
500 rows := sql db {
501 select from DynamicOrMember order by id
502 }!
503
504 assert rows.map(it.status) == ['archived', 'archived', 'archived', 'active']
505}
506