litedbmodel 1.0.1 → 1.1.0

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 (83) hide show
  1. package/README.md +17 -13
  2. package/dist/DBModel.d.ts +18 -18
  3. package/dist/DBModel.d.ts.map +1 -1
  4. package/dist/DBModel.js +9 -9
  5. package/dist/DBModel.js.map +1 -1
  6. package/dist/LazyRelation.js +7 -7
  7. package/dist/LazyRelation.js.map +1 -1
  8. package/dist/SqlFragment.js +1 -1
  9. package/dist/SqlFragment.js.map +1 -1
  10. package/dist/decorators.d.ts +6 -7
  11. package/dist/decorators.d.ts.map +1 -1
  12. package/dist/decorators.js +36 -15
  13. package/dist/decorators.js.map +1 -1
  14. package/dist/types.d.ts +0 -9
  15. package/dist/types.d.ts.map +1 -1
  16. package/docs/COMPARISON.md +4 -2
  17. package/docs/api/README.md +61 -9
  18. package/docs/api/classes/Conditions.md +75 -8
  19. package/docs/api/classes/DBHandler.md +3 -3
  20. package/docs/api/classes/DBModel.md +260 -106
  21. package/docs/api/classes/LimitExceededError.md +1 -1
  22. package/docs/api/classes/Middleware.md +1 -1
  23. package/docs/api/classes/SqlRaw.md +53 -0
  24. package/docs/api/classes/SqlRef.md +59 -0
  25. package/docs/api/classes/Values.md +6 -6
  26. package/docs/api/classes/WriteInReadOnlyContextError.md +1 -1
  27. package/docs/api/classes/WriteOutsideTransactionError.md +1 -1
  28. package/docs/api/functions/belongsTo.md +2 -2
  29. package/docs/api/functions/closeAllPools.md +1 -1
  30. package/docs/api/functions/condsToRecord.md +23 -0
  31. package/docs/api/functions/createMiddleware.md +68 -0
  32. package/docs/api/functions/createPostgresDriver.md +2 -2
  33. package/docs/api/functions/createSqliteDriver.md +1 -1
  34. package/docs/api/functions/dbCast.md +1 -1
  35. package/docs/api/functions/dbCastIn.md +1 -1
  36. package/docs/api/functions/dbDynamic.md +1 -1
  37. package/docs/api/functions/dbFalse.md +1 -1
  38. package/docs/api/functions/dbImmediate.md +1 -1
  39. package/docs/api/functions/dbIn.md +1 -1
  40. package/docs/api/functions/dbNotNull.md +1 -1
  41. package/docs/api/functions/dbNow.md +1 -1
  42. package/docs/api/functions/dbNull.md +1 -1
  43. package/docs/api/functions/dbRaw.md +1 -1
  44. package/docs/api/functions/dbTrue.md +1 -1
  45. package/docs/api/functions/dbUuid.md +1 -1
  46. package/docs/api/functions/dbUuidIn.md +1 -1
  47. package/docs/api/functions/getDBConfig.md +1 -1
  48. package/docs/api/functions/getDBHandler.md +1 -1
  49. package/docs/api/functions/getTransactionConnection.md +2 -2
  50. package/docs/api/functions/getTransactionContext.md +2 -2
  51. package/docs/api/functions/hasMany.md +2 -2
  52. package/docs/api/functions/hasOne.md +2 -2
  53. package/docs/api/functions/initDBHandler.md +1 -1
  54. package/docs/api/functions/isAnySqlFragment.md +25 -0
  55. package/docs/api/functions/isSqlCondition.md +23 -0
  56. package/docs/api/functions/isSqlFragment.md +23 -0
  57. package/docs/api/functions/isSqlRaw.md +23 -0
  58. package/docs/api/functions/isSqlRef.md +23 -0
  59. package/docs/api/functions/isSqlTypedFragment.md +23 -0
  60. package/docs/api/functions/model.md +4 -4
  61. package/docs/api/functions/parentRef.md +1 -1
  62. package/docs/api/functions/sql.md +182 -0
  63. package/docs/api/globals.md +71 -19
  64. package/docs/api/interfaces/Column.md +31 -31
  65. package/docs/api/interfaces/ColumnOptions.md +4 -4
  66. package/docs/api/interfaces/CreatedMiddlewareClass.md +110 -0
  67. package/docs/api/interfaces/DBConfig.md +2 -2
  68. package/docs/api/interfaces/DBConfigOptions.md +1 -1
  69. package/docs/api/interfaces/DeleteOptions.md +1 -1
  70. package/docs/api/interfaces/InsertOptions.md +2 -2
  71. package/docs/api/interfaces/LimitConfig.md +1 -1
  72. package/docs/api/interfaces/MiddlewareConfig.md +40 -0
  73. package/docs/api/interfaces/ModelOptions.md +1 -1
  74. package/docs/api/interfaces/PkeyResult.md +1 -1
  75. package/docs/api/interfaces/SelectOptions.md +1 -1
  76. package/docs/api/interfaces/SqlCondition.md +27 -0
  77. package/docs/api/interfaces/SqlFragment.md +20 -0
  78. package/docs/api/interfaces/SqlTypedFragment.md +29 -0
  79. package/docs/api/interfaces/TransactionOptions.md +1 -1
  80. package/docs/api/interfaces/UpdateManyOptions.md +1 -1
  81. package/docs/api/interfaces/UpdateOptions.md +1 -1
  82. package/docs/sql-tagged-template.md +5 -5
  83. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- [**litedbmodel v0.20.1**](../README.md)
1
+ [**litedbmodel v1.0.1**](../README.md)
2
2
 
3
3
  ***
4
4
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Abstract Class: DBModel
8
8
 
9
- Defined in: DBModel.ts:110
9
+ Defined in: DBModel.ts:113
10
10
 
11
11
  Base class for all database models in litedbmodel.
12
12
  Provides CRUD operations, relations, transactions, and middleware support.
@@ -63,7 +63,7 @@ const john = await User.findOne([[User.email, 'john@example.com']]);
63
63
  new DBModel(): DBModel;
64
64
  ```
65
65
 
66
- Defined in: DBModel.ts:1495
66
+ Defined in: DBModel.ts:1583
67
67
 
68
68
  #### Returns
69
69
 
@@ -73,27 +73,28 @@ Defined in: DBModel.ts:1495
73
73
 
74
74
  | Property | Modifier | Type | Default value | Description | Defined in |
75
75
  | ------ | ------ | ------ | ------ | ------ | ------ |
76
- | <a id="table_name"></a> `TABLE_NAME` | `static` | `string` | `''` | Table name | DBModel.ts:116 |
77
- | <a id="update_table_name"></a> `UPDATE_TABLE_NAME` | `static` | `string` \| `null` | `null` | Table name for UPDATE/DELETE (if different from TABLE_NAME) | DBModel.ts:141 |
78
- | <a id="select_column"></a> `SELECT_COLUMN` | `static` | `string` | `'*'` | Default SELECT columns | DBModel.ts:144 |
79
- | <a id="default_order"></a> `DEFAULT_ORDER` | `static` | `OrderSpec` \| `null` | `null` | Default ORDER BY clause (type-safe OrderColumn or OrderColumn[]) | DBModel.ts:147 |
80
- | <a id="default_group"></a> `DEFAULT_GROUP` | `static` | \| `string` \| [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\> \| [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\>[] \| `null` | `null` | Default GROUP BY clause (Column, Column[], or raw string) | DBModel.ts:150 |
81
- | <a id="find_filter"></a> `FIND_FILTER` | `static` | `Conds` \| `null` | `null` | Default filter conditions applied to all queries (use tuple format like find()) | DBModel.ts:153 |
82
- | <a id="query"></a> `QUERY` | `static` | `string` \| `null` | `null` | SQL query for query-based models (view models, aggregations, etc.) When defined, the model uses this query as a CTE instead of TABLE_NAME. **Example** `// Static query static QUERY = ` SELECT users.id, COUNT(posts.id) as post_count FROM users LEFT JOIN posts ON users.id = posts.user_id GROUP BY users.id `;` | DBModel.ts:169 |
83
- | <a id="pkey_columns"></a> `PKEY_COLUMNS` | `static` | [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\>[] \| `null` | `null` | Primary key columns (use getter to reference Model.column) | DBModel.ts:178 |
84
- | <a id="seq_name"></a> `SEQ_NAME` | `static` | `string` \| `null` | `null` | Sequence name for auto-increment (use getter if needed) | DBModel.ts:181 |
85
- | <a id="id_type"></a> `ID_TYPE` | `static` | `"uuid"` \| `"serial"` \| `null` | `null` | ID type: 'serial' for auto-increment, 'uuid' for UUID generation | DBModel.ts:184 |
86
- | <a id="_dbconfig"></a> `_dbConfig` | `static` | [`DBConfig`](../interfaces/DBConfig.md) \| `null` | `null` | Database config | DBModel.ts:191 |
87
- | <a id="_limitconfig"></a> `_limitConfig` | `static` | [`LimitConfig`](../interfaces/LimitConfig.md) | `{}` | Limit config for safety guards | DBModel.ts:194 |
88
- | <a id="_configoptions"></a> `_configOptions` | `static` | [`DBConfigOptions`](../interfaces/DBConfigOptions.md) | `undefined` | Configuration options for reader/writer separation | DBModel.ts:197 |
89
- | <a id="_lasttransactiontime"></a> `_lastTransactionTime` | `static` | `number` | `0` | Last transaction completion time (for writer sticky) | DBModel.ts:203 |
90
- | <a id="true"></a> `true` | `readonly` | `DBBoolValue` | `undefined` | Boolean TRUE value | DBModel.ts:1104 |
91
- | <a id="false"></a> `false` | `readonly` | `DBBoolValue` | `undefined` | Boolean FALSE value | DBModel.ts:1107 |
92
- | <a id="null"></a> `null` | `readonly` | `DBNullValue` | `undefined` | NULL value | DBModel.ts:1110 |
93
- | <a id="notnull"></a> `notNull` | `readonly` | `DBNotNullValue` | `undefined` | NOT NULL value | DBModel.ts:1113 |
94
- | <a id="now"></a> `now` | `readonly` | `DBImmediateValue` | `undefined` | NOW() value | DBModel.ts:1116 |
95
- | <a id="_modelclass"></a> `_modelClass` | `protected` | *typeof* `DBModel` | `undefined` | Instance reference to the static class | DBModel.ts:1487 |
96
- | <a id="_relationcache"></a> `_relationCache` | `protected` | `Map`\<`string`, `unknown`\> | `undefined` | Per-instance cache for loaded relations | DBModel.ts:1490 |
76
+ | <a id="table_name"></a> `TABLE_NAME` | `static` | `string` | `''` | Table name | DBModel.ts:119 |
77
+ | <a id="update_table_name"></a> `UPDATE_TABLE_NAME` | `static` | `string` \| `null` | `null` | Table name for UPDATE/DELETE (if different from TABLE_NAME) | DBModel.ts:144 |
78
+ | <a id="select_column"></a> `SELECT_COLUMN` | `static` | `string` | `'*'` | Default SELECT columns | DBModel.ts:147 |
79
+ | <a id="default_order"></a> `DEFAULT_ORDER` | `static` | `OrderSpec` \| `null` | `null` | Default ORDER BY clause (type-safe OrderColumn or OrderColumn[]) | DBModel.ts:150 |
80
+ | <a id="default_group"></a> `DEFAULT_GROUP` | `static` | \| `string` \| [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\> \| [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\>[] \| `null` | `null` | Default GROUP BY clause (Column, Column[], or raw string) | DBModel.ts:153 |
81
+ | <a id="find_filter"></a> `FIND_FILTER` | `static` | `Conds` \| `null` | `null` | Default filter conditions applied to all queries (use tuple format like find()) | DBModel.ts:156 |
82
+ | <a id="query"></a> `QUERY` | `static` | \| `string` \| [`SqlFragment`](../interfaces/SqlFragment.md) \| [`SqlTypedFragment`](../interfaces/SqlTypedFragment.md)\<`unknown`, `unknown`\> \| [`SqlCondition`](../interfaces/SqlCondition.md)\<`unknown`\> \| `null` | `null` | SQL query for query-based models (view models, aggregations, etc.) When defined, the model uses this query as a CTE instead of TABLE_NAME. **Example** `// Static query static QUERY = ` SELECT users.id, COUNT(posts.id) as post_count FROM users LEFT JOIN posts ON users.id = posts.user_id GROUP BY users.id `;` | DBModel.ts:172 |
83
+ | <a id="pkey_columns"></a> `PKEY_COLUMNS` | `static` | [`Column`](../interfaces/Column.md)\<`unknown`, `unknown`\>[] \| `null` | `null` | Primary key columns (use getter to reference Model.column) | DBModel.ts:181 |
84
+ | <a id="seq_name"></a> `SEQ_NAME` | `static` | `string` \| `null` | `null` | Sequence name for auto-increment (use getter if needed) | DBModel.ts:184 |
85
+ | <a id="id_type"></a> `ID_TYPE` | `static` | `"uuid"` \| `"serial"` \| `null` | `null` | ID type: 'serial' for auto-increment, 'uuid' for UUID generation | DBModel.ts:187 |
86
+ | <a id="_dbconfig"></a> `_dbConfig` | `static` | [`DBConfig`](../interfaces/DBConfig.md) \| `null` | `null` | Database config | DBModel.ts:194 |
87
+ | <a id="_limitconfig"></a> `_limitConfig` | `static` | [`LimitConfig`](../interfaces/LimitConfig.md) | `{}` | Limit config for safety guards | DBModel.ts:197 |
88
+ | <a id="_configoptions"></a> `_configOptions` | `static` | [`DBConfigOptions`](../interfaces/DBConfigOptions.md) | `undefined` | Configuration options for reader/writer separation | DBModel.ts:200 |
89
+ | <a id="_lasttransactiontime"></a> `_lastTransactionTime` | `static` | `number` | `0` | Last transaction completion time (for writer sticky) | DBModel.ts:206 |
90
+ | <a id="true"></a> `true` | `readonly` | `DBBoolValue` | `undefined` | Boolean TRUE value | DBModel.ts:1150 |
91
+ | <a id="false"></a> `false` | `readonly` | `DBBoolValue` | `undefined` | Boolean FALSE value | DBModel.ts:1153 |
92
+ | <a id="null"></a> `null` | `readonly` | `DBNullValue` | `undefined` | NULL value | DBModel.ts:1156 |
93
+ | <a id="notnull"></a> `notNull` | `readonly` | `DBNotNullValue` | `undefined` | NOT NULL value | DBModel.ts:1159 |
94
+ | <a id="now"></a> `now` | `readonly` | `DBImmediateValue` | `undefined` | NOW() value | DBModel.ts:1162 |
95
+ | <a id="_modelclass"></a> `_modelClass` | `protected` | *typeof* `DBModel` | `undefined` | Instance reference to the static class | DBModel.ts:1572 |
96
+ | <a id="_relationcache"></a> `_relationCache` | `protected` | `Map`\<`string`, `unknown`\> \| `null` | `null` | Per-instance cache for loaded relations (lazy-initialized) | DBModel.ts:1575 |
97
+ | <a id="_deferredcontext"></a> `_deferredContext` | `public` | \[*typeof* `DBModel`, `DBModel`[]\] \| `null` | `null` | Deferred context info: [sourceClass, records] set by _select, resolved on first relation access | DBModel.ts:1581 |
97
98
 
98
99
  ## Methods
99
100
 
@@ -103,7 +104,7 @@ Defined in: DBModel.ts:1495
103
104
  static asModel<T>(this: T): T & ColumnsOf<InstanceType<T>>;
104
105
  ```
105
106
 
106
- Defined in: DBModel.ts:136
107
+ Defined in: DBModel.ts:139
107
108
 
108
109
  Returns the model class with type-safe column properties.
109
110
  Use this instead of manual casting with `ColumnsOf`.
@@ -147,7 +148,7 @@ await User.find([[User.name, 'John']]);
147
148
  static setConfig(config: DBConfig, options?: DBConfigOptions): void;
148
149
  ```
149
150
 
150
- Defined in: DBModel.ts:233
151
+ Defined in: DBModel.ts:236
151
152
 
152
153
  Initialize DBModel with database config.
153
154
  Call this once at application startup.
@@ -196,7 +197,7 @@ DBModel.setConfig(
196
197
  static getLimitConfig(): LimitConfig;
197
198
  ```
198
199
 
199
- Defined in: DBModel.ts:257
200
+ Defined in: DBModel.ts:260
200
201
 
201
202
  Get current limit configuration.
202
203
 
@@ -212,7 +213,7 @@ Get current limit configuration.
212
213
  static setLimitConfig(config: LimitConfig): void;
213
214
  ```
214
215
 
215
- Defined in: DBModel.ts:272
216
+ Defined in: DBModel.ts:275
216
217
 
217
218
  Update limit configuration.
218
219
 
@@ -244,7 +245,7 @@ DBModel.setLimitConfig({ findHardLimit: null, hasManyHardLimit: null });
244
245
  static getDBConfig(): DBConfig | null;
245
246
  ```
246
247
 
247
- Defined in: DBModel.ts:279
248
+ Defined in: DBModel.ts:282
248
249
 
249
250
  Get database config
250
251
 
@@ -257,17 +258,17 @@ Get database config
257
258
  ### getDriverType()
258
259
 
259
260
  ```ts
260
- static getDriverType(): "postgres" | "sqlite" | "mysql";
261
+ static getDriverType(): "postgres" | "mysql" | "sqlite";
261
262
  ```
262
263
 
263
- Defined in: DBModel.ts:287
264
+ Defined in: DBModel.ts:290
264
265
 
265
266
  Get the database driver type.
266
267
  Returns 'postgres', 'mysql', or 'sqlite'.
267
268
 
268
269
  #### Returns
269
270
 
270
- `"postgres"` \| `"sqlite"` \| `"mysql"`
271
+ `"postgres"` \| `"mysql"` \| `"sqlite"`
271
272
 
272
273
  ***
273
274
 
@@ -277,7 +278,7 @@ Returns 'postgres', 'mysql', or 'sqlite'.
277
278
  protected static getHandler(): DBHandler;
278
279
  ```
279
280
 
280
- Defined in: DBModel.ts:313
281
+ Defined in: DBModel.ts:316
281
282
 
282
283
  Get a DBHandler instance for this model.
283
284
  Connection priority:
@@ -298,7 +299,7 @@ Connection priority:
298
299
  protected static _shouldUseWriterSticky(): boolean;
299
300
  ```
300
301
 
301
- Defined in: DBModel.ts:339
302
+ Defined in: DBModel.ts:345
302
303
 
303
304
  Check if we should use writer due to sticky after transaction.
304
305
 
@@ -308,13 +309,47 @@ Check if we should use writer due to sticky after transaction.
308
309
 
309
310
  ***
310
311
 
312
+ ### \_getTransactionContext()
313
+
314
+ ```ts
315
+ protected static _getTransactionContext(): AsyncLocalStorage<TransactionContext>;
316
+ ```
317
+
318
+ Defined in: DBModel.ts:357
319
+
320
+ Get transaction context storage.
321
+ Override in subclass to use independent transaction context.
322
+
323
+ #### Returns
324
+
325
+ `AsyncLocalStorage`\<`TransactionContext`\>
326
+
327
+ ***
328
+
329
+ ### \_getWriterContext()
330
+
331
+ ```ts
332
+ protected static _getWriterContext(): AsyncLocalStorage<WriterContext>;
333
+ ```
334
+
335
+ Defined in: DBModel.ts:365
336
+
337
+ Get writer context storage.
338
+ Override in subclass to use independent writer context.
339
+
340
+ #### Returns
341
+
342
+ `AsyncLocalStorage`\<`WriterContext`\>
343
+
344
+ ***
345
+
311
346
  ### inWriterContext()
312
347
 
313
348
  ```ts
314
349
  static inWriterContext(): boolean;
315
350
  ```
316
351
 
317
- Defined in: DBModel.ts:350
352
+ Defined in: DBModel.ts:372
318
353
 
319
354
  Check if currently in a withWriter context.
320
355
 
@@ -330,7 +365,7 @@ Check if currently in a withWriter context.
330
365
  static use(MiddlewareClass: MiddlewareClass): () => void;
331
366
  ```
332
367
 
333
- Defined in: DBModel.ts:393
368
+ Defined in: DBModel.ts:415
334
369
 
335
370
  Register a middleware class to intercept DBModel methods.
336
371
 
@@ -381,13 +416,79 @@ console.log(LoggerMiddleware.getCurrentContext().getLogs());
381
416
 
382
417
  ***
383
418
 
419
+ ### createMiddleware()
420
+
421
+ ```ts
422
+ static createMiddleware<S>(config: MiddlewareConfig<S>): CreatedMiddlewareClass<S>;
423
+ ```
424
+
425
+ Defined in: DBModel.ts:467
426
+
427
+ Create a middleware class from a configuration object.
428
+
429
+ This is a simpler alternative to extending the Middleware class directly.
430
+ Each request gets its own copy of the state object via AsyncLocalStorage.
431
+
432
+ #### Type Parameters
433
+
434
+ | Type Parameter | Default type |
435
+ | ------ | ------ |
436
+ | `S` *extends* `object` | `Record`\<`string`, `never`\> |
437
+
438
+ #### Parameters
439
+
440
+ | Parameter | Type | Description |
441
+ | ------ | ------ | ------ |
442
+ | `config` | [`MiddlewareConfig`](../interfaces/MiddlewareConfig.md)\<`S`\> | Middleware configuration with state and hook functions |
443
+
444
+ #### Returns
445
+
446
+ [`CreatedMiddlewareClass`](../interfaces/CreatedMiddlewareClass.md)\<`S`\>
447
+
448
+ A middleware class that can be passed to DBModel.use()
449
+
450
+ #### Example
451
+
452
+ ```typescript
453
+ // Simple logger (no state)
454
+ const LoggerMiddleware = DBModel.createMiddleware({
455
+ execute: async function(next, sql, params) {
456
+ console.log('SQL:', sql);
457
+ return next(sql, params);
458
+ }
459
+ });
460
+
461
+ // With per-request state
462
+ const TenantMiddleware = DBModel.createMiddleware({
463
+ state: { tenantId: 0, logs: [] as string[] },
464
+
465
+ // Note: hook signature is (model, next, ...args) for method-level hooks
466
+ find: async function(model, next, conditions, options) {
467
+ // `this` is typed as { tenantId: number; logs: string[] }
468
+ this.logs.push(`find on ${model.TABLE_NAME}`);
469
+ if (model.tenant_id) {
470
+ conditions = [[model.tenant_id, this.tenantId], ...conditions];
471
+ }
472
+ return next(conditions, options);
473
+ }
474
+ });
475
+
476
+ // Register
477
+ DBModel.use(TenantMiddleware);
478
+
479
+ // Set tenant for current request (type-safe)
480
+ TenantMiddleware.getCurrentContext().tenantId = 123;
481
+ ```
482
+
483
+ ***
484
+
384
485
  ### removeMiddleware()
385
486
 
386
487
  ```ts
387
488
  static removeMiddleware(MiddlewareClass: MiddlewareClass): boolean;
388
489
  ```
389
490
 
390
- Defined in: DBModel.ts:409
491
+ Defined in: DBModel.ts:478
391
492
 
392
493
  Remove a middleware class
393
494
 
@@ -411,7 +512,7 @@ true if middleware was found and removed
411
512
  static clearMiddlewares(): void;
412
513
  ```
413
514
 
414
- Defined in: DBModel.ts:421
515
+ Defined in: DBModel.ts:490
415
516
 
416
517
  Clear all middlewares (useful for testing)
417
518
 
@@ -427,7 +528,7 @@ Clear all middlewares (useful for testing)
427
528
  static getMiddlewares(): readonly MiddlewareClass[];
428
529
  ```
429
530
 
430
- Defined in: DBModel.ts:428
531
+ Defined in: DBModel.ts:497
431
532
 
432
533
  Get registered middleware classes
433
534
 
@@ -450,7 +551,7 @@ static buildSelectSQL<T>(
450
551
  };
451
552
  ```
452
553
 
453
- Defined in: DBModel.ts:615
554
+ Defined in: DBModel.ts:684
454
555
 
455
556
  Build SELECT SQL without executing.
456
557
  Useful for constructing CTE/subquery SQL fragments.
@@ -484,8 +585,8 @@ Object with sql and params
484
585
 
485
586
  | Name | Type | Defined in |
486
587
  | ------ | ------ | ------ |
487
- | `sql` | `string` | DBModel.ts:620 |
488
- | `params` | `unknown`[] | DBModel.ts:620 |
588
+ | `sql` | `string` | DBModel.ts:689 |
589
+ | `params` | `unknown`[] | DBModel.ts:689 |
489
590
 
490
591
  #### Example
491
592
 
@@ -510,7 +611,7 @@ static inSubquery<T, S>(
510
611
  conditions: readonly [Column<any, S>, unknown][]): readonly [string, DBSubquery];
511
612
  ```
512
613
 
513
- Defined in: DBModel.ts:1162
614
+ Defined in: DBModel.ts:1208
514
615
 
515
616
  IN subquery condition.
516
617
  Creates a condition like: column IN (SELECT selectColumn FROM targetModel WHERE ...)
@@ -578,7 +679,7 @@ static notInSubquery<T, S>(
578
679
  conditions: readonly [Column<any, S>, unknown][]): readonly [string, DBSubquery];
579
680
  ```
580
681
 
581
- Defined in: DBModel.ts:1210
682
+ Defined in: DBModel.ts:1256
582
683
 
583
684
  NOT IN subquery condition.
584
685
  Creates a condition like: table.column NOT IN (SELECT table.column FROM targetModel WHERE ...)
@@ -631,7 +732,7 @@ await User.find([
631
732
  static exists<S>(conditions: readonly [Column<any, S>, unknown][]): readonly [string, DBExists];
632
733
  ```
633
734
 
634
- Defined in: DBModel.ts:1253
735
+ Defined in: DBModel.ts:1299
635
736
 
636
737
  EXISTS subquery condition.
637
738
  Creates a condition like: EXISTS (SELECT 1 FROM targetModel WHERE table.column = ...)
@@ -678,7 +779,7 @@ await User.find([
678
779
  static notExists<S>(conditions: readonly [Column<any, S>, unknown][]): readonly [string, DBExists];
679
780
  ```
680
781
 
681
- Defined in: DBModel.ts:1288
782
+ Defined in: DBModel.ts:1334
682
783
 
683
784
  NOT EXISTS subquery condition.
684
785
  Creates a condition like: NOT EXISTS (SELECT 1 FROM targetModel WHERE table.column = ...)
@@ -724,7 +825,7 @@ await User.find([
724
825
  static getTableName(): string;
725
826
  ```
726
827
 
727
- Defined in: DBModel.ts:1377
828
+ Defined in: DBModel.ts:1423
728
829
 
729
830
  Get table name for SELECT queries.
730
831
  For query-based models, returns the CTE alias (TABLE_NAME).
@@ -741,7 +842,7 @@ For query-based models, returns the CTE alias (TABLE_NAME).
741
842
  static isQueryBased(): boolean;
742
843
  ```
743
844
 
744
- Defined in: DBModel.ts:1400
845
+ Defined in: DBModel.ts:1481
745
846
 
746
847
  Check if this model is query-based (uses QUERY instead of TABLE_NAME)
747
848
 
@@ -754,16 +855,21 @@ Check if this model is query-based (uses QUERY instead of TABLE_NAME)
754
855
  ### withQuery()
755
856
 
756
857
  ```ts
757
- static withQuery<T>(this: T, queryConfig: {
858
+ static withQuery<T>(this: T, queryConfig:
859
+ | SqlFragment
860
+ | SqlTypedFragment<unknown, unknown>
861
+ | SqlCondition<unknown>
862
+ | {
758
863
  sql: string;
759
864
  params?: unknown[];
760
865
  }): T;
761
866
  ```
762
867
 
763
- Defined in: DBModel.ts:1428
868
+ Defined in: DBModel.ts:1510
764
869
 
765
870
  Create a new model class bound to specific query parameters.
766
871
  Used for parameterized query-based models.
872
+ Accepts either `{ sql, params }` object or a `SqlFragment` from `sql` tagged template.
767
873
 
768
874
  #### Type Parameters
769
875
 
@@ -776,9 +882,7 @@ Used for parameterized query-based models.
776
882
  | Parameter | Type | Description |
777
883
  | ------ | ------ | ------ |
778
884
  | `this` | `T` | - |
779
- | `queryConfig` | \{ `sql`: `string`; `params?`: `unknown`[]; \} | Query configuration with sql and params |
780
- | `queryConfig.sql` | `string` | - |
781
- | `queryConfig.params?` | `unknown`[] | - |
885
+ | `queryConfig` | \| [`SqlFragment`](../interfaces/SqlFragment.md) \| [`SqlTypedFragment`](../interfaces/SqlTypedFragment.md)\<`unknown`, `unknown`\> \| [`SqlCondition`](../interfaces/SqlCondition.md)\<`unknown`\> \| \{ `sql`: `string`; `params?`: `unknown`[]; \} | Query configuration with sql and params, or SqlFragment |
782
886
 
783
887
  #### Returns
784
888
 
@@ -789,19 +893,19 @@ A new model class with bound parameters
789
893
  #### Example
790
894
 
791
895
  ```typescript
896
+ import { sql } from 'litedbmodel';
897
+
792
898
  class SalesReportModel extends DBModel {
793
- static QUERY = '...'; // Base query template
794
-
795
899
  static forPeriod(startDate: string, endDate: string) {
796
- return this.withQuery({
797
- sql: `SELECT ... WHERE date >= $1 AND date < $2 ...`,
798
- params: [startDate, endDate],
799
- });
900
+ return this.withQuery(sql`
901
+ SELECT p.id, SUM(oi.quantity) AS total
902
+ FROM products p
903
+ JOIN order_items oi ON p.id = oi.product_id
904
+ WHERE oi.created_at >= ${startDate} AND oi.created_at < ${endDate}
905
+ GROUP BY p.id
906
+ `);
800
907
  }
801
908
  }
802
-
803
- const Q1Report = SalesReport.forPeriod('2024-01-01', '2024-04-01');
804
- const results = await Q1Report.find([...]);
805
909
  ```
806
910
 
807
911
  ***
@@ -812,7 +916,7 @@ const results = await Q1Report.find([...]);
812
916
  static getUpdateTableName(): string;
813
917
  ```
814
918
 
815
- Defined in: DBModel.ts:1475
919
+ Defined in: DBModel.ts:1560
816
920
 
817
921
  Get table name for UPDATE/DELETE queries.
818
922
  Query-based models cannot be updated/deleted directly.
@@ -829,7 +933,7 @@ Query-based models cannot be updated/deleted directly.
829
933
  clearRelationCache(): void;
830
934
  ```
831
935
 
832
- Defined in: DBModel.ts:1528
936
+ Defined in: DBModel.ts:1624
833
937
 
834
938
  Clear the relation cache for this instance.
835
939
  Also clears the context cache to force reload from DB.
@@ -846,7 +950,7 @@ Also clears the context cache to force reload from DB.
846
950
  typeCastFromDB(): void;
847
951
  ```
848
952
 
849
- Defined in: DBModel.ts:1665
953
+ Defined in: DBModel.ts:1764
850
954
 
851
955
  Called after loading from DB to convert types
852
956
  Override in derived class to implement type conversions
@@ -872,7 +976,7 @@ typeCastFromDB(): void {
872
976
  getPkey(): Record<string, unknown> | null;
873
977
  ```
874
978
 
875
- Defined in: DBModel.ts:1677
979
+ Defined in: DBModel.ts:1776
876
980
 
877
981
  Get primary key as object
878
982
 
@@ -890,7 +994,7 @@ Object with primary key column names and values, or null if not set
890
994
  setPkey(key: unknown): void;
891
995
  ```
892
996
 
893
- Defined in: DBModel.ts:1698
997
+ Defined in: DBModel.ts:1797
894
998
 
895
999
  Set primary key value
896
1000
 
@@ -912,7 +1016,7 @@ Set primary key value
912
1016
  getPkeyString(): string;
913
1017
  ```
914
1018
 
915
- Defined in: DBModel.ts:1716
1019
+ Defined in: DBModel.ts:1815
916
1020
 
917
1021
  Get primary key as string (for logging, caching, etc.)
918
1022
 
@@ -928,7 +1032,7 @@ Get primary key as string (for logging, caching, etc.)
928
1032
  getSingleColId(): unknown;
929
1033
  ```
930
1034
 
931
- Defined in: DBModel.ts:1728
1035
+ Defined in: DBModel.ts:1827
932
1036
 
933
1037
  Get single-column ID value
934
1038
 
@@ -946,7 +1050,7 @@ ID value or undefined
946
1050
  clone<T>(this: T): T;
947
1051
  ```
948
1052
 
949
- Defined in: DBModel.ts:1743
1053
+ Defined in: DBModel.ts:1842
950
1054
 
951
1055
  Create a shallow copy of the model instance
952
1056
 
@@ -974,7 +1078,7 @@ Create a shallow copy of the model instance
974
1078
  assign(source: Partial<this>): this;
975
1079
  ```
976
1080
 
977
- Defined in: DBModel.ts:1751
1081
+ Defined in: DBModel.ts:1850
978
1082
 
979
1083
  Copy properties from another object
980
1084
 
@@ -996,7 +1100,7 @@ Copy properties from another object
996
1100
  toObject(): Record<string, unknown>;
997
1101
  ```
998
1102
 
999
- Defined in: DBModel.ts:1762
1103
+ Defined in: DBModel.ts:1861
1000
1104
 
1001
1105
  Convert to plain object
1002
1106
 
@@ -1012,7 +1116,7 @@ Convert to plain object
1012
1116
  toJSON(): Record<string, unknown>;
1013
1117
  ```
1014
1118
 
1015
- Defined in: DBModel.ts:1775
1119
+ Defined in: DBModel.ts:1874
1016
1120
 
1017
1121
  Convert to JSON-serializable object
1018
1122
 
@@ -1028,7 +1132,7 @@ Convert to JSON-serializable object
1028
1132
  static fromObject<T>(this: () => T, obj: Record<string, unknown>): T;
1029
1133
  ```
1030
1134
 
1031
- Defined in: DBModel.ts:1786
1135
+ Defined in: DBModel.ts:1885
1032
1136
 
1033
1137
  Create an instance from a plain object
1034
1138
 
@@ -1057,7 +1161,7 @@ Create an instance from a plain object
1057
1161
  static fromObjects<T>(this: () => T, objs: Record<string, unknown>[]): T[];
1058
1162
  ```
1059
1163
 
1060
- Defined in: DBModel.ts:1799
1164
+ Defined in: DBModel.ts:1898
1061
1165
 
1062
1166
  Create multiple instances from an array of plain objects
1063
1167
 
@@ -1086,7 +1190,7 @@ Create multiple instances from an array of plain objects
1086
1190
  static columnList<T>(records: T[], columnName: string): unknown[];
1087
1191
  ```
1088
1192
 
1089
- Defined in: DBModel.ts:1809
1193
+ Defined in: DBModel.ts:1908
1090
1194
 
1091
1195
  Get column values from an array of model instances
1092
1196
 
@@ -1115,7 +1219,7 @@ Get column values from an array of model instances
1115
1219
  static hashByProperty<T>(records: T[], propertyKey: string): Record<string, T>;
1116
1220
  ```
1117
1221
 
1118
- Defined in: DBModel.ts:1819
1222
+ Defined in: DBModel.ts:1918
1119
1223
 
1120
1224
  Create a hash map by property value
1121
1225
 
@@ -1144,7 +1248,7 @@ Create a hash map by property value
1144
1248
  static groupByProperty<T>(records: T[], propertyKey: string): Record<string, T[]>;
1145
1249
  ```
1146
1250
 
1147
- Defined in: DBModel.ts:1834
1251
+ Defined in: DBModel.ts:1933
1148
1252
 
1149
1253
  Group records by property value
1150
1254
 
@@ -1173,7 +1277,7 @@ Group records by property value
1173
1277
  static idList<T>(records: T[], column?: string): unknown[];
1174
1278
  ```
1175
1279
 
1176
- Defined in: DBModel.ts:1852
1280
+ Defined in: DBModel.ts:1951
1177
1281
 
1178
1282
  Get ID list from records
1179
1283
 
@@ -1205,7 +1309,7 @@ static makeLikeString(
1205
1309
  back: boolean): string;
1206
1310
  ```
1207
1311
 
1208
- Defined in: DBModel.ts:1860
1312
+ Defined in: DBModel.ts:1959
1209
1313
 
1210
1314
  Generate LIKE pattern string
1211
1315
 
@@ -1229,7 +1333,7 @@ Generate LIKE pattern string
1229
1333
  static or<T>(this: T, ...condGroups: readonly CondsOf<T>[]): OrCondOf<T>;
1230
1334
  ```
1231
1335
 
1232
- Defined in: DBModel.ts:1897
1336
+ Defined in: DBModel.ts:1996
1233
1337
 
1234
1338
  Create a type-safe OR condition for this model.
1235
1339
  All columns in the conditions must belong to this model.
@@ -1280,7 +1384,7 @@ static find<T>(
1280
1384
  options?: SelectOptions): Promise<InstanceType<T>[]>;
1281
1385
  ```
1282
1386
 
1283
- Defined in: DBModel.ts:1933
1387
+ Defined in: DBModel.ts:2032
1284
1388
 
1285
1389
  Find all records using type-safe condition tuples.
1286
1390
  All columns in conditions must belong to this model.
@@ -1334,7 +1438,7 @@ static findOne<T>(
1334
1438
  options?: SelectOptions): Promise<InstanceType<T> | null>;
1335
1439
  ```
1336
1440
 
1337
- Defined in: DBModel.ts:1979
1441
+ Defined in: DBModel.ts:2078
1338
1442
 
1339
1443
  Find first record using type-safe condition tuples.
1340
1444
 
@@ -1377,7 +1481,7 @@ static findById<T>(
1377
1481
  options?: SelectOptions): Promise<InstanceType<T>[]>;
1378
1482
  ```
1379
1483
 
1380
- Defined in: DBModel.ts:2018
1484
+ Defined in: DBModel.ts:2117
1381
1485
 
1382
1486
  Find records by primary key using PkeyResult format.
1383
1487
  Efficiently fetches multiple records by their primary keys.
@@ -1429,7 +1533,7 @@ const users = await User.findById(result);
1429
1533
  static count<T>(this: T, conditions: CondsOf<T>): Promise<number>;
1430
1534
  ```
1431
1535
 
1432
- Defined in: DBModel.ts:2137
1536
+ Defined in: DBModel.ts:2182
1433
1537
 
1434
1538
  Count records using type-safe condition tuples.
1435
1539
 
@@ -1469,7 +1573,7 @@ static create<T, P>(
1469
1573
  options?: InsertOptions<InstanceType<T>>): Promise<PkeyResult | null>;
1470
1574
  ```
1471
1575
 
1472
- Defined in: DBModel.ts:2172
1576
+ Defined in: DBModel.ts:2217
1473
1577
 
1474
1578
  Create a new record using type-safe column-value tuples.
1475
1579
  Value types are validated at compile time.
@@ -1523,7 +1627,7 @@ static createMany<T>(
1523
1627
  options?: InsertOptions<InstanceType<T>>): Promise<PkeyResult | null>;
1524
1628
  ```
1525
1629
 
1526
- Defined in: DBModel.ts:2242
1630
+ Defined in: DBModel.ts:2287
1527
1631
 
1528
1632
  Create multiple records using type-safe column-value tuples.
1529
1633
 
@@ -1576,7 +1680,7 @@ static update<T, V>(
1576
1680
  options?: UpdateOptions): Promise<PkeyResult | null>;
1577
1681
  ```
1578
1682
 
1579
- Defined in: DBModel.ts:2312
1683
+ Defined in: DBModel.ts:2357
1580
1684
 
1581
1685
  Update records using type-safe column-value tuples.
1582
1686
  Value types are validated at compile time.
@@ -1632,7 +1736,7 @@ static delete<T>(
1632
1736
  options?: DeleteOptions): Promise<PkeyResult | null>;
1633
1737
  ```
1634
1738
 
1635
- Defined in: DBModel.ts:2390
1739
+ Defined in: DBModel.ts:2436
1636
1740
 
1637
1741
  Delete records matching conditions
1638
1742
 
@@ -1678,7 +1782,7 @@ static updateMany<T>(
1678
1782
  options: UpdateManyOptions): Promise<PkeyResult | null>;
1679
1783
  ```
1680
1784
 
1681
- Defined in: DBModel.ts:2467
1785
+ Defined in: DBModel.ts:2514
1682
1786
 
1683
1787
  Update multiple records with different values per row.
1684
1788
  Uses efficient bulk update strategies (UNNEST for PostgreSQL, VALUES for MySQL/SQLite).
@@ -1724,36 +1828,86 @@ const users = await User.findById(result);
1724
1828
 
1725
1829
  ### execute()
1726
1830
 
1831
+ #### Call Signature
1832
+
1727
1833
  ```ts
1728
1834
  static execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
1729
1835
  ```
1730
1836
 
1731
- Defined in: DBModel.ts:2761
1837
+ Defined in: DBModel.ts:2657
1732
1838
 
1733
1839
  Execute raw SQL query.
1840
+ Accepts either a SQL string with params, or a `SqlFragment` from `sql` tagged template.
1734
1841
 
1735
- #### Parameters
1842
+ ##### Parameters
1736
1843
 
1737
1844
  | Parameter | Type | Description |
1738
1845
  | ------ | ------ | ------ |
1739
- | `sql` | `string` | SQL query |
1740
- | `params?` | `unknown`[] | Query parameters |
1846
+ | `sql` | `string` | SQL query string or SqlFragment |
1847
+ | `params?` | `unknown`[] | Query parameters (ignored when SqlFragment is passed) |
1741
1848
 
1742
- #### Returns
1849
+ ##### Returns
1743
1850
 
1744
1851
  `Promise`\<`ExecuteResult`\>
1745
1852
 
1746
1853
  QueryResult with rows, rowCount
1747
1854
 
1748
- #### Example
1855
+ ##### Example
1856
+
1857
+ ```typescript
1858
+ // Traditional
1859
+ const result = await DBModel.execute(
1860
+ 'SELECT * FROM users WHERE id = $1',
1861
+ [1]
1862
+ );
1863
+
1864
+ // With sql tag
1865
+ import { sql } from 'litedbmodel';
1866
+ const result = await DBModel.execute(
1867
+ sql`SELECT process_daily_aggregates(${targetDate})`
1868
+ );
1869
+ ```
1870
+
1871
+ #### Call Signature
1872
+
1873
+ ```ts
1874
+ static execute(fragment:
1875
+ | SqlFragment
1876
+ | SqlTypedFragment<unknown, unknown>
1877
+ | SqlCondition<unknown>): Promise<ExecuteResult>;
1878
+ ```
1879
+
1880
+ Defined in: DBModel.ts:2658
1881
+
1882
+ Execute raw SQL query.
1883
+ Accepts either a SQL string with params, or a `SqlFragment` from `sql` tagged template.
1884
+
1885
+ ##### Parameters
1886
+
1887
+ | Parameter | Type |
1888
+ | ------ | ------ |
1889
+ | `fragment` | \| [`SqlFragment`](../interfaces/SqlFragment.md) \| [`SqlTypedFragment`](../interfaces/SqlTypedFragment.md)\<`unknown`, `unknown`\> \| [`SqlCondition`](../interfaces/SqlCondition.md)\<`unknown`\> |
1890
+
1891
+ ##### Returns
1892
+
1893
+ `Promise`\<`ExecuteResult`\>
1894
+
1895
+ QueryResult with rows, rowCount
1896
+
1897
+ ##### Example
1749
1898
 
1750
1899
  ```typescript
1900
+ // Traditional
1751
1901
  const result = await DBModel.execute(
1752
1902
  'SELECT * FROM users WHERE id = $1',
1753
1903
  [1]
1754
1904
  );
1755
- console.log(result.rows);
1756
- console.log(result.rowCount);
1905
+
1906
+ // With sql tag
1907
+ import { sql } from 'litedbmodel';
1908
+ const result = await DBModel.execute(
1909
+ sql`SELECT process_daily_aggregates(${targetDate})`
1910
+ );
1757
1911
  ```
1758
1912
 
1759
1913
  ***
@@ -1767,7 +1921,7 @@ static query<T>(
1767
1921
  params?: unknown[]): Promise<InstanceType<T>[]>;
1768
1922
  ```
1769
1923
 
1770
- Defined in: DBModel.ts:2805
1924
+ Defined in: DBModel.ts:2710
1771
1925
 
1772
1926
  Execute raw SQL and return model instances.
1773
1927
  The SQL should return columns matching the model's properties.
@@ -1816,7 +1970,7 @@ const posts = await Post.query(`
1816
1970
  static inTransaction(): boolean;
1817
1971
  ```
1818
1972
 
1819
- Defined in: DBModel.ts:2835
1973
+ Defined in: DBModel.ts:2742
1820
1974
 
1821
1975
  Check if currently in a transaction
1822
1976
 
@@ -1832,7 +1986,7 @@ Check if currently in a transaction
1832
1986
  static transaction<R>(func: () => Promise<R>, options: TransactionOptions): Promise<R>;
1833
1987
  ```
1834
1988
 
1835
- Defined in: DBModel.ts:2873
1989
+ Defined in: DBModel.ts:2780
1836
1990
 
1837
1991
  Execute a function within a transaction
1838
1992
  All model operations inside the callback will use the same database connection.
@@ -1891,7 +2045,7 @@ await DBModel.transaction(
1891
2045
  static getCurrentConnection(): DBConnection | null;
1892
2046
  ```
1893
2047
 
1894
- Defined in: DBModel.ts:2976
2048
+ Defined in: DBModel.ts:2885
1895
2049
 
1896
2050
  Get current transaction connection
1897
2051
  Use this to execute raw SQL queries within a transaction
@@ -1921,7 +2075,7 @@ await DBModel.transaction(async () => {
1921
2075
  static getCurrentClient(): DBConnection | null;
1922
2076
  ```
1923
2077
 
1924
- Defined in: DBModel.ts:2984
2078
+ Defined in: DBModel.ts:2893
1925
2079
 
1926
2080
  #### Returns
1927
2081
 
@@ -1939,7 +2093,7 @@ Use getCurrentConnection() instead
1939
2093
  static withWriter<R>(func: () => Promise<R>): Promise<R>;
1940
2094
  ```
1941
2095
 
1942
- Defined in: DBModel.ts:3009
2096
+ Defined in: DBModel.ts:2918
1943
2097
 
1944
2098
  Execute a function with explicit writer connection access.
1945
2099
  Use this when you need to read from writer to avoid replication lag.
@@ -1985,7 +2139,7 @@ await DBModel.withWriter(async () => {
1985
2139
  static createDBBase(config: DBConfig, options?: DBConfigOptions): typeof DBModel;
1986
2140
  ```
1987
2141
 
1988
- Defined in: DBModel.ts:3070
2142
+ Defined in: DBModel.ts:2980
1989
2143
 
1990
2144
  Create an independent database base class.
1991
2145
  Use this to connect to multiple databases with isolated configurations.
@@ -2044,7 +2198,7 @@ await BaseDB.transaction(async () => {
2044
2198
  reload(forUpdate: boolean): Promise<DBModel | null>;
2045
2199
  ```
2046
2200
 
2047
- Defined in: DBModel.ts:3246
2201
+ Defined in: DBModel.ts:3050
2048
2202
 
2049
2203
  Reload this instance from the database
2050
2204