v / vlib / orm / orm_fn_test.v
789 lines · 732 sloc · 20.41 KB · 7b724e98ac187e233bd03716901c29f5e00f815f
Raw
1// vtest retry: 3
2import orm
3
4fn test_orm_stmt_gen_update() {
5 table := orm.Table{
6 name: 'Test'
7 }
8 query_and, _ := orm.orm_stmt_gen(.default, table, "'", .update, true, '?', 0, orm.QueryData{
9 fields: ['test', 'a']
10 data: []
11 types: []
12 kinds: []
13 }, orm.QueryData{
14 fields: ['id', 'name']
15 data: []
16 types: []
17 kinds: [.ge, .eq]
18 is_and: [true]
19 })
20 assert query_and == "UPDATE 'Test' SET 'test' = ?0, 'a' = ?1 WHERE 'id' >= ?2 AND 'name' = ?3;"
21
22 query_or, _ := orm.orm_stmt_gen(.default, table, "'", .update, true, '?', 0, orm.QueryData{
23 fields: ['test', 'a']
24 data: []
25 types: []
26 kinds: []
27 }, orm.QueryData{
28 fields: ['id', 'name']
29 data: []
30 types: []
31 kinds: [.ge, .eq]
32 is_and: [false]
33 })
34 assert query_or == "UPDATE 'Test' SET 'test' = ?0, 'a' = ?1 WHERE 'id' >= ?2 OR 'name' = ?3;"
35}
36
37fn test_orm_stmt_gen_insert() {
38 table := orm.Table{
39 name: 'Test'
40 }
41 query, _ := orm.orm_stmt_gen(.default, table, "'", .insert, true, '?', 0, orm.QueryData{
42 fields: ['test', 'a']
43 data: []
44 types: []
45 kinds: []
46 }, orm.QueryData{})
47 assert query == "INSERT INTO 'Test' ('test', 'a') VALUES (?0, ?1);"
48}
49
50fn test_orm_stmt_gen_bulk_insert() {
51 table := orm.Table{
52 name: 'Test'
53 }
54 query, converted := orm.orm_stmt_gen(.default, table, "'", .insert, true, '?', 0, orm.QueryData{
55 fields: ['name', 'age']
56 data: [orm.Primitive('Alice'), orm.Primitive(25), orm.Primitive('Bob'), orm.Primitive(30)]
57 batch_rows: 2
58 }, orm.QueryData{})
59 assert query == "INSERT INTO 'Test' ('name', 'age') VALUES (?0, ?1), (?2, ?3);"
60 assert converted.data.len == 4
61
62 pg_query, _ := orm.orm_stmt_gen(.pg, table, '"', .insert, true, '$', 1, orm.QueryData{
63 fields: ['name', 'age']
64 data: [orm.Primitive('Alice'), orm.Primitive(25), orm.Primitive('Bob'), orm.Primitive(30)]
65 batch_rows: 2
66 }, orm.QueryData{})
67 assert pg_query == 'INSERT INTO "Test" ("name", "age") VALUES ($1, $2), ($3, $4);'
68
69 mysql_query, _ := orm.orm_stmt_gen(.mysql, table, '`', .insert, false, '?', 1, orm.QueryData{
70 fields: ['name', 'age']
71 data: [orm.Primitive('Alice'), orm.Primitive(25), orm.Primitive('Bob'), orm.Primitive(30)]
72 batch_rows: 2
73 }, orm.QueryData{})
74 assert mysql_query == 'INSERT INTO `Test` (`name`, `age`) VALUES (?, ?), (?, ?);'
75}
76
77fn test_orm_stmt_gen_bulk_update() {
78 table := orm.Table{
79 name: 'Test'
80 }
81 query, _ := orm.orm_stmt_gen(.default, table, "'", .update, true, '?', 0, orm.QueryData{
82 fields: ['name', 'age']
83 data: [orm.Primitive(1), orm.Primitive('Alice'), orm.Primitive(2), orm.Primitive('Bob'),
84 orm.Primitive(1), orm.Primitive(25), orm.Primitive(2), orm.Primitive(30)]
85 batch_rows: 2
86 batch_key: 'id'
87 }, orm.QueryData{
88 fields: ['id', 'id']
89 data: [orm.Primitive(1), orm.Primitive(2)]
90 kinds: [.eq, .eq]
91 is_and: [false]
92 })
93 assert query == "UPDATE 'Test' SET 'name' = CASE 'id' WHEN ?0 THEN ?1 WHEN ?2 THEN ?3 ELSE 'name' END, 'age' = CASE 'id' WHEN ?4 THEN ?5 WHEN ?6 THEN ?7 ELSE 'age' END WHERE 'id' = ?8 OR 'id' = ?9;"
94
95 pg_query, _ := orm.orm_stmt_gen(.pg, table, '"', .update, true, '$', 1, orm.QueryData{
96 fields: ['name']
97 data: [orm.Primitive(1), orm.Primitive('Alice'), orm.Primitive(2), orm.Primitive('Bob')]
98 batch_rows: 2
99 batch_key: 'id'
100 }, orm.QueryData{
101 fields: ['id', 'id']
102 data: [orm.Primitive(1), orm.Primitive(2)]
103 kinds: [.eq, .eq]
104 is_and: [false]
105 })
106 assert pg_query == 'UPDATE "Test" SET "name" = CASE "id" WHEN $1 THEN $2 WHEN $3 THEN $4 ELSE "name" END WHERE "id" = $5 OR "id" = $6;'
107
108 mysql_query, _ := orm.orm_stmt_gen(.mysql, table, '`', .update, false, '?', 1, orm.QueryData{
109 fields: ['name']
110 data: [orm.Primitive(1), orm.Primitive('Alice'), orm.Primitive(2), orm.Primitive('Bob')]
111 batch_rows: 2
112 batch_key: 'id'
113 }, orm.QueryData{
114 fields: ['id', 'id']
115 data: [orm.Primitive(1), orm.Primitive(2)]
116 kinds: [.eq, .eq]
117 is_and: [false]
118 })
119 assert mysql_query == 'UPDATE `Test` SET `name` = CASE `id` WHEN ? THEN ? WHEN ? THEN ? ELSE `name` END WHERE `id` = ? OR `id` = ?;'
120}
121
122fn test_orm_stmt_gen_insert_default_values_pg() {
123 table := orm.Table{
124 name: 'Test'
125 }
126 query, converted := orm.orm_stmt_gen(.pg, table, "'", .insert, true, '$', 1, orm.QueryData{
127 fields: ['id', 'example']
128 data: [orm.Primitive(0), orm.Primitive('')]
129 types: []
130 kinds: []
131 auto_fields: [0, 1]
132 }, orm.QueryData{})
133 assert query == "INSERT INTO 'Test' DEFAULT VALUES;"
134 assert converted.fields.len == 0
135 assert converted.data.len == 0
136}
137
138fn test_orm_stmt_gen_insert_default_values_mysql() {
139 table := orm.Table{
140 name: 'Test'
141 }
142 query, converted := orm.orm_stmt_gen(.mysql, table, '`', .insert, false, '?', 1, orm.QueryData{
143 fields: ['id']
144 data: [orm.Primitive(0)]
145 auto_fields: [0]
146 }, orm.QueryData{})
147 assert query == 'INSERT INTO `Test` () VALUES ();'
148 assert converted.fields.len == 0
149 assert converted.data.len == 0
150
151 bulk_query, bulk_converted := orm.orm_stmt_gen(.mysql, table, '`', .insert, false, '?', 1, orm.QueryData{
152 fields: ['id']
153 data: [orm.Primitive(0), orm.Primitive(0), orm.Primitive(0)]
154 auto_fields: [0]
155 batch_rows: 3
156 }, orm.QueryData{})
157 assert bulk_query == 'INSERT INTO `Test` () VALUES (), (), ();'
158 assert bulk_converted.fields.len == 0
159 assert bulk_converted.data.len == 0
160}
161
162fn test_orm_stmt_gen_h2_insert_default_values() {
163 table := orm.Table{
164 name: 'Test'
165 }
166 query, _ :=
167 orm.orm_stmt_gen(.h2, table, '"', .insert, false, '?', 1, orm.QueryData{}, orm.QueryData{})
168 assert query == 'INSERT INTO "Test" DEFAULT VALUES;'
169}
170
171fn test_orm_stmt_gen_delete() {
172 table := orm.Table{
173 name: 'Test'
174 }
175 query_and, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{
176 fields: ['test', 'a']
177 data: []
178 types: []
179 kinds: []
180 }, orm.QueryData{
181 fields: ['id', 'name']
182 data: []
183 types: []
184 kinds: [.ge, .eq]
185 is_and: [true]
186 })
187 assert query_and == "DELETE FROM 'Test' WHERE 'id' >= ?0 AND 'name' = ?1;"
188
189 query_or, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{
190 fields: ['test', 'a']
191 data: []
192 types: []
193 kinds: []
194 }, orm.QueryData{
195 fields: ['id', 'name']
196 data: []
197 types: []
198 kinds: [.ge, .eq]
199 is_and: [false]
200 })
201 assert query_or == "DELETE FROM 'Test' WHERE 'id' >= ?0 OR 'name' = ?1;"
202}
203
204fn test_orm_stmt_gen_where_unary_before_array() {
205 table := orm.Table{
206 name: 'Test'
207 }
208 query, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{}, orm.QueryData{
209 fields: ['deleted_at', 'tenant_id']
210 data: [orm.Primitive([orm.Primitive(1), orm.Primitive(2)])]
211 kinds: [.is_null, .in]
212 is_and: [true]
213 })
214 assert query == "DELETE FROM 'Test' WHERE 'deleted_at' IS NULL AND 'tenant_id' IN (?0, ?1);"
215}
216
217fn test_orm_stmt_gen_where_typed_array() {
218 table := orm.Table{
219 name: 'Test'
220 }
221 query, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{}, orm.QueryData{
222 fields: ['tenant_id']
223 data: [orm.Primitive([1, 2])]
224 kinds: [.in]
225 })
226 assert query == "DELETE FROM 'Test' WHERE 'tenant_id' IN (?0, ?1);"
227}
228
229fn get_select_fields() []string {
230 return ['id', 'test', 'abc']
231}
232
233fn test_orm_select_gen() {
234 query := orm.orm_select_gen(orm.SelectConfig{
235 table: orm.Table{
236 name: 'test_table'
237 }
238 fields: get_select_fields()
239 }, "'", true, '?', 0, orm.QueryData{})
240
241 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table';"
242}
243
244fn test_orm_select_gen_with_limit() {
245 query := orm.orm_select_gen(orm.SelectConfig{
246 table: orm.Table{
247 name: 'test_table'
248 }
249 fields: get_select_fields()
250 has_limit: true
251 }, "'", true, '?', 0, orm.QueryData{})
252
253 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' LIMIT ?0;"
254}
255
256fn test_orm_select_gen_with_where() {
257 query := orm.orm_select_gen(orm.SelectConfig{
258 table: orm.Table{
259 name: 'test_table'
260 }
261 fields: get_select_fields()
262 has_where: true
263 }, "'", true, '?', 0, orm.QueryData{
264 fields: ['abc', 'test']
265 kinds: [.eq, .gt]
266 is_and: [true]
267 })
268
269 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' WHERE 'abc' = ?0 AND 'test' > ?1;"
270}
271
272fn test_orm_select_gen_preserves_embedded_column_dot() {
273 query := orm.orm_select_gen(orm.SelectConfig{
274 table: orm.Table{
275 name: 'test_table'
276 }
277 fields: get_select_fields()
278 has_where: true
279 }, "'", true, '?', 0, orm.QueryData{
280 fields: ['Coordinates.latitude']
281 kinds: [.eq]
282 })
283
284 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' WHERE 'Coordinates.latitude' = ?0;"
285}
286
287fn test_orm_select_gen_with_order() {
288 query := orm.orm_select_gen(orm.SelectConfig{
289 table: orm.Table{
290 name: 'test_table'
291 }
292 fields: get_select_fields()
293 has_order: true
294 order_type: .desc
295 }, "'", true, '?', 0, orm.QueryData{})
296
297 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' ORDER BY '' DESC;"
298}
299
300fn test_orm_select_gen_with_offset() {
301 query := orm.orm_select_gen(orm.SelectConfig{
302 table: orm.Table{
303 name: 'test_table'
304 }
305 fields: get_select_fields()
306 has_offset: true
307 }, "'", true, '?', 0, orm.QueryData{})
308
309 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' OFFSET ?0;"
310}
311
312fn test_orm_select_gen_with_all() {
313 query := orm.orm_select_gen(orm.SelectConfig{
314 table: orm.Table{
315 name: 'test_table'
316 }
317 fields: get_select_fields()
318 has_limit: true
319 has_order: true
320 order_type: .desc
321 has_offset: true
322 has_where: true
323 }, "'", true, '?', 0, orm.QueryData{
324 fields: ['abc', 'test']
325 kinds: [.eq, .gt]
326 is_and: [true]
327 })
328
329 assert query == "SELECT 'id', 'test', 'abc' FROM 'test_table' WHERE 'abc' = ?0 AND 'test' > ?1 ORDER BY '' DESC LIMIT ?2 OFFSET ?3;"
330}
331
332fn test_orm_select_gen_with_distinct() {
333 query := orm.orm_select_gen(orm.SelectConfig{
334 table: orm.Table{
335 name: 'test_table'
336 }
337 fields: get_select_fields()
338 has_distinct: true
339 }, "'", true, '?', 0, orm.QueryData{})
340
341 assert query == "SELECT DISTINCT 'id', 'test', 'abc' FROM 'test_table';"
342}
343
344fn test_orm_select_gen_with_distinct_and_where() {
345 query := orm.orm_select_gen(orm.SelectConfig{
346 table: orm.Table{
347 name: 'test_table'
348 }
349 fields: get_select_fields()
350 has_distinct: true
351 has_where: true
352 }, "'", true, '?', 0, orm.QueryData{
353 fields: ['abc']
354 kinds: [.eq]
355 is_and: []
356 })
357
358 assert query == "SELECT DISTINCT 'id', 'test', 'abc' FROM 'test_table' WHERE 'abc' = ?0;"
359}
360
361fn test_orm_select_gen_with_sum() {
362 query := orm.orm_select_gen(orm.SelectConfig{
363 table: orm.Table{
364 name: 'test_table'
365 }
366 aggregate_kind: .sum
367 aggregate_field: 'age'
368 fields: ['age']
369 types: [orm.type_idx['int']]
370 }, "'", true, '?', 0, orm.QueryData{})
371
372 assert query == "SELECT SUM('age') FROM 'test_table';"
373}
374
375fn test_orm_select_gen_with_avg_and_where() {
376 query := orm.orm_select_gen(orm.SelectConfig{
377 table: orm.Table{
378 name: 'test_table'
379 }
380 aggregate_kind: .avg
381 aggregate_field: 'score'
382 fields: ['score']
383 types: [orm.type_idx['f64']]
384 has_where: true
385 }, "'", true, '?', 0, orm.QueryData{
386 fields: ['abc']
387 kinds: [.eq]
388 is_and: []
389 })
390
391 assert query == "SELECT AVG('score') FROM 'test_table' WHERE 'abc' = ?0;"
392}
393
394fn test_orm_select_gen_with_count() {
395 query := orm.orm_select_gen(orm.SelectConfig{
396 table: orm.Table{
397 name: 'test_table'
398 }
399 aggregate_kind: .count
400 types: [orm.type_idx['int']]
401 }, "'", true, '?', 0, orm.QueryData{})
402
403 assert query == "SELECT COUNT(*) FROM 'test_table';"
404}
405
406fn test_orm_table_gen() {
407 table := orm.Table{
408 name: 'test_table'
409 }
410 query := orm.orm_table_gen(.default, table, "'", true, 0, [
411 orm.TableField{
412 name: 'id'
413 typ: typeof[int]().idx
414 default_val: '10'
415 nullable: true
416 attrs: [
417 VAttribute{
418 name: 'primary'
419 },
420 VAttribute{
421 name: 'sql'
422 has_arg: true
423 arg: 'serial'
424 kind: .plain
425 },
426 ]
427 },
428 orm.TableField{
429 name: 'test'
430 typ: typeof[string]().idx
431 nullable: true
432 },
433 orm.TableField{
434 name: 'abc'
435 typ: typeof[i64]().idx
436 nullable: true
437 default_val: '6754'
438 },
439 ], sql_type_from_v, false) or { panic(err) }
440 assert query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
441
442 alt_query := orm.orm_table_gen(.default, table, "'", true, 0, [
443 orm.TableField{
444 name: 'id'
445 typ: typeof[int]().idx
446 nullable: true
447 default_val: '10'
448 attrs: [
449 VAttribute{
450 name: 'primary'
451 },
452 VAttribute{
453 name: 'sql'
454 has_arg: true
455 arg: 'serial'
456 kind: .plain
457 },
458 ]
459 },
460 orm.TableField{
461 name: 'test'
462 typ: typeof[string]().idx
463 nullable: true
464 },
465 orm.TableField{
466 name: 'abc'
467 typ: typeof[i64]().idx
468 nullable: true
469 default_val: '6754'
470 },
471 ], sql_type_from_v, true) or { panic(err) }
472 assert alt_query == "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='test_table' and xtype='U') CREATE TABLE 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
473
474 unique_query := orm.orm_table_gen(.default, table, "'", true, 0, [
475 orm.TableField{
476 name: 'id'
477 typ: typeof[int]().idx
478 nullable: true
479 default_val: '10'
480 attrs: [
481 VAttribute{
482 name: 'primary'
483 },
484 VAttribute{
485 name: 'sql'
486 has_arg: true
487 arg: 'serial'
488 kind: .plain
489 },
490 ]
491 },
492 orm.TableField{
493 name: 'test'
494 typ: typeof[string]().idx
495 attrs: [
496 VAttribute{
497 name: 'unique'
498 },
499 ]
500 },
501 orm.TableField{
502 name: 'abc'
503 typ: typeof[i64]().idx
504 default_val: '6754'
505 },
506 ], sql_type_from_v, false) or { panic(err) }
507 assert unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT NOT NULL, 'abc' INT64 DEFAULT 6754 NOT NULL, PRIMARY KEY('id'), UNIQUE('test'));"
508
509 mult_unique_query := orm.orm_table_gen(.default, table, "'", true, 0, [
510 orm.TableField{
511 name: 'id'
512 typ: typeof[int]().idx
513 nullable: true
514 default_val: '10'
515 attrs: [
516 VAttribute{
517 name: 'primary'
518 },
519 VAttribute{
520 name: 'sql'
521 has_arg: true
522 arg: 'serial'
523 kind: .plain
524 },
525 ]
526 },
527 orm.TableField{
528 name: 'test'
529 typ: typeof[string]().idx
530 nullable: true
531 attrs: [
532 VAttribute{
533 name: 'unique'
534 has_arg: true
535 arg: 'test'
536 kind: .string
537 },
538 ]
539 },
540 orm.TableField{
541 name: 'abc'
542 typ: typeof[i64]().idx
543 nullable: true
544 default_val: '6754'
545 attrs: [
546 VAttribute{
547 name: 'unique'
548 has_arg: true
549 arg: 'test'
550 kind: .string
551 },
552 ]
553 },
554 ], sql_type_from_v, false) or { panic(err) }
555 assert mult_unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, /* test */UNIQUE('test', 'abc'), PRIMARY KEY('id'));"
556
557 table_with_unique := orm.Table{
558 name: 'test_table'
559 attrs: [
560 VAttribute{
561 name: 'unique_key'
562 has_arg: true
563 arg: 'test, abc'
564 kind: .string
565 },
566 ]
567 }
568 table_unique_query := orm.orm_table_gen(.default, table_with_unique, "'", true, 0, [
569 orm.TableField{
570 name: 'id'
571 typ: typeof[int]().idx
572 nullable: true
573 default_val: '10'
574 attrs: [
575 VAttribute{
576 name: 'primary'
577 },
578 VAttribute{
579 name: 'sql'
580 has_arg: true
581 arg: 'serial'
582 kind: .plain
583 },
584 ]
585 },
586 orm.TableField{
587 name: 'test'
588 typ: typeof[string]().idx
589 nullable: true
590 },
591 orm.TableField{
592 name: 'abc'
593 typ: typeof[i64]().idx
594 nullable: true
595 default_val: '6754'
596 },
597 ], sql_type_from_v, false) or { panic(err) }
598 assert table_unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, UNIQUE('test', 'abc'), PRIMARY KEY('id'));"
599}
600
601fn test_orm_table_gen_h2() {
602 table := orm.Table{
603 name: 'test_table'
604 attrs: [
605 VAttribute{
606 name: 'comment'
607 has_arg: true
608 arg: 'test table'
609 kind: .string
610 },
611 ]
612 }
613 query := orm.orm_table_gen(.h2, table, '"', true, 0, [
614 orm.TableField{
615 name: 'id'
616 typ: typeof[int]().idx
617 attrs: [
618 VAttribute{
619 name: 'primary'
620 },
621 VAttribute{
622 name: 'sql'
623 has_arg: true
624 arg: 'serial'
625 kind: .plain
626 },
627 ]
628 },
629 orm.TableField{
630 name: 'name'
631 typ: typeof[string]().idx
632 attrs: [
633 VAttribute{
634 name: 'comment'
635 has_arg: true
636 arg: 'display name'
637 kind: .string
638 },
639 VAttribute{
640 name: 'index'
641 },
642 ]
643 },
644 ], sql_type_from_v, false) or { panic(err) }
645 assert query == 'CREATE TABLE IF NOT EXISTS "test_table" ("id" SERIAL NOT NULL, "name" TEXT NOT NULL, PRIMARY KEY("id"));\nCOMMENT ON TABLE "test_table" IS \'test table\';\nCOMMENT ON COLUMN "test_table"."name" IS \'display name\';\nCREATE INDEX "idx_test_table" ON "test_table" ("name");'
646}
647
648fn reset_tenant_filter() {
649 orm.configure_tenant_filter(enabled: false, field_name: 'tenant_id')
650 orm.clear_current_tenant_id()
651}
652
653fn test_apply_tenant_filter_appends_default_field() {
654 defer {
655 reset_tenant_filter()
656 }
657 reset_tenant_filter()
658 orm.configure_tenant_filter(field_name: 'tenant_id')
659 orm.set_current_tenant_id(77)
660 where := orm.QueryData{
661 fields: ['id']
662 data: [orm.Primitive(int(11))]
663 kinds: [.eq]
664 }
665 filtered := orm.apply_tenant_filter(orm.Table{
666 name: 'test_table'
667 }, where)
668 assert filtered.fields == ['id', 'tenant_id']
669 assert filtered.data == [orm.Primitive(int(11)), orm.Primitive(int(77))]
670 assert filtered.kinds == [.eq, .eq]
671 assert filtered.is_and == [true]
672}
673
674fn test_apply_tenant_filter_does_not_duplicate_existing_field() {
675 defer {
676 reset_tenant_filter()
677 }
678 reset_tenant_filter()
679 orm.configure_tenant_filter(field_name: 'tenant_id')
680 orm.set_current_tenant_id(77)
681 where := orm.QueryData{
682 fields: ['tenant_id']
683 data: [orm.Primitive(int(11))]
684 kinds: [.eq]
685 }
686 filtered := orm.apply_tenant_filter(orm.Table{
687 name: 'test_table'
688 }, where)
689 assert filtered.fields == ['tenant_id']
690 assert filtered.data == [orm.Primitive(int(11))]
691 assert filtered.kinds == [.eq]
692 assert filtered.is_and == []
693}
694
695fn test_apply_tenant_filter_with_table_override_and_ignore() {
696 defer {
697 reset_tenant_filter()
698 }
699 reset_tenant_filter()
700 orm.configure_tenant_filter(field_name: 'tenant_id')
701 orm.set_current_tenant_id(5)
702 with_override := orm.apply_tenant_filter(orm.Table{
703 name: 'test_table'
704 attrs: [
705 VAttribute{
706 name: 'tenant_field'
707 has_arg: true
708 arg: 'company_id'
709 kind: .string
710 },
711 ]
712 }, orm.QueryData{})
713 assert with_override.fields == ['company_id']
714 assert with_override.data == [orm.Primitive(int(5))]
715 ignored := orm.apply_tenant_filter(orm.Table{
716 name: 'test_table'
717 attrs: [
718 VAttribute{
719 name: 'ignore_tenant_filter'
720 },
721 ]
722 }, orm.QueryData{})
723 assert ignored.fields == []
724 assert ignored.data == []
725}
726
727fn test_apply_tenant_filter_wraps_existing_where_clause() {
728 defer {
729 reset_tenant_filter()
730 }
731 reset_tenant_filter()
732 orm.configure_tenant_filter(field_name: 'tenant_id')
733 orm.set_current_tenant_id(42)
734 filtered := orm.apply_tenant_filter(orm.Table{
735 name: 'test_table'
736 }, orm.QueryData{
737 fields: ['a', 'b']
738 kinds: [.eq, .eq]
739 is_and: [false]
740 })
741 assert filtered.fields == ['a', 'b', 'tenant_id']
742 assert filtered.is_and == [false, true]
743 assert filtered.parentheses.len == 1
744 assert filtered.parentheses[0] == [0, 1]
745}
746
747fn test_without_tenant_filter_and_with_tenant() {
748 defer {
749 reset_tenant_filter()
750 }
751 reset_tenant_filter()
752 orm.configure_tenant_filter(field_name: 'tenant_id')
753 orm.set_current_tenant_id(10)
754 without_filter := orm.without_tenant_filter[orm.QueryData](fn () !orm.QueryData {
755 return orm.apply_tenant_filter(orm.Table{
756 name: 'test_table'
757 }, orm.QueryData{})
758 }) or { panic(err) }
759 assert without_filter.fields == []
760
761 with_override := orm.with_tenant[orm.QueryData](22, fn () !orm.QueryData {
762 return orm.apply_tenant_filter(orm.Table{
763 name: 'test_table'
764 }, orm.QueryData{})
765 }) or { panic(err) }
766 assert with_override.fields == ['tenant_id']
767 assert with_override.data == [orm.Primitive(int(22))]
768
769 after_scope := orm.apply_tenant_filter(orm.Table{
770 name: 'test_table'
771 }, orm.QueryData{})
772 assert after_scope.data == [orm.Primitive(int(10))]
773}
774
775fn sql_type_from_v(typ int) !string {
776 return if typ in orm.nums {
777 'INT'
778 } else if typ in orm.num64 {
779 'INT64'
780 } else if typ in orm.float {
781 'DOUBLE'
782 } else if typ == orm.type_string {
783 'TEXT'
784 } else if typ == orm.serial {
785 'SERIAL'
786 } else {
787 error('Unknown type ${typ}')
788 }
789}
790