@simplysm/orm-common 13.0.75 → 13.0.77

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.
Files changed (135) hide show
  1. package/README.md +575 -50
  2. package/dist/create-db-context.d.ts +1 -1
  3. package/dist/create-db-context.d.ts.map +1 -1
  4. package/dist/create-db-context.js +34 -27
  5. package/dist/create-db-context.js.map +1 -1
  6. package/dist/ddl/initialize.js +4 -4
  7. package/dist/ddl/initialize.js.map +1 -1
  8. package/dist/ddl/relation-ddl.d.ts +7 -7
  9. package/dist/ddl/relation-ddl.d.ts.map +1 -1
  10. package/dist/ddl/relation-ddl.js +18 -18
  11. package/dist/ddl/relation-ddl.js.map +1 -1
  12. package/dist/ddl/schema-ddl.d.ts +1 -1
  13. package/dist/ddl/schema-ddl.d.ts.map +1 -1
  14. package/dist/ddl/schema-ddl.js +2 -2
  15. package/dist/ddl/schema-ddl.js.map +1 -1
  16. package/dist/ddl/table-ddl.js +2 -2
  17. package/dist/ddl/table-ddl.js.map +1 -1
  18. package/dist/exec/queryable.d.ts +24 -24
  19. package/dist/exec/queryable.d.ts.map +1 -1
  20. package/dist/exec/queryable.js +37 -37
  21. package/dist/exec/queryable.js.map +1 -1
  22. package/dist/expr/expr-unit.js +1 -1
  23. package/dist/expr/expr-unit.js.map +1 -1
  24. package/dist/expr/expr.d.ts +9 -9
  25. package/dist/expr/expr.d.ts.map +1 -1
  26. package/dist/expr/expr.js +10 -10
  27. package/dist/expr/expr.js.map +1 -1
  28. package/dist/query-builder/base/expr-renderer-base.d.ts +2 -2
  29. package/dist/query-builder/base/expr-renderer-base.d.ts.map +1 -1
  30. package/dist/query-builder/base/query-builder-base.d.ts +7 -15
  31. package/dist/query-builder/base/query-builder-base.d.ts.map +1 -1
  32. package/dist/query-builder/base/query-builder-base.js +2 -2
  33. package/dist/query-builder/base/query-builder-base.js.map +1 -1
  34. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +4 -4
  35. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
  36. package/dist/query-builder/mssql/mssql-expr-renderer.js +8 -8
  37. package/dist/query-builder/mssql/mssql-expr-renderer.js.map +1 -1
  38. package/dist/query-builder/mssql/mssql-query-builder.d.ts +7 -7
  39. package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
  40. package/dist/query-builder/mssql/mssql-query-builder.js +7 -7
  41. package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -1
  42. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +4 -4
  43. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
  44. package/dist/query-builder/mysql/mysql-expr-renderer.js +9 -9
  45. package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -1
  46. package/dist/query-builder/mysql/mysql-query-builder.d.ts +7 -7
  47. package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
  48. package/dist/query-builder/mysql/mysql-query-builder.js +11 -11
  49. package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -1
  50. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +4 -4
  51. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
  52. package/dist/query-builder/postgresql/postgresql-expr-renderer.js +8 -8
  53. package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -1
  54. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +7 -7
  55. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
  56. package/dist/query-builder/postgresql/postgresql-query-builder.js +7 -7
  57. package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -1
  58. package/dist/schema/procedure-builder.d.ts +1 -1
  59. package/dist/schema/table-builder.d.ts +1 -1
  60. package/dist/schema/table-builder.d.ts.map +1 -1
  61. package/dist/schema/table-builder.js +1 -1
  62. package/dist/schema/view-builder.d.ts +1 -1
  63. package/dist/schema/view-builder.d.ts.map +1 -1
  64. package/dist/schema/view-builder.js +1 -1
  65. package/dist/types/db-context-def.d.ts +18 -18
  66. package/dist/types/db-context-def.d.ts.map +1 -1
  67. package/dist/types/expr.d.ts +6 -6
  68. package/dist/types/expr.d.ts.map +1 -1
  69. package/dist/types/query-def.d.ts +15 -15
  70. package/dist/types/query-def.d.ts.map +1 -1
  71. package/dist/types/query-def.js +6 -6
  72. package/dist/utils/result-parser.d.ts.map +1 -1
  73. package/dist/utils/result-parser.js +44 -16
  74. package/dist/utils/result-parser.js.map +1 -1
  75. package/package.json +2 -2
  76. package/src/create-db-context.ts +36 -29
  77. package/src/ddl/initialize.ts +4 -4
  78. package/src/ddl/relation-ddl.ts +16 -16
  79. package/src/ddl/schema-ddl.ts +2 -2
  80. package/src/ddl/table-ddl.ts +2 -2
  81. package/src/exec/queryable.ts +58 -58
  82. package/src/expr/expr-unit.ts +1 -1
  83. package/src/expr/expr.ts +13 -13
  84. package/src/query-builder/base/expr-renderer-base.ts +2 -2
  85. package/src/query-builder/base/query-builder-base.ts +18 -14
  86. package/src/query-builder/mssql/mssql-expr-renderer.ts +11 -10
  87. package/src/query-builder/mssql/mssql-query-builder.ts +13 -13
  88. package/src/query-builder/mysql/mysql-expr-renderer.ts +12 -11
  89. package/src/query-builder/mysql/mysql-query-builder.ts +17 -17
  90. package/src/query-builder/postgresql/postgresql-expr-renderer.ts +11 -10
  91. package/src/query-builder/postgresql/postgresql-query-builder.ts +13 -13
  92. package/src/schema/procedure-builder.ts +1 -1
  93. package/src/schema/table-builder.ts +1 -1
  94. package/src/schema/view-builder.ts +1 -1
  95. package/src/types/db-context-def.ts +18 -18
  96. package/src/types/expr.ts +6 -6
  97. package/src/types/query-def.ts +31 -31
  98. package/src/utils/result-parser.ts +60 -16
  99. package/tests/db-context/create-db-context.spec.ts +6 -37
  100. package/tests/db-context/define-db-context.spec.ts +0 -51
  101. package/tests/ddl/basic.expected.ts +8 -8
  102. package/tests/ddl/basic.spec.ts +24 -181
  103. package/tests/ddl/column-builder.spec.ts +0 -112
  104. package/tests/ddl/index-builder.spec.ts +10 -64
  105. package/tests/ddl/procedure-builder.spec.ts +0 -106
  106. package/tests/ddl/relation-builder.spec.ts +4 -205
  107. package/tests/ddl/table-builder.spec.ts +0 -34
  108. package/tests/ddl/view-builder.spec.ts +0 -60
  109. package/tests/dml/delete.spec.ts +0 -33
  110. package/tests/dml/insert.spec.ts +0 -78
  111. package/tests/dml/update.spec.ts +2 -98
  112. package/tests/dml/upsert.spec.ts +0 -52
  113. package/tests/errors/queryable-errors.spec.ts +0 -51
  114. package/tests/escape.spec.ts +0 -41
  115. package/tests/examples/pivot.spec.ts +0 -333
  116. package/tests/examples/sampling.spec.ts +0 -63
  117. package/tests/examples/unpivot.spec.ts +0 -65
  118. package/tests/exec/search-parser.spec.ts +0 -16
  119. package/tests/expr/comparison.spec.ts +0 -66
  120. package/tests/expr/conditional.expected.ts +2 -2
  121. package/tests/expr/conditional.spec.ts +8 -35
  122. package/tests/expr/date.spec.ts +5 -72
  123. package/tests/expr/math.spec.ts +0 -47
  124. package/tests/expr/string.spec.ts +0 -56
  125. package/tests/expr/utility.spec.ts +0 -27
  126. package/tests/select/basic.spec.ts +5 -74
  127. package/tests/select/filter.spec.ts +0 -114
  128. package/tests/select/group.spec.ts +0 -85
  129. package/tests/select/join.spec.ts +0 -113
  130. package/tests/select/order.spec.ts +0 -49
  131. package/tests/select/subquery.spec.ts +0 -96
  132. package/tests/select/window.spec.ts +0 -185
  133. package/tests/types/nullable-queryable-record.spec.ts +0 -48
  134. package/tests/utils/result-parser-perf.spec.ts +0 -67
  135. package/tests/utils/result-parser.spec.ts +4 -38
@@ -279,64 +279,6 @@ describe("SELECT - UNION", () => {
279
279
  });
280
280
  });
281
281
 
282
- describe("3 or more", () => {
283
- const db = createTestDb();
284
- const qr1 = db.user().where((item) => [expr.eq(item.age, 20)]);
285
- const qr2 = db.user().where((item) => [expr.eq(item.age, 30)]);
286
- const qr3 = db.user().where((item) => [expr.eq(item.age, 40)]);
287
- const def = Queryable.union(qr1, qr2, qr3).getSelectQueryDef();
288
-
289
- it("Verify QueryDef", () => {
290
- expect(def).toEqual({
291
- type: "select",
292
- as: "T4",
293
- from: [
294
- {
295
- type: "select",
296
- as: "T1",
297
- from: { database: "TestDb", schema: "TestSchema", name: "User" },
298
- where: [
299
- {
300
- type: "eq",
301
- source: { type: "column", path: ["T1", "age"] },
302
- target: { type: "value", value: 20 },
303
- },
304
- ],
305
- },
306
- {
307
- type: "select",
308
- as: "T2",
309
- from: { database: "TestDb", schema: "TestSchema", name: "User" },
310
- where: [
311
- {
312
- type: "eq",
313
- source: { type: "column", path: ["T2", "age"] },
314
- target: { type: "value", value: 30 },
315
- },
316
- ],
317
- },
318
- {
319
- type: "select",
320
- as: "T3",
321
- from: { database: "TestDb", schema: "TestSchema", name: "User" },
322
- where: [
323
- {
324
- type: "eq",
325
- source: { type: "column", path: ["T3", "age"] },
326
- target: { type: "value", value: 40 },
327
- },
328
- ],
329
- },
330
- ],
331
- });
332
- });
333
-
334
- it.each(dialects)("[%s] Verify SQL", (dialect) => {
335
- const builder = createQueryBuilder(dialect);
336
- expect(builder.build(def)).toMatchSql(expected.unionThree[dialect]);
337
- });
338
- });
339
-
340
282
  describe("UNION -> WHERE (apply to each query)", () => {
341
283
  const db = createTestDb();
342
284
  const qr1 = db.user();
@@ -439,44 +381,6 @@ describe("SELECT - UNION", () => {
439
381
  });
440
382
  });
441
383
 
442
- describe("UNION -> SELECT", () => {
443
- const db = createTestDb();
444
- const qr1 = db.user().select((item) => ({ id: item.id, name: item.name }));
445
- const qr2 = db.user().select((item) => ({ id: item.id, name: item.name }));
446
- const def = Queryable.union(qr1, qr2).getSelectQueryDef();
447
-
448
- it("Verify QueryDef", () => {
449
- expect(def).toEqual({
450
- type: "select",
451
- as: "T3",
452
- from: [
453
- {
454
- type: "select",
455
- as: "T1",
456
- from: { database: "TestDb", schema: "TestSchema", name: "User" },
457
- select: {
458
- id: { type: "column", path: ["T1", "id"] },
459
- name: { type: "column", path: ["T1", "name"] },
460
- },
461
- },
462
- {
463
- type: "select",
464
- as: "T2",
465
- from: { database: "TestDb", schema: "TestSchema", name: "User" },
466
- select: {
467
- id: { type: "column", path: ["T2", "id"] },
468
- name: { type: "column", path: ["T2", "name"] },
469
- },
470
- },
471
- ],
472
- });
473
- });
474
-
475
- it.each(dialects)("[%s] Verify SQL", (dialect) => {
476
- const builder = createQueryBuilder(dialect);
477
- expect(builder.build(def)).toMatchSql(expected.unionThenSelect[dialect]);
478
- });
479
- });
480
384
  });
481
385
 
482
386
  //#region ========== SCALAR SUBQUERY ==========
@@ -57,25 +57,6 @@ describe("SELECT - Window Functions", () => {
57
57
  }))
58
58
  .getSelectQueryDef();
59
59
 
60
- it("Verify QueryDef", () => {
61
- expect(def).toEqual({
62
- type: "select",
63
- as: "T1",
64
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
65
- select: {
66
- id: { type: "column", path: ["T1", "id"] },
67
- name: { type: "column", path: ["T1", "name"] },
68
- rank: {
69
- type: "window",
70
- fn: { type: "rank" },
71
- spec: {
72
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "DESC"]],
73
- },
74
- },
75
- },
76
- });
77
- });
78
-
79
60
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
80
61
  const builder = createQueryBuilder(dialect);
81
62
  expect(builder.build(def)).toMatchSql(expected.rank[dialect]);
@@ -92,24 +73,6 @@ describe("SELECT - Window Functions", () => {
92
73
  }))
93
74
  .getSelectQueryDef();
94
75
 
95
- it("Verify QueryDef", () => {
96
- expect(def).toEqual({
97
- type: "select",
98
- as: "T1",
99
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
100
- select: {
101
- id: { type: "column", path: ["T1", "id"] },
102
- denseRank: {
103
- type: "window",
104
- fn: { type: "denseRank" },
105
- spec: {
106
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "DESC"]],
107
- },
108
- },
109
- },
110
- });
111
- });
112
-
113
76
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
114
77
  const builder = createQueryBuilder(dialect);
115
78
  expect(builder.build(def)).toMatchSql(expected.denseRank[dialect]);
@@ -205,28 +168,6 @@ describe("SELECT - Window Functions", () => {
205
168
  }))
206
169
  .getSelectQueryDef();
207
170
 
208
- it("Verify QueryDef", () => {
209
- expect(def).toEqual({
210
- type: "select",
211
- as: "T1",
212
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
213
- select: {
214
- id: { type: "column", path: ["T1", "id"] },
215
- nextId: {
216
- type: "window",
217
- fn: {
218
- type: "lead",
219
- column: { type: "column", path: ["T1", "id"] },
220
- offset: 1,
221
- },
222
- spec: {
223
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "ASC"]],
224
- },
225
- },
226
- },
227
- });
228
- });
229
-
230
171
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
231
172
  const builder = createQueryBuilder(dialect);
232
173
  expect(builder.build(def)).toMatchSql(expected.lead[dialect]);
@@ -282,29 +223,6 @@ describe("SELECT - Window Functions", () => {
282
223
  }))
283
224
  .getSelectQueryDef();
284
225
 
285
- it("Verify QueryDef", () => {
286
- expect(def).toEqual({
287
- type: "select",
288
- as: "T1",
289
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
290
- select: {
291
- id: { type: "column", path: ["T1", "id"] },
292
- nextId: {
293
- type: "window",
294
- fn: {
295
- type: "lead",
296
- column: { type: "column", path: ["T1", "id"] },
297
- offset: 1,
298
- default: { type: "value", value: -1 },
299
- },
300
- spec: {
301
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "ASC"]],
302
- },
303
- },
304
- },
305
- });
306
- });
307
-
308
226
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
309
227
  const builder = createQueryBuilder(dialect);
310
228
  expect(builder.build(def)).toMatchSql(expected.leadWithDefault[dialect]);
@@ -362,27 +280,6 @@ describe("SELECT - Window Functions", () => {
362
280
  }))
363
281
  .getSelectQueryDef();
364
282
 
365
- it("Verify QueryDef", () => {
366
- expect(def).toEqual({
367
- type: "select",
368
- as: "T1",
369
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
370
- select: {
371
- id: { type: "column", path: ["T1", "id"] },
372
- avgId: {
373
- type: "window",
374
- fn: {
375
- type: "avg",
376
- column: { type: "column", path: ["T1", "id"] },
377
- },
378
- spec: {
379
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
380
- },
381
- },
382
- },
383
- });
384
- });
385
-
386
283
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
387
284
  const builder = createQueryBuilder(dialect);
388
285
  expect(builder.build(def)).toMatchSql(expected.avgOver[dialect]);
@@ -496,46 +393,6 @@ describe("SELECT - Window Functions", () => {
496
393
  }))
497
394
  .getSelectQueryDef();
498
395
 
499
- it("Verify QueryDef", () => {
500
- expect(def).toEqual({
501
- type: "select",
502
- as: "T1",
503
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
504
- select: {
505
- id: { type: "column", path: ["T1", "id"] },
506
- name: { type: "column", path: ["T1", "name"] },
507
- rowNum: {
508
- type: "window",
509
- fn: { type: "rowNumber" },
510
- spec: {
511
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
512
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "ASC"]],
513
- },
514
- },
515
- rank: {
516
- type: "window",
517
- fn: { type: "rank" },
518
- spec: {
519
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
520
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "DESC"]],
521
- },
522
- },
523
- prevName: {
524
- type: "window",
525
- fn: {
526
- type: "lag",
527
- column: { type: "column", path: ["T1", "name"] },
528
- offset: 1,
529
- },
530
- spec: {
531
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
532
- orderBy: [[{ type: "column", path: ["T1", "id"] }, "ASC"]],
533
- },
534
- },
535
- },
536
- });
537
- });
538
-
539
396
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
540
397
  const builder = createQueryBuilder(dialect);
541
398
  expect(builder.build(def)).toMatchSql(expected.combined[dialect]);
@@ -552,27 +409,6 @@ describe("SELECT - Window Functions", () => {
552
409
  }))
553
410
  .getSelectQueryDef();
554
411
 
555
- it("Verify QueryDef", () => {
556
- expect(def).toEqual({
557
- type: "select",
558
- as: "T1",
559
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
560
- select: {
561
- id: { type: "column", path: ["T1", "id"] },
562
- minId: {
563
- type: "window",
564
- fn: {
565
- type: "min",
566
- column: { type: "column", path: ["T1", "id"] },
567
- },
568
- spec: {
569
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
570
- },
571
- },
572
- },
573
- });
574
- });
575
-
576
412
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
577
413
  const builder = createQueryBuilder(dialect);
578
414
  expect(builder.build(def)).toMatchSql(expected.minOver[dialect]);
@@ -589,27 +425,6 @@ describe("SELECT - Window Functions", () => {
589
425
  }))
590
426
  .getSelectQueryDef();
591
427
 
592
- it("Verify QueryDef", () => {
593
- expect(def).toEqual({
594
- type: "select",
595
- as: "T1",
596
- from: { database: "TestDb", schema: "TestSchema", name: "Employee" },
597
- select: {
598
- id: { type: "column", path: ["T1", "id"] },
599
- maxId: {
600
- type: "window",
601
- fn: {
602
- type: "max",
603
- column: { type: "column", path: ["T1", "id"] },
604
- },
605
- spec: {
606
- partitionBy: [{ type: "column", path: ["T1", "departmentId"] }],
607
- },
608
- },
609
- },
610
- });
611
- });
612
-
613
428
  it.each(dialects)("[%s] Verify SQL", (dialect) => {
614
429
  const builder = createQueryBuilder(dialect);
615
430
  expect(builder.build(def)).toMatchSql(expected.maxOver[dialect]);
@@ -31,21 +31,6 @@ describe("NullableQueryableRecord type inference", () => {
31
31
  expect(q).toBeDefined();
32
32
  });
33
33
 
34
- it("non-optional relation (required object) fields should remain ExprUnit<T>", () => {
35
- const db = createTestDb();
36
- const q = db.post().select((item) => ({
37
- title: item.title,
38
- viewCount: item.viewCount,
39
- }));
40
-
41
- type Result = typeof q extends { meta: { columns: infer C } } ? C : never;
42
- type TitleType = Result extends { title: { $infer: infer T } } ? T : never;
43
-
44
- expectTypeOf<TitleType>().toEqualTypeOf<string>();
45
-
46
- expect(q).toBeDefined();
47
- });
48
-
49
34
  it("QueryableRecord preserves optional modifier (for select output)", () => {
50
35
  type OptionalData = { id?: number; name: string };
51
36
  type Result = QueryableRecord<OptionalData>;
@@ -57,17 +42,6 @@ describe("NullableQueryableRecord type inference", () => {
57
42
  expect(true).toBe(true);
58
43
  });
59
44
 
60
- it("QueryableRecord preserves optional modifier for write operations", () => {
61
- type OptionalData = { id?: number; name: string };
62
- type WriteResult = QueryableRecord<OptionalData>;
63
-
64
- // QueryableRecord preserves optional keys (for update/insert operations)
65
- expectTypeOf<Required<WriteResult>["id"]>().toMatchTypeOf<{ $infer: number | undefined }>();
66
- expectTypeOf<WriteResult["name"]>().toMatchTypeOf<{ $infer: string }>();
67
-
68
- expect(true).toBe(true);
69
- });
70
-
71
45
  it("select auto-infers result type from callback return", () => {
72
46
  const db = createTestDb();
73
47
 
@@ -109,28 +83,6 @@ describe("NullableQueryableRecord type inference", () => {
109
83
  expect(true).toBe(true);
110
84
  });
111
85
 
112
- it("select with optional properties then orderBy should compile", () => {
113
- const db = createTestDb();
114
-
115
- /*type IUserItem = {
116
- id?: number;
117
- name?: string;
118
- isActive: boolean;
119
- };*/
120
-
121
- const q = db
122
- .user()
123
- .where((u) => [expr.eq(u.isActive, true)])
124
- .select((c) => ({
125
- id: c.id,
126
- name: c.name,
127
- isActive: c.isActive,
128
- }))
129
- .orderBy((c) => c.id, "DESC");
130
-
131
- expect(q).toBeDefined();
132
- });
133
-
134
86
  it("NullableQueryableRecord wraps primitives with | undefined", () => {
135
87
  // Type-only test — verified by pnpm typecheck
136
88
  type TestData = { name: string; age: number | undefined };
@@ -85,27 +85,6 @@ describe("result-parser performance", () => {
85
85
  console.log(` simple 10,000: ${elapsed.toFixed(2)}ms`);
86
86
  });
87
87
 
88
- it("50,000 records processing - within 3000ms", async () => {
89
- const raw = generateSimpleRecords(50_000);
90
- const meta: ResultMeta = {
91
- columns: {
92
- id: "number",
93
- name: "string",
94
- email: "string",
95
- age: "number",
96
- active: "boolean",
97
- },
98
- joins: {},
99
- };
100
-
101
- const start = performance.now();
102
- const result = await parseQueryResult(raw, meta);
103
- const elapsed = performance.now() - start;
104
-
105
- expect(result).toHaveLength(50_000);
106
- expect(elapsed).toBeLessThan(3000);
107
- console.log(` simple 50,000: ${elapsed.toFixed(2)}ms`);
108
- });
109
88
  });
110
89
 
111
90
  describe("1-level JOIN processing", () => {
@@ -131,27 +110,6 @@ describe("result-parser performance", () => {
131
110
  console.log(` JOIN 10,000 (1000×10): ${elapsed.toFixed(2)}ms`);
132
111
  });
133
112
 
134
- it("5,000 users × 10 posts = 50,000 records - within 3000ms", async () => {
135
- const raw = generateJoinRecords(5_000, 10);
136
- const meta: ResultMeta = {
137
- columns: {
138
- "id": "number",
139
- "name": "string",
140
- "posts.id": "number",
141
- "posts.title": "string",
142
- "posts.content": "string",
143
- },
144
- joins: { posts: { isSingle: false } },
145
- };
146
-
147
- const start = performance.now();
148
- const result = await parseQueryResult(raw, meta);
149
- const elapsed = performance.now() - start;
150
-
151
- expect(result).toHaveLength(5_000);
152
- expect(elapsed).toBeLessThan(3000);
153
- console.log(` JOIN 50,000 (5000×10): ${elapsed.toFixed(2)}ms`);
154
- });
155
113
  });
156
114
 
157
115
  describe("2-level nested JOIN processing", () => {
@@ -181,30 +139,5 @@ describe("result-parser performance", () => {
181
139
  console.log(` nested JOIN 5,000 (100×10×5): ${elapsed.toFixed(2)}ms`);
182
140
  });
183
141
 
184
- it("500 users × 10 posts × 5 comments = 25,000 records - within 2000ms", async () => {
185
- const raw = generateNestedJoinRecords(500, 10, 5);
186
- const meta: ResultMeta = {
187
- columns: {
188
- "id": "number",
189
- "name": "string",
190
- "posts.id": "number",
191
- "posts.title": "string",
192
- "posts.comments.id": "number",
193
- "posts.comments.text": "string",
194
- },
195
- joins: {
196
- "posts": { isSingle: false },
197
- "posts.comments": { isSingle: false },
198
- },
199
- };
200
-
201
- const start = performance.now();
202
- const result = await parseQueryResult(raw, meta);
203
- const elapsed = performance.now() - start;
204
-
205
- expect(result).toHaveLength(500);
206
- expect(elapsed).toBeLessThan(2000);
207
- console.log(` nested JOIN 25,000 (500×10×5): ${elapsed.toFixed(2)}ms`);
208
- });
209
142
  });
210
143
  });
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { bytesFromHex, DateOnly, DateTime, Time, Uuid } from "@simplysm/core-common";
2
+ import { bytes, DateOnly, DateTime, Time, Uuid } from "@simplysm/core-common";
3
3
  import { parseQueryResult } from "../../src/utils/result-parser";
4
4
  import type { ResultMeta } from "../../src/types/db";
5
5
 
@@ -40,17 +40,6 @@ describe("result-parser", () => {
40
40
  expect(result).toEqual([{ active: true, deleted: false }]);
41
41
  });
42
42
 
43
- it("boolean conversion - true/false", async () => {
44
- const raw = [{ active: true, deleted: false }];
45
- const meta: ResultMeta = {
46
- columns: { active: "boolean", deleted: "boolean" },
47
- joins: {},
48
- };
49
-
50
- const result = await parseQueryResult(raw, meta);
51
- expect(result).toEqual([{ active: true, deleted: false }]);
52
- });
53
-
54
43
  it('boolean conversion - "0"/"1" strings', async () => {
55
44
  const raw = [{ active: "1", deleted: "0" }];
56
45
  const meta: ResultMeta = {
@@ -123,7 +112,7 @@ describe("result-parser", () => {
123
112
 
124
113
  it("Uuid conversion - Uint8Array", async () => {
125
114
  const uuidStr = "550e8400-e29b-41d4-a716-446655440000";
126
- const uuidBytes = bytesFromHex(uuidStr.replace(/-/g, ""));
115
+ const uuidBytes = bytes.fromHex(uuidStr.replace(/-/g, ""));
127
116
  const raw = [{ id: uuidBytes }];
128
117
  const meta: ResultMeta = {
129
118
  columns: { id: "Uuid" },
@@ -137,8 +126,8 @@ describe("result-parser", () => {
137
126
  });
138
127
 
139
128
  it("Bytes conversion - Uint8Array passthrough", async () => {
140
- const bytes = new Uint8Array([0x01, 0x02, 0x03]);
141
- const raw = [{ data: bytes }];
129
+ const rawBytes = new Uint8Array([0x01, 0x02, 0x03]);
130
+ const raw = [{ data: rawBytes }];
142
131
  const meta: ResultMeta = {
143
132
  columns: { data: "Bytes" },
144
133
  joins: {},
@@ -183,18 +172,6 @@ describe("result-parser", () => {
183
172
  expect(result![0]).not.toHaveProperty("name");
184
173
  });
185
174
 
186
- it("undefined value removes the key", async () => {
187
- const raw = [{ id: 1, name: undefined }];
188
- const meta: ResultMeta = {
189
- columns: { id: "number", name: "string" },
190
- joins: {},
191
- };
192
-
193
- const result = await parseQueryResult(raw, meta);
194
- expect(result).toEqual([{ id: 1 }]);
195
- expect(result![0]).not.toHaveProperty("name");
196
- });
197
-
198
175
  it("record with all null values is excluded", async () => {
199
176
  const raw = [{ id: null, name: null }];
200
177
  const meta: ResultMeta = {
@@ -618,17 +595,6 @@ describe("result-parser", () => {
618
595
  //#region ========== edge cases ==========
619
596
 
620
597
  describe("edge cases", () => {
621
- it("joins is an empty object", async () => {
622
- const raw = [{ id: 1, name: "User1" }];
623
- const meta: ResultMeta = {
624
- columns: { id: "number", name: "string" },
625
- joins: {},
626
- };
627
-
628
- const result = await parseQueryResult(raw, meta);
629
- expect(result).toEqual([{ id: 1, name: "User1" }]);
630
- });
631
-
632
598
  it("deduplicates duplicate data", async () => {
633
599
  const raw = [
634
600
  { "id": 1, "name": "User1", "posts.id": 10, "posts.title": "Post1" },