@simplysm/orm-common 13.0.85 → 13.0.87
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.
- package/README.md +65 -59
- package/docs/ddl.md +195 -0
- package/docs/query.md +469 -0
- package/docs/schema.md +238 -0
- package/package.json +2 -2
- package/docs/db-context.md +0 -238
- package/docs/expressions.md +0 -413
- package/docs/query-builder.md +0 -198
- package/docs/queryable.md +0 -420
- package/docs/schema-builders.md +0 -216
- package/docs/types-and-utilities.md +0 -353
package/docs/schema-builders.md
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
# Schema Builders
|
|
2
|
-
|
|
3
|
-
Define database tables, views, and stored procedures with a fluent, type-safe API.
|
|
4
|
-
|
|
5
|
-
## API Reference
|
|
6
|
-
|
|
7
|
-
### `Table(name)`
|
|
8
|
-
|
|
9
|
-
Factory function that creates a `TableBuilder` for defining table schemas.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
function Table(name: string): TableBuilder<{}, {}>
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
#### TableBuilder Methods
|
|
16
|
-
|
|
17
|
-
| Method | Signature | Description |
|
|
18
|
-
|--------|-----------|-------------|
|
|
19
|
-
| `description(desc)` | `.description(desc: string)` | Set table description (DDL comment) |
|
|
20
|
-
| `database(db)` | `.database(db: string)` | Set database name |
|
|
21
|
-
| `schema(schema)` | `.schema(schema: string)` | Set schema name (MSSQL: `dbo`, PostgreSQL: `public`) |
|
|
22
|
-
| `columns(fn)` | `.columns((c) => ({...}))` | Define columns using column factory |
|
|
23
|
-
| `primaryKey(...cols)` | `.primaryKey("col1", "col2")` | Set primary key (single or composite) |
|
|
24
|
-
| `indexes(fn)` | `.indexes((i) => [...])` | Define indexes |
|
|
25
|
-
| `relations(fn)` | `.relations((r) => ({...}))` | Define relationships (FK, reverse FK, logical relations) |
|
|
26
|
-
|
|
27
|
-
#### Type Inference Properties
|
|
28
|
-
|
|
29
|
-
| Property | Description |
|
|
30
|
-
|----------|-------------|
|
|
31
|
-
| `$inferSelect` | Full type (columns + deep relations) |
|
|
32
|
-
| `$inferColumns` | Columns only |
|
|
33
|
-
| `$inferInsert` | Insert type (autoIncrement/nullable/default fields are optional) |
|
|
34
|
-
| `$inferUpdate` | Update type (all fields optional) |
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
### `View(name)`
|
|
39
|
-
|
|
40
|
-
Factory function that creates a `ViewBuilder` for defining database views.
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
function View(name: string): ViewBuilder<any, {}, {}>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
#### ViewBuilder Methods
|
|
47
|
-
|
|
48
|
-
| Method | Signature | Description |
|
|
49
|
-
|--------|-----------|-------------|
|
|
50
|
-
| `description(desc)` | `.description(desc: string)` | Set view description |
|
|
51
|
-
| `database(db)` | `.database(db: string)` | Set database name |
|
|
52
|
-
| `schema(schema)` | `.schema(schema: string)` | Set schema name |
|
|
53
|
-
| `query(viewFn)` | `.query((db) => db.table().select(...))` | Define view SELECT query |
|
|
54
|
-
| `relations(fn)` | `.relations((r) => ({...}))` | Define relationships (logical only, no FK) |
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
### `Procedure(name)`
|
|
59
|
-
|
|
60
|
-
Factory function that creates a `ProcedureBuilder` for defining stored procedures.
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
function Procedure(name: string): ProcedureBuilder<never, never>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
#### ProcedureBuilder Methods
|
|
67
|
-
|
|
68
|
-
| Method | Signature | Description |
|
|
69
|
-
|--------|-----------|-------------|
|
|
70
|
-
| `description(desc)` | `.description(desc: string)` | Set procedure description |
|
|
71
|
-
| `database(db)` | `.database(db: string)` | Set database name |
|
|
72
|
-
| `schema(schema)` | `.schema(schema: string)` | Set schema name |
|
|
73
|
-
| `params(fn)` | `.params((c) => ({...}))` | Define input parameters |
|
|
74
|
-
| `returns(fn)` | `.returns((c) => ({...}))` | Define return columns |
|
|
75
|
-
| `body(sql)` | `.body("SELECT ...")` | Set procedure body SQL |
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
### Column Factory
|
|
80
|
-
|
|
81
|
-
The column factory (`c`) is provided inside `.columns()` and `.params()`/`.returns()` callbacks.
|
|
82
|
-
|
|
83
|
-
#### Column Types
|
|
84
|
-
|
|
85
|
-
| Method | SQL Type | TypeScript Type | Notes |
|
|
86
|
-
|--------|----------|-----------------|-------|
|
|
87
|
-
| `c.int()` | INT | `number` | 4 bytes |
|
|
88
|
-
| `c.bigint()` | BIGINT | `number` | 8 bytes |
|
|
89
|
-
| `c.float()` | FLOAT | `number` | Single precision |
|
|
90
|
-
| `c.double()` | DOUBLE | `number` | Double precision |
|
|
91
|
-
| `c.decimal(p, s)` | DECIMAL(p,s) | `number` | Fixed-point |
|
|
92
|
-
| `c.varchar(len)` | VARCHAR(len) | `string` | Variable-length string |
|
|
93
|
-
| `c.char(len)` | CHAR(len) | `string` | Fixed-length string |
|
|
94
|
-
| `c.text()` | TEXT | `string` | Large text |
|
|
95
|
-
| `c.binary()` | BLOB/VARBINARY/BYTEA | `Bytes` | Binary data |
|
|
96
|
-
| `c.boolean()` | TINYINT(1)/BIT/BOOLEAN | `boolean` | |
|
|
97
|
-
| `c.datetime()` | DATETIME | `DateTime` | Date + time |
|
|
98
|
-
| `c.date()` | DATE | `DateOnly` | Date only |
|
|
99
|
-
| `c.time()` | TIME | `Time` | Time only |
|
|
100
|
-
| `c.uuid()` | BINARY(16)/UNIQUEIDENTIFIER/UUID | `Uuid` | |
|
|
101
|
-
|
|
102
|
-
#### Column Modifiers
|
|
103
|
-
|
|
104
|
-
| Method | Description |
|
|
105
|
-
|--------|-------------|
|
|
106
|
-
| `.autoIncrement()` | Auto-increment (optional in INSERT inference) |
|
|
107
|
-
| `.nullable()` | Allow NULL (adds `undefined` to type) |
|
|
108
|
-
| `.default(value)` | Set default value (optional in INSERT inference) |
|
|
109
|
-
| `.description(desc)` | Set column comment |
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### Index Factory
|
|
114
|
-
|
|
115
|
-
The index factory (`i`) is provided inside `.indexes()` callbacks.
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
i.index("col1", "col2") // Create index on columns
|
|
119
|
-
.unique() // Make unique
|
|
120
|
-
.orderBy("ASC", "DESC") // Set sort order per column
|
|
121
|
-
.name("IX_Custom_Name") // Custom index name
|
|
122
|
-
.description("desc") // Description
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
### Relation Factory
|
|
128
|
-
|
|
129
|
-
The relation factory (`r`) is provided inside `.relations()` callbacks.
|
|
130
|
-
|
|
131
|
-
| Method | Type | Description |
|
|
132
|
-
|--------|------|-------------|
|
|
133
|
-
| `r.foreignKey(cols, targetFn)` | N:1 | FK constraint created in DB |
|
|
134
|
-
| `r.foreignKeyTarget(targetFn, relName)` | 1:N | Reverse FK reference (array by default) |
|
|
135
|
-
| `r.relationKey(cols, targetFn)` | N:1 | Logical relation (no DB FK) |
|
|
136
|
-
| `r.relationKeyTarget(targetFn, relName)` | 1:N | Logical reverse reference |
|
|
137
|
-
|
|
138
|
-
Both `foreignKeyTarget` and `relationKeyTarget` support `.single()` to indicate a 1:1 relationship (returns single object instead of array).
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Usage Examples
|
|
143
|
-
|
|
144
|
-
### Complete Table Definition
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
const User = Table("User")
|
|
148
|
-
.database("mydb")
|
|
149
|
-
.description("Application users")
|
|
150
|
-
.columns((c) => ({
|
|
151
|
-
id: c.bigint().autoIncrement(),
|
|
152
|
-
name: c.varchar(100),
|
|
153
|
-
email: c.varchar(200).nullable(),
|
|
154
|
-
status: c.varchar(20).default("active"),
|
|
155
|
-
createdAt: c.datetime().default("CURRENT_TIMESTAMP"),
|
|
156
|
-
}))
|
|
157
|
-
.primaryKey("id")
|
|
158
|
-
.indexes((i) => [
|
|
159
|
-
i.index("email").unique(),
|
|
160
|
-
i.index("status", "createdAt").orderBy("ASC", "DESC"),
|
|
161
|
-
]);
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Table with Relations
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
const Post = Table("Post")
|
|
168
|
-
.columns((c) => ({
|
|
169
|
-
id: c.bigint().autoIncrement(),
|
|
170
|
-
authorId: c.bigint(),
|
|
171
|
-
title: c.varchar(200),
|
|
172
|
-
}))
|
|
173
|
-
.primaryKey("id")
|
|
174
|
-
.relations((r) => ({
|
|
175
|
-
author: r.foreignKey(["authorId"], () => User),
|
|
176
|
-
}));
|
|
177
|
-
|
|
178
|
-
const User = Table("User")
|
|
179
|
-
.columns((c) => ({
|
|
180
|
-
id: c.bigint().autoIncrement(),
|
|
181
|
-
name: c.varchar(100),
|
|
182
|
-
}))
|
|
183
|
-
.primaryKey("id")
|
|
184
|
-
.relations((r) => ({
|
|
185
|
-
posts: r.foreignKeyTarget(() => Post, "author"),
|
|
186
|
-
profile: r.foreignKeyTarget(() => Profile, "user").single(),
|
|
187
|
-
}));
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### View Definition
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
const ActiveUsers = View("ActiveUsers")
|
|
194
|
-
.database("mydb")
|
|
195
|
-
.query((db: MyDb) =>
|
|
196
|
-
db.user()
|
|
197
|
-
.where((u) => [expr.eq(u.status, "active")])
|
|
198
|
-
.select((u) => ({ id: u.id, name: u.name, email: u.email }))
|
|
199
|
-
);
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Procedure Definition
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
const GetUserById = Procedure("GetUserById")
|
|
206
|
-
.database("mydb")
|
|
207
|
-
.params((c) => ({
|
|
208
|
-
userId: c.bigint(),
|
|
209
|
-
}))
|
|
210
|
-
.returns((c) => ({
|
|
211
|
-
id: c.bigint(),
|
|
212
|
-
name: c.varchar(100),
|
|
213
|
-
email: c.varchar(200),
|
|
214
|
-
}))
|
|
215
|
-
.body("SELECT id, name, email FROM User WHERE id = userId");
|
|
216
|
-
```
|
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
# Types and Utilities
|
|
2
|
-
|
|
3
|
-
Core type definitions, error handling, search parsing, and result parsing utilities.
|
|
4
|
-
|
|
5
|
-
## API Reference
|
|
6
|
-
|
|
7
|
-
### Column Types
|
|
8
|
-
|
|
9
|
-
#### `DataType`
|
|
10
|
-
|
|
11
|
-
SQL data type definition used in column metadata.
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
type DataType =
|
|
15
|
-
| { type: "int" }
|
|
16
|
-
| { type: "bigint" }
|
|
17
|
-
| { type: "float" }
|
|
18
|
-
| { type: "double" }
|
|
19
|
-
| { type: "decimal"; precision: number; scale?: number }
|
|
20
|
-
| { type: "varchar"; length: number }
|
|
21
|
-
| { type: "char"; length: number }
|
|
22
|
-
| { type: "text" }
|
|
23
|
-
| { type: "binary" }
|
|
24
|
-
| { type: "boolean" }
|
|
25
|
-
| { type: "datetime" }
|
|
26
|
-
| { type: "date" }
|
|
27
|
-
| { type: "time" }
|
|
28
|
-
| { type: "uuid" };
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
#### `ColumnPrimitive`
|
|
32
|
-
|
|
33
|
-
All primitive TypeScript types that can be stored in columns. `undefined` represents NULL.
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
type ColumnPrimitive = string | number | boolean | DateTime | DateOnly | Time | Uuid | Bytes | undefined;
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
#### `ColumnPrimitiveStr`
|
|
40
|
-
|
|
41
|
-
String keys for column primitive type mapping.
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
type ColumnPrimitiveStr = "string" | "number" | "boolean" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Bytes";
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
#### `ColumnMeta`
|
|
48
|
-
|
|
49
|
-
Column metadata generated by `ColumnBuilder`.
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
interface ColumnMeta {
|
|
53
|
-
type: ColumnPrimitiveStr;
|
|
54
|
-
dataType: DataType;
|
|
55
|
-
autoIncrement?: boolean;
|
|
56
|
-
nullable?: boolean;
|
|
57
|
-
default?: ColumnPrimitive;
|
|
58
|
-
description?: string;
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
#### `inferColumnPrimitiveStr(value)`
|
|
63
|
-
|
|
64
|
-
Infer `ColumnPrimitiveStr` from a runtime value.
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
function inferColumnPrimitiveStr(value: ColumnPrimitive): ColumnPrimitiveStr
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
inferColumnPrimitiveStr("hello") // "string"
|
|
72
|
-
inferColumnPrimitiveStr(123) // "number"
|
|
73
|
-
inferColumnPrimitiveStr(new DateTime()) // "DateTime"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
#### `dataTypeStrToColumnPrimitiveStr`
|
|
77
|
-
|
|
78
|
-
Mapping from SQL type strings to TypeScript type names.
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
dataTypeStrToColumnPrimitiveStr["int"] // "number"
|
|
82
|
-
dataTypeStrToColumnPrimitiveStr["varchar"] // "string"
|
|
83
|
-
dataTypeStrToColumnPrimitiveStr["datetime"] // "DateTime"
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
### Database Types
|
|
89
|
-
|
|
90
|
-
#### `Dialect`
|
|
91
|
-
|
|
92
|
-
Supported database dialects.
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
type Dialect = "mysql" | "mssql" | "postgresql";
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
#### `dialects`
|
|
99
|
-
|
|
100
|
-
Array of all supported dialects (useful for testing).
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
const dialects: Dialect[] = ["mysql", "mssql", "postgresql"];
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
#### `IsolationLevel`
|
|
107
|
-
|
|
108
|
-
Transaction isolation levels.
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
type IsolationLevel =
|
|
112
|
-
| "READ_UNCOMMITTED"
|
|
113
|
-
| "READ_COMMITTED"
|
|
114
|
-
| "REPEATABLE_READ"
|
|
115
|
-
| "SERIALIZABLE";
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
#### `DataRecord`
|
|
119
|
-
|
|
120
|
-
Recursive type for query result records (supports nested relations).
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
type DataRecord = {
|
|
124
|
-
[key: string]: ColumnPrimitive | DataRecord | DataRecord[];
|
|
125
|
-
};
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
#### `ResultMeta`
|
|
129
|
-
|
|
130
|
-
Metadata for transforming raw query results into typed TypeScript objects.
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
interface ResultMeta {
|
|
134
|
-
columns: Record<string, ColumnPrimitiveStr>;
|
|
135
|
-
joins: Record<string, { isSingle: boolean }>;
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
#### `QueryBuildResult`
|
|
140
|
-
|
|
141
|
-
Result of building a QueryDef into SQL.
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
interface QueryBuildResult {
|
|
145
|
-
sql: string;
|
|
146
|
-
resultSetIndex?: number;
|
|
147
|
-
resultSetStride?: number;
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### `Migration`
|
|
152
|
-
|
|
153
|
-
Database migration definition.
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
interface Migration {
|
|
157
|
-
name: string;
|
|
158
|
-
up: (db: DbContextBase & DbContextDdlMethods) => Promise<void>;
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
### Error Handling
|
|
165
|
-
|
|
166
|
-
#### `DbTransactionError`
|
|
167
|
-
|
|
168
|
-
Standardized database transaction error with DBMS-independent error codes.
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
class DbTransactionError extends Error {
|
|
172
|
-
readonly name = "DbTransactionError";
|
|
173
|
-
readonly code: DbErrorCode;
|
|
174
|
-
readonly originalError?: unknown;
|
|
175
|
-
|
|
176
|
-
constructor(code: DbErrorCode, message: string, originalError?: unknown);
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### `DbErrorCode`
|
|
181
|
-
|
|
182
|
-
Transaction-related error codes.
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
enum DbErrorCode {
|
|
186
|
-
NO_ACTIVE_TRANSACTION = "NO_ACTIVE_TRANSACTION",
|
|
187
|
-
TRANSACTION_ALREADY_STARTED = "TRANSACTION_ALREADY_STARTED",
|
|
188
|
-
DEADLOCK = "DEADLOCK",
|
|
189
|
-
LOCK_TIMEOUT = "LOCK_TIMEOUT",
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
try {
|
|
195
|
-
await executor.rollbackTransaction();
|
|
196
|
-
} catch (err) {
|
|
197
|
-
if (err instanceof DbTransactionError) {
|
|
198
|
-
if (err.code === DbErrorCode.NO_ACTIVE_TRANSACTION) {
|
|
199
|
-
return; // Already rolled back, safe to ignore
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
throw err;
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
### Search Parser
|
|
209
|
-
|
|
210
|
-
#### `parseSearchQuery(searchText)`
|
|
211
|
-
|
|
212
|
-
Parse a user search string into structured SQL LIKE patterns.
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
function parseSearchQuery(searchText: string): ParsedSearchQuery
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
interface ParsedSearchQuery {
|
|
220
|
-
or: string[]; // General terms (OR condition)
|
|
221
|
-
must: string[]; // Required terms (AND condition, + prefix or quotes)
|
|
222
|
-
not: string[]; // Excluded terms (NOT condition, - prefix)
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Search Syntax:**
|
|
227
|
-
|
|
228
|
-
| Syntax | Meaning | Example |
|
|
229
|
-
|--------|---------|---------|
|
|
230
|
-
| `term1 term2` | OR (match any) | `apple banana` |
|
|
231
|
-
| `+term` | Required (AND) | `+apple +banana` |
|
|
232
|
-
| `-term` | Excluded (NOT) | `apple -banana` |
|
|
233
|
-
| `"exact phrase"` | Exact match (required) | `"delicious fruit"` |
|
|
234
|
-
| `*` | Wildcard | `app*` -> `app%` |
|
|
235
|
-
|
|
236
|
-
**Escape sequences:** `\\` (literal `\`), `\*` (literal `*`), `\%` (literal `%`), `\"` (literal `"`), `\+` (literal `+`), `\-` (literal `-`)
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
parseSearchQuery('apple "delicious fruit" -banana +strawberry')
|
|
240
|
-
// {
|
|
241
|
-
// or: ["%apple%"],
|
|
242
|
-
// must: ["%delicious fruit%", "%strawberry%"],
|
|
243
|
-
// not: ["%banana%"]
|
|
244
|
-
// }
|
|
245
|
-
|
|
246
|
-
parseSearchQuery('app* test')
|
|
247
|
-
// {
|
|
248
|
-
// or: ["app%", "%test%"],
|
|
249
|
-
// must: [],
|
|
250
|
-
// not: []
|
|
251
|
-
// }
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
### Result Parser
|
|
257
|
-
|
|
258
|
-
#### `parseQueryResult(rawResults, meta)`
|
|
259
|
-
|
|
260
|
-
Transform raw database query results into typed TypeScript objects. Handles type conversion, nested JOIN result grouping, and deduplication.
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
async function parseQueryResult<TRecord>(
|
|
264
|
-
rawResults: Record<string, unknown>[],
|
|
265
|
-
meta: ResultMeta,
|
|
266
|
-
): Promise<TRecord[] | undefined>
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**Features:**
|
|
270
|
-
- Type conversion (string to number, string to DateTime, etc.)
|
|
271
|
-
- Flat-to-nested object transformation (`"posts.id"` -> `{ posts: { id } }`)
|
|
272
|
-
- JOIN result grouping with deduplication
|
|
273
|
-
- Single vs array relationship handling (`isSingle`)
|
|
274
|
-
- Event loop yielding for large datasets (every 100 records)
|
|
275
|
-
- Returns `undefined` for empty results
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
// Simple type parsing
|
|
279
|
-
const raw = [{ id: "1", createdAt: "2026-01-07T10:00:00.000Z" }];
|
|
280
|
-
const meta = { columns: { id: "number", createdAt: "DateTime" }, joins: {} };
|
|
281
|
-
const result = await parseQueryResult(raw, meta);
|
|
282
|
-
// [{ id: 1, createdAt: DateTime(...) }]
|
|
283
|
-
|
|
284
|
-
// JOIN result nesting
|
|
285
|
-
const raw = [
|
|
286
|
-
{ id: 1, name: "Alice", "posts.id": 10, "posts.title": "Post1" },
|
|
287
|
-
{ id: 1, name: "Alice", "posts.id": 11, "posts.title": "Post2" },
|
|
288
|
-
];
|
|
289
|
-
const meta = {
|
|
290
|
-
columns: { id: "number", name: "string", "posts.id": "number", "posts.title": "string" },
|
|
291
|
-
joins: { posts: { isSingle: false } },
|
|
292
|
-
};
|
|
293
|
-
const result = await parseQueryResult(raw, meta);
|
|
294
|
-
// [{ id: 1, name: "Alice", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
---
|
|
298
|
-
|
|
299
|
-
### QueryDef Types
|
|
300
|
-
|
|
301
|
-
#### `QueryDefObjectName`
|
|
302
|
-
|
|
303
|
-
Database object name with optional namespace.
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
interface QueryDefObjectName {
|
|
307
|
-
database?: string;
|
|
308
|
-
schema?: string;
|
|
309
|
-
name: string;
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
#### `QueryDef`
|
|
314
|
-
|
|
315
|
-
Union type of all query definitions (DML + DDL + utility).
|
|
316
|
-
|
|
317
|
-
Key DML types:
|
|
318
|
-
|
|
319
|
-
| Type | Interface | Description |
|
|
320
|
-
|------|-----------|-------------|
|
|
321
|
-
| `"select"` | `SelectQueryDef` | SELECT with FROM, WHERE, JOIN, ORDER BY, GROUP BY, HAVING, LIMIT, WITH |
|
|
322
|
-
| `"insert"` | `InsertQueryDef` | INSERT with records, output, overrideIdentity |
|
|
323
|
-
| `"insertIfNotExists"` | `InsertIfNotExistsQueryDef` | Conditional INSERT |
|
|
324
|
-
| `"insertInto"` | `InsertIntoQueryDef` | INSERT INTO ... SELECT |
|
|
325
|
-
| `"update"` | `UpdateQueryDef` | UPDATE with JOIN support |
|
|
326
|
-
| `"delete"` | `DeleteQueryDef` | DELETE with JOIN support |
|
|
327
|
-
| `"upsert"` | `UpsertQueryDef` | INSERT or UPDATE (MERGE) |
|
|
328
|
-
|
|
329
|
-
#### `DDL_TYPES`
|
|
330
|
-
|
|
331
|
-
Constant array of all DDL query type strings. Used to prevent DDL execution inside transactions.
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
const DDL_TYPES: readonly string[]
|
|
335
|
-
// ["clearSchema", "createTable", "dropTable", "renameTable", "truncate",
|
|
336
|
-
// "addColumn", "dropColumn", "modifyColumn", "renameColumn",
|
|
337
|
-
// "dropPrimaryKey", "addPrimaryKey", "addForeignKey", "dropForeignKey",
|
|
338
|
-
// "addIndex", "dropIndex", "createView", "dropView", "createProc", "dropProc"]
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
### Type Inference Utilities
|
|
344
|
-
|
|
345
|
-
| Type | Description |
|
|
346
|
-
|------|-------------|
|
|
347
|
-
| `InferColumns<T>` | Infer value types from ColumnBuilderRecord |
|
|
348
|
-
| `InferInsertColumns<T>` | Infer INSERT type (required + optional fields) |
|
|
349
|
-
| `InferUpdateColumns<T>` | Infer UPDATE type (all fields optional) |
|
|
350
|
-
| `InferColumnExprs<T>` | Infer expression input types |
|
|
351
|
-
| `InferDeepRelations<T>` | Infer nested relation types (all optional) |
|
|
352
|
-
| `ExtractRelationTarget<T>` | Extract N:1 relation target type |
|
|
353
|
-
| `ExtractRelationTargetResult<T>` | Extract 1:N relation target type (array or single) |
|