@simplysm/orm-common 13.0.82 → 13.0.84

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 (80) hide show
  1. package/README.md +106 -0
  2. package/dist/ddl/initialize.d.ts +2 -2
  3. package/dist/ddl/initialize.js +1 -1
  4. package/dist/ddl/initialize.js.map +1 -1
  5. package/dist/ddl/table-ddl.d.ts +1 -1
  6. package/dist/exec/queryable.d.ts +115 -115
  7. package/dist/exec/queryable.js +68 -68
  8. package/dist/exec/queryable.js.map +1 -1
  9. package/dist/expr/expr.d.ts +248 -248
  10. package/dist/expr/expr.js +250 -250
  11. package/dist/query-builder/base/expr-renderer-base.d.ts +7 -7
  12. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +3 -3
  13. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
  14. package/dist/query-builder/mssql/mssql-expr-renderer.js +5 -5
  15. package/dist/query-builder/mssql/mssql-query-builder.d.ts +2 -2
  16. package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
  17. package/dist/query-builder/mssql/mssql-query-builder.js +7 -7
  18. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +2 -2
  19. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
  20. package/dist/query-builder/mysql/mysql-expr-renderer.js +4 -4
  21. package/dist/query-builder/mysql/mysql-query-builder.d.ts +10 -10
  22. package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
  23. package/dist/query-builder/mysql/mysql-query-builder.js +4 -4
  24. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +2 -2
  25. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
  26. package/dist/query-builder/postgresql/postgresql-expr-renderer.js +4 -4
  27. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +8 -8
  28. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
  29. package/dist/query-builder/postgresql/postgresql-query-builder.js +7 -7
  30. package/dist/query-builder/query-builder.d.ts +1 -1
  31. package/dist/schema/factory/column-builder.d.ts +46 -46
  32. package/dist/schema/factory/column-builder.js +25 -25
  33. package/dist/schema/factory/index-builder.d.ts +22 -22
  34. package/dist/schema/factory/index-builder.js +14 -14
  35. package/dist/schema/factory/relation-builder.d.ts +93 -93
  36. package/dist/schema/factory/relation-builder.d.ts.map +1 -1
  37. package/dist/schema/factory/relation-builder.js +37 -37
  38. package/dist/schema/procedure-builder.d.ts +38 -38
  39. package/dist/schema/procedure-builder.d.ts.map +1 -1
  40. package/dist/schema/procedure-builder.js +26 -26
  41. package/dist/schema/table-builder.d.ts +38 -38
  42. package/dist/schema/table-builder.d.ts.map +1 -1
  43. package/dist/schema/table-builder.js +29 -29
  44. package/dist/schema/view-builder.d.ts +26 -26
  45. package/dist/schema/view-builder.d.ts.map +1 -1
  46. package/dist/schema/view-builder.js +18 -18
  47. package/dist/types/db.d.ts +40 -40
  48. package/dist/types/expr.d.ts +75 -75
  49. package/dist/types/expr.d.ts.map +1 -1
  50. package/dist/types/query-def.d.ts +32 -32
  51. package/dist/types/query-def.d.ts.map +1 -1
  52. package/docs/db-context.md +238 -0
  53. package/docs/expressions.md +413 -0
  54. package/docs/query-builder.md +198 -0
  55. package/docs/queryable.md +420 -0
  56. package/docs/schema-builders.md +216 -0
  57. package/docs/types-and-utilities.md +353 -0
  58. package/package.json +4 -3
  59. package/src/ddl/initialize.ts +16 -16
  60. package/src/ddl/table-ddl.ts +1 -1
  61. package/src/exec/queryable.ts +163 -163
  62. package/src/expr/expr.ts +257 -257
  63. package/src/query-builder/base/expr-renderer-base.ts +8 -8
  64. package/src/query-builder/mssql/mssql-expr-renderer.ts +20 -20
  65. package/src/query-builder/mssql/mssql-query-builder.ts +28 -28
  66. package/src/query-builder/mysql/mysql-expr-renderer.ts +22 -22
  67. package/src/query-builder/mysql/mysql-query-builder.ts +65 -65
  68. package/src/query-builder/postgresql/postgresql-expr-renderer.ts +15 -15
  69. package/src/query-builder/postgresql/postgresql-query-builder.ts +43 -43
  70. package/src/query-builder/query-builder.ts +1 -1
  71. package/src/schema/factory/column-builder.ts +48 -48
  72. package/src/schema/factory/index-builder.ts +22 -22
  73. package/src/schema/factory/relation-builder.ts +95 -95
  74. package/src/schema/procedure-builder.ts +38 -38
  75. package/src/schema/table-builder.ts +38 -38
  76. package/src/schema/view-builder.ts +28 -28
  77. package/src/types/db.ts +41 -41
  78. package/src/types/expr.ts +79 -79
  79. package/src/types/query-def.ts +37 -37
  80. package/tests/ddl/basic.expected.ts +8 -8
@@ -0,0 +1,198 @@
1
+ # Query Builder
2
+
3
+ Converts `QueryDef` AST objects into dialect-specific SQL strings for MySQL, MSSQL, and PostgreSQL.
4
+
5
+ ## API Reference
6
+
7
+ ### `createQueryBuilder(dialect)`
8
+
9
+ Factory function that returns a dialect-specific `QueryBuilderBase` instance.
10
+
11
+ ```typescript
12
+ function createQueryBuilder(dialect: Dialect): QueryBuilderBase
13
+ ```
14
+
15
+ **Parameters:**
16
+ - `dialect` -- `"mysql"` | `"mssql"` | `"postgresql"`
17
+
18
+ **Returns:** `MysqlQueryBuilder` | `MssqlQueryBuilder` | `PostgresqlQueryBuilder`
19
+
20
+ ---
21
+
22
+ ### `QueryBuilderBase`
23
+
24
+ Abstract base class for SQL rendering. Contains shared logic and dispatches to dialect-specific implementations.
25
+
26
+ #### `build(def)`
27
+
28
+ Convert any `QueryDef` to SQL.
29
+
30
+ ```typescript
31
+ build(def: QueryDef): QueryBuildResult
32
+ ```
33
+
34
+ **QueryBuildResult:**
35
+
36
+ ```typescript
37
+ interface QueryBuildResult {
38
+ sql: string;
39
+ resultSetIndex?: number; // Which result set to read (for multi-statement queries)
40
+ resultSetStride?: number; // Read every Nth result set
41
+ }
42
+ ```
43
+
44
+ ---
45
+
46
+ ### `ExprRendererBase`
47
+
48
+ Abstract base class for rendering `Expr` AST nodes to SQL strings.
49
+
50
+ #### Key Methods
51
+
52
+ | Method | Description |
53
+ |--------|-------------|
54
+ | `render(expr)` | Render any Expr or WhereExpr to SQL string |
55
+ | `renderWhere(exprs)` | Render array of WhereExpr joined with AND |
56
+ | `wrap(name)` | Wrap identifier (MySQL: `` `name` ``, MSSQL: `[name]`, PostgreSQL: `"name"`) |
57
+ | `escapeString(value)` | Escape string for SQL literal |
58
+ | `escapeValue(value)` | Escape any value to appropriate SQL literal |
59
+
60
+ ---
61
+
62
+ ### Dialect Implementations
63
+
64
+ #### `MysqlQueryBuilder` / `MysqlExprRenderer`
65
+
66
+ MySQL 8.0.14+ specific SQL generation.
67
+
68
+ - Identifier quoting: `` `name` ``
69
+ - NULL-safe equality: `<=>`
70
+ - LATERAL JOIN support
71
+ - `LIMIT offset, count` syntax
72
+
73
+ #### `MssqlQueryBuilder` / `MssqlExprRenderer`
74
+
75
+ Microsoft SQL Server 2012+ specific SQL generation.
76
+
77
+ - Identifier quoting: `[name]`
78
+ - Three-part naming: `[database].[schema].[name]`
79
+ - `CROSS APPLY` / `OUTER APPLY` instead of LATERAL
80
+ - `OFFSET ... FETCH NEXT` for pagination
81
+ - `IDENTITY_INSERT` handling
82
+
83
+ #### `PostgresqlQueryBuilder` / `PostgresqlExprRenderer`
84
+
85
+ PostgreSQL 9.0+ specific SQL generation.
86
+
87
+ - Identifier quoting: `"name"`
88
+ - `LATERAL` JOIN support
89
+ - `LIMIT ... OFFSET` syntax
90
+ - `RETURN QUERY` for procedures
91
+
92
+ ---
93
+
94
+ ### Supported QueryDef Types
95
+
96
+ The query builder handles all `QueryDef` union types:
97
+
98
+ #### DML
99
+
100
+ | Type | Description |
101
+ |------|-------------|
102
+ | `select` | SELECT query |
103
+ | `insert` | INSERT query |
104
+ | `insertIfNotExists` | Conditional INSERT |
105
+ | `insertInto` | INSERT INTO ... SELECT |
106
+ | `update` | UPDATE query |
107
+ | `delete` | DELETE query |
108
+ | `upsert` | INSERT or UPDATE (MERGE) |
109
+
110
+ #### DDL -- Table
111
+
112
+ | Type | Description |
113
+ |------|-------------|
114
+ | `createTable` | CREATE TABLE |
115
+ | `dropTable` | DROP TABLE |
116
+ | `renameTable` | RENAME TABLE |
117
+ | `truncate` | TRUNCATE TABLE |
118
+
119
+ #### DDL -- Column
120
+
121
+ | Type | Description |
122
+ |------|-------------|
123
+ | `addColumn` | ALTER TABLE ADD COLUMN |
124
+ | `dropColumn` | ALTER TABLE DROP COLUMN |
125
+ | `modifyColumn` | ALTER TABLE MODIFY COLUMN |
126
+ | `renameColumn` | ALTER TABLE RENAME COLUMN |
127
+
128
+ #### DDL -- Constraints
129
+
130
+ | Type | Description |
131
+ |------|-------------|
132
+ | `addPrimaryKey` | ADD PRIMARY KEY |
133
+ | `dropPrimaryKey` | DROP PRIMARY KEY |
134
+ | `addForeignKey` | ADD FOREIGN KEY |
135
+ | `dropForeignKey` | DROP FOREIGN KEY |
136
+ | `addIndex` | CREATE INDEX |
137
+ | `dropIndex` | DROP INDEX |
138
+
139
+ #### DDL -- View/Procedure
140
+
141
+ | Type | Description |
142
+ |------|-------------|
143
+ | `createView` | CREATE VIEW |
144
+ | `dropView` | DROP VIEW |
145
+ | `createProc` | CREATE PROCEDURE |
146
+ | `dropProc` | DROP PROCEDURE |
147
+ | `execProc` | EXECUTE PROCEDURE |
148
+
149
+ #### Utility
150
+
151
+ | Type | Description |
152
+ |------|-------------|
153
+ | `clearSchema` | Drop all objects in schema |
154
+ | `schemaExists` | Check schema existence |
155
+ | `switchFk` | Enable/disable FK constraints |
156
+
157
+ ---
158
+
159
+ ## Usage Examples
160
+
161
+ ### Build SQL from QueryDef
162
+
163
+ ```typescript
164
+ import { createQueryBuilder } from "@simplysm/orm-common";
165
+
166
+ const builder = createQueryBuilder("mysql");
167
+ const result = builder.build({
168
+ type: "select",
169
+ from: { database: "mydb", name: "User" },
170
+ as: "T1",
171
+ select: {
172
+ id: { type: "column", path: ["T1", "id"] },
173
+ name: { type: "column", path: ["T1", "name"] },
174
+ },
175
+ where: [{
176
+ type: "eq",
177
+ source: { type: "column", path: ["T1", "status"] },
178
+ target: { type: "value", value: "active" },
179
+ }],
180
+ });
181
+
182
+ console.log(result.sql);
183
+ // SELECT `T1`.`id` AS `id`, `T1`.`name` AS `name`
184
+ // FROM `mydb`.`User` AS `T1`
185
+ // WHERE `T1`.`status` <=> 'active'
186
+ ```
187
+
188
+ ### Multi-dialect Testing
189
+
190
+ ```typescript
191
+ import { createQueryBuilder, dialects } from "@simplysm/orm-common";
192
+
193
+ for (const dialect of dialects) {
194
+ const builder = createQueryBuilder(dialect);
195
+ const result = builder.build(queryDef);
196
+ console.log(`[${dialect}] ${result.sql}`);
197
+ }
198
+ ```
@@ -0,0 +1,420 @@
1
+ # Queryable
2
+
3
+ Chainable query builder for constructing type-safe SELECT, INSERT, UPDATE, DELETE, JOIN, GROUP BY, UNION, and recursive CTE queries.
4
+
5
+ ## API Reference
6
+
7
+ ### `Queryable<TData, TFrom>`
8
+
9
+ The core query builder class. Created automatically from DbContext table/view accessors (e.g., `db.user()`).
10
+
11
+ - `TData` -- Data type of the query result
12
+ - `TFrom` -- Source table builder (required for CUD operations; `never` for views/subqueries)
13
+
14
+ ---
15
+
16
+ ### SELECT / Projection
17
+
18
+ #### `.select(fn)`
19
+
20
+ Specify columns to SELECT with optional transformations.
21
+
22
+ ```typescript
23
+ select<R>(fn: (columns) => R): Queryable<UnwrapQueryableRecord<R>, never>
24
+ ```
25
+
26
+ ```typescript
27
+ db.user().select((u) => ({
28
+ userName: u.name,
29
+ upperEmail: expr.upper(u.email),
30
+ }))
31
+ ```
32
+
33
+ #### `.distinct()`
34
+
35
+ Apply DISTINCT to remove duplicate rows.
36
+
37
+ ```typescript
38
+ db.user().select((u) => ({ name: u.name })).distinct()
39
+ ```
40
+
41
+ #### `.lock()`
42
+
43
+ Apply row lock (`FOR UPDATE`) within a transaction.
44
+
45
+ ```typescript
46
+ db.user().where((u) => [expr.eq(u.id, 1)]).lock()
47
+ ```
48
+
49
+ ---
50
+
51
+ ### Filtering
52
+
53
+ #### `.where(predicate)`
54
+
55
+ Add WHERE conditions. Multiple calls are combined with AND.
56
+
57
+ ```typescript
58
+ where(predicate: (columns) => WhereExprUnit[]): Queryable<TData, TFrom>
59
+ ```
60
+
61
+ ```typescript
62
+ db.user()
63
+ .where((u) => [expr.eq(u.status, "active")])
64
+ .where((u) => [expr.gte(u.age, 18)])
65
+ ```
66
+
67
+ #### `.search(fn, searchText)`
68
+
69
+ Full-text search using LIKE patterns. Supports `+required`, `-excluded`, `"exact phrase"`, and `*wildcard` syntax.
70
+
71
+ ```typescript
72
+ db.user().search((u) => [u.name, u.email], 'John +active -deleted')
73
+ ```
74
+
75
+ ---
76
+
77
+ ### Sorting and Pagination
78
+
79
+ #### `.orderBy(fn, direction?)`
80
+
81
+ Add ORDER BY. Multiple calls add additional sort columns.
82
+
83
+ ```typescript
84
+ db.user()
85
+ .orderBy((u) => u.name)
86
+ .orderBy((u) => u.createdAt, "DESC")
87
+ ```
88
+
89
+ #### `.top(count)`
90
+
91
+ Select only top N rows. Can be used without ORDER BY.
92
+
93
+ ```typescript
94
+ db.user().top(10)
95
+ ```
96
+
97
+ #### `.limit(skip, take)`
98
+
99
+ Set LIMIT/OFFSET for pagination. Requires `orderBy()` first.
100
+
101
+ ```typescript
102
+ db.user()
103
+ .orderBy((u) => u.createdAt)
104
+ .limit(0, 20) // first 20 rows
105
+ ```
106
+
107
+ ---
108
+
109
+ ### Grouping
110
+
111
+ #### `.groupBy(fn)`
112
+
113
+ Add GROUP BY clause.
114
+
115
+ ```typescript
116
+ db.order()
117
+ .select((o) => ({
118
+ userId: o.userId,
119
+ totalAmount: expr.sum(o.amount),
120
+ }))
121
+ .groupBy((o) => [o.userId])
122
+ ```
123
+
124
+ #### `.having(predicate)`
125
+
126
+ Add HAVING clause (filter after GROUP BY).
127
+
128
+ ```typescript
129
+ db.order()
130
+ .select((o) => ({
131
+ userId: o.userId,
132
+ totalAmount: expr.sum(o.amount),
133
+ }))
134
+ .groupBy((o) => [o.userId])
135
+ .having((o) => [expr.gte(o.totalAmount, 10000)])
136
+ ```
137
+
138
+ ---
139
+
140
+ ### JOIN
141
+
142
+ #### `.join(as, fn)` -- 1:N JOIN
143
+
144
+ LEFT OUTER JOIN that adds results as an array property.
145
+
146
+ ```typescript
147
+ db.user().join("posts", (qr, u) =>
148
+ qr.from(Post).where((p) => [expr.eq(p.authorId, u.id)])
149
+ )
150
+ // Result: { id, name, posts: [{ id, title }, ...] }
151
+ ```
152
+
153
+ #### `.joinSingle(as, fn)` -- N:1 / 1:1 JOIN
154
+
155
+ LEFT OUTER JOIN that adds results as a single object property.
156
+
157
+ ```typescript
158
+ db.post().joinSingle("author", (qr, p) =>
159
+ qr.from(User).where((u) => [expr.eq(u.id, p.authorId)])
160
+ )
161
+ // Result: { id, title, author: { id, name } | undefined }
162
+ ```
163
+
164
+ #### `.include(fn)` -- Automatic Relation JOIN
165
+
166
+ Automatically JOIN based on relations defined in `TableBuilder.relations()`.
167
+
168
+ ```typescript
169
+ // Single relation
170
+ db.post().include((p) => p.author)
171
+
172
+ // Nested relation
173
+ db.post().include((p) => p.author.company)
174
+
175
+ // Multiple relations (chain include calls)
176
+ db.user()
177
+ .include((u) => u.company)
178
+ .include((u) => u.posts)
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Subquery and UNION
184
+
185
+ #### `.wrap()`
186
+
187
+ Wrap current Queryable as a subquery. Required before `count()` after `distinct()` or `groupBy()`.
188
+
189
+ ```typescript
190
+ const count = await db.user()
191
+ .select((u) => ({ name: u.name }))
192
+ .distinct()
193
+ .wrap()
194
+ .count();
195
+ ```
196
+
197
+ #### `Queryable.union(...queries)`
198
+
199
+ Combine multiple Queryables with UNION ALL.
200
+
201
+ ```typescript
202
+ const combined = Queryable.union(
203
+ db.user().where((u) => [expr.eq(u.type, "admin")]),
204
+ db.user().where((u) => [expr.eq(u.type, "manager")]),
205
+ );
206
+ ```
207
+
208
+ ---
209
+
210
+ ### Recursive CTE
211
+
212
+ #### `.recursive(fn)`
213
+
214
+ Build recursive Common Table Expressions for hierarchical data.
215
+
216
+ ```typescript
217
+ db.employee()
218
+ .where((e) => [expr.null(e.managerId)]) // base case: root nodes
219
+ .recursive((cte) =>
220
+ cte.from(Employee)
221
+ .where((e) => [expr.eq(e.managerId, e.self[0].id)])
222
+ )
223
+ ```
224
+
225
+ ---
226
+
227
+ ### Execution -- SELECT
228
+
229
+ #### `.execute()`
230
+
231
+ Execute SELECT and return result array.
232
+
233
+ ```typescript
234
+ const users: User[] = await db.user()
235
+ .where((u) => [expr.eq(u.isActive, true)])
236
+ .execute();
237
+ ```
238
+
239
+ #### `.single()`
240
+
241
+ Return single result. Throws if more than one result.
242
+
243
+ ```typescript
244
+ const user = await db.user()
245
+ .where((u) => [expr.eq(u.id, 1)])
246
+ .single();
247
+ // returns User | undefined
248
+ ```
249
+
250
+ #### `.first()`
251
+
252
+ Return first result (ignores additional results).
253
+
254
+ ```typescript
255
+ const latest = await db.user()
256
+ .orderBy((u) => u.createdAt, "DESC")
257
+ .first();
258
+ ```
259
+
260
+ #### `.count(fn?)`
261
+
262
+ Return row count. Cannot be used directly after `distinct()` or `groupBy()` (use `wrap()` first).
263
+
264
+ ```typescript
265
+ const count = await db.user()
266
+ .where((u) => [expr.eq(u.isActive, true)])
267
+ .count();
268
+ ```
269
+
270
+ #### `.exists()`
271
+
272
+ Check if any matching rows exist.
273
+
274
+ ```typescript
275
+ const hasAdmin = await db.user()
276
+ .where((u) => [expr.eq(u.role, "admin")])
277
+ .exists();
278
+ ```
279
+
280
+ ---
281
+
282
+ ### Execution -- INSERT
283
+
284
+ #### `.insert(records, outputColumns?)`
285
+
286
+ Insert records. Automatically chunks into batches of 1000 (MSSQL limit).
287
+
288
+ ```typescript
289
+ // Simple insert
290
+ await db.user().insert([
291
+ { name: "Alice", email: "alice@test.com" },
292
+ { name: "Bob" },
293
+ ]);
294
+
295
+ // Insert with output (get auto-generated IDs)
296
+ const inserted = await db.user().insert(
297
+ [{ name: "Alice" }],
298
+ ["id"],
299
+ );
300
+ // inserted[0].id
301
+ ```
302
+
303
+ #### `.insertIfNotExists(record, outputColumns?)`
304
+
305
+ Insert only if WHERE condition matches no rows.
306
+
307
+ ```typescript
308
+ await db.user()
309
+ .where((u) => [expr.eq(u.email, "test@test.com")])
310
+ .insertIfNotExists({ name: "Test", email: "test@test.com" });
311
+ ```
312
+
313
+ #### `.insertInto(targetTable, outputColumns?)`
314
+
315
+ INSERT INTO ... SELECT (copy current query results into another table).
316
+
317
+ ```typescript
318
+ await db.user()
319
+ .select((u) => ({ name: u.name, createdAt: u.createdAt }))
320
+ .where((u) => [expr.eq(u.isArchived, false)])
321
+ .insertInto(ArchivedUser);
322
+ ```
323
+
324
+ ---
325
+
326
+ ### Execution -- UPDATE
327
+
328
+ #### `.update(recordFn, outputColumns?)`
329
+
330
+ Update matching rows. The callback receives current column values for reference.
331
+
332
+ ```typescript
333
+ await db.user()
334
+ .where((u) => [expr.eq(u.id, 1)])
335
+ .update(() => ({
336
+ name: expr.val("string", "New Name"),
337
+ }));
338
+ ```
339
+
340
+ ---
341
+
342
+ ### Execution -- DELETE
343
+
344
+ #### `.delete(outputColumns?)`
345
+
346
+ Delete matching rows.
347
+
348
+ ```typescript
349
+ await db.user()
350
+ .where((u) => [expr.eq(u.status, "deleted")])
351
+ .delete();
352
+ ```
353
+
354
+ ---
355
+
356
+ ### Execution -- UPSERT
357
+
358
+ #### `.upsert(record, outputColumns?)`
359
+
360
+ INSERT or UPDATE (MERGE pattern). Requires a WHERE condition to check existence.
361
+
362
+ ```typescript
363
+ await db.user()
364
+ .where((u) => [expr.eq(u.email, "test@test.com")])
365
+ .upsert({
366
+ insert: { name: "Test", email: "test@test.com" },
367
+ update: { name: expr.val("string", "Updated") },
368
+ });
369
+ ```
370
+
371
+ ---
372
+
373
+ ### QueryDef Accessors
374
+
375
+ Each execution method has a corresponding `get*QueryDef()` method that returns the raw `QueryDef` without executing it:
376
+
377
+ - `getSelectQueryDef()` -- Returns `SelectQueryDef`
378
+ - `getInsertQueryDef(records, outputColumns?)` -- Returns `InsertQueryDef`
379
+ - `getInsertIfNotExistsQueryDef(record, outputColumns?)` -- Returns `InsertIfNotExistsQueryDef`
380
+ - `getInsertIntoQueryDef(targetTable, outputColumns?)` -- Returns `InsertIntoQueryDef`
381
+ - `getResultMeta(outputColumns?)` -- Returns `ResultMeta` for type parsing
382
+
383
+ ---
384
+
385
+ ## Usage Examples
386
+
387
+ ### Complex Query with Multiple Features
388
+
389
+ ```typescript
390
+ const result = await db.order()
391
+ .include((o) => o.customer)
392
+ .where((o) => [
393
+ expr.gte(o.createdAt, expr.val("DateTime", startDate)),
394
+ expr.eq(o.status, "completed"),
395
+ ])
396
+ .select((o) => ({
397
+ orderId: o.id,
398
+ customerName: o.customer.name,
399
+ total: o.totalAmount,
400
+ }))
401
+ .orderBy((o) => o.total, "DESC")
402
+ .limit(0, 50)
403
+ .execute();
404
+ ```
405
+
406
+ ### Aggregation with GROUP BY
407
+
408
+ ```typescript
409
+ const stats = await db.order()
410
+ .select((o) => ({
411
+ month: expr.month(o.createdAt),
412
+ year: expr.year(o.createdAt),
413
+ totalRevenue: expr.sum(o.amount),
414
+ orderCount: expr.count(),
415
+ }))
416
+ .groupBy((o) => [o.month, o.year])
417
+ .orderBy((o) => o.year)
418
+ .orderBy((o) => o.month)
419
+ .execute();
420
+ ```