@simplysm/orm-common 14.0.1 → 14.0.4
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 +135 -0
- package/dist/exec/queryable.js +18 -18
- package/dist/exec/queryable.js.map +1 -1
- package/dist/expr/expr.d.ts +102 -102
- package/dist/expr/expr.js +105 -105
- package/dist/expr/expr.js.map +1 -1
- package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +1 -1
- package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/mssql/mssql-expr-renderer.js +17 -17
- package/dist/query-builder/mssql/mssql-expr-renderer.js.map +1 -1
- package/dist/query-builder/mssql/mssql-query-builder.d.ts +2 -2
- package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
- package/dist/query-builder/mssql/mssql-query-builder.js +26 -26
- package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -1
- package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +1 -1
- package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/mysql/mysql-expr-renderer.js +14 -14
- package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -1
- package/dist/query-builder/mysql/mysql-query-builder.d.ts +10 -10
- package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
- package/dist/query-builder/mysql/mysql-query-builder.js +67 -67
- package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -1
- package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +1 -1
- package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/postgresql/postgresql-expr-renderer.js +13 -13
- package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -1
- package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +8 -8
- package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
- package/dist/query-builder/postgresql/postgresql-query-builder.js +47 -47
- package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -1
- package/dist/schema/factory/relation-builder.d.ts +8 -8
- package/dist/schema/factory/relation-builder.js +9 -9
- package/dist/schema/factory/relation-builder.js.map +1 -1
- package/dist/schema/view-builder.js +2 -2
- package/dist/schema/view-builder.js.map +1 -1
- package/dist/types/column.d.ts +21 -21
- package/dist/types/column.js +5 -5
- package/dist/utils/result-parser.d.ts +11 -11
- package/dist/utils/result-parser.js +48 -48
- package/dist/utils/result-parser.js.map +1 -1
- package/docs/core.md +206 -0
- package/docs/expression.md +217 -0
- package/docs/query-builder.md +126 -0
- package/docs/queryable.md +236 -0
- package/docs/schema-builders.md +352 -0
- package/docs/types.md +501 -0
- package/package.json +7 -3
- package/src/exec/queryable.ts +18 -18
- package/src/expr/expr.ts +105 -105
- package/src/query-builder/mssql/mssql-expr-renderer.ts +17 -17
- package/src/query-builder/mssql/mssql-query-builder.ts +26 -26
- package/src/query-builder/mysql/mysql-expr-renderer.ts +14 -14
- package/src/query-builder/mysql/mysql-query-builder.ts +67 -67
- package/src/query-builder/postgresql/postgresql-expr-renderer.ts +13 -13
- package/src/query-builder/postgresql/postgresql-query-builder.ts +47 -47
- package/src/schema/factory/relation-builder.ts +9 -9
- package/src/schema/view-builder.ts +2 -2
- package/src/types/column.ts +23 -23
- package/src/utils/result-parser.ts +49 -49
package/docs/types.md
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# Types
|
|
2
|
+
|
|
3
|
+
Core type definitions for the ORM.
|
|
4
|
+
|
|
5
|
+
## Dialect
|
|
6
|
+
|
|
7
|
+
Supported database dialects.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
type Dialect = "mysql" | "mssql" | "postgresql";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Constant:**
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
const dialects: Dialect[] = ["mysql", "mssql", "postgresql"];
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## IsolationLevel
|
|
20
|
+
|
|
21
|
+
Transaction isolation levels.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
type IsolationLevel =
|
|
25
|
+
| "READ_UNCOMMITTED"
|
|
26
|
+
| "READ_COMMITTED"
|
|
27
|
+
| "REPEATABLE_READ"
|
|
28
|
+
| "SERIALIZABLE";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## DataRecord
|
|
32
|
+
|
|
33
|
+
Recursive data record type for query results. Supports nested relations.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
type DataRecord = {
|
|
37
|
+
[key: string]: ColumnPrimitive | DataRecord | DataRecord[];
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## DbContextExecutor
|
|
42
|
+
|
|
43
|
+
Interface for DB connection and query execution. Implemented by `NodeDbContextExecutor` (server) or service-based executors (client).
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface DbContextExecutor {
|
|
47
|
+
connect(): Promise<void>;
|
|
48
|
+
close(): Promise<void>;
|
|
49
|
+
beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
|
|
50
|
+
commitTransaction(): Promise<void>;
|
|
51
|
+
rollbackTransaction(): Promise<void>;
|
|
52
|
+
executeDefs<T = DataRecord>(
|
|
53
|
+
defs: QueryDef[],
|
|
54
|
+
resultMetas?: (ResultMeta | undefined)[],
|
|
55
|
+
): Promise<T[][]>;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## ResultMeta
|
|
60
|
+
|
|
61
|
+
Metadata for transforming raw query results into typed TypeScript objects.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface ResultMeta {
|
|
65
|
+
columns: Record<string, ColumnPrimitiveStr>;
|
|
66
|
+
joins: Record<string, { isSingle: boolean }>;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Field | Description |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `columns` | Maps column name (dot-notation for nested) to TypeScript type name |
|
|
73
|
+
| `joins` | Maps JOIN alias to single/array indicator |
|
|
74
|
+
|
|
75
|
+
## Migration
|
|
76
|
+
|
|
77
|
+
Database migration definition for schema versioning.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
interface Migration {
|
|
81
|
+
name: string;
|
|
82
|
+
up: (db: DbContextBase & DbContextDdlMethods) => Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
| Field | Type | Description |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `name` | `string` | Unique migration name (timestamp recommended) |
|
|
89
|
+
| `up` | `(db) => Promise<void>` | Migration function with DDL access |
|
|
90
|
+
|
|
91
|
+
## QueryBuildResult
|
|
92
|
+
|
|
93
|
+
Return type of `QueryBuilderBase.build()`.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
interface QueryBuildResult {
|
|
97
|
+
sql: string;
|
|
98
|
+
resultSetIndex?: number;
|
|
99
|
+
resultSetStride?: number;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Field | Type | Description |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `sql` | `string` | Generated SQL string |
|
|
106
|
+
| `resultSetIndex` | `number` | Result set index to read (default: 0) |
|
|
107
|
+
| `resultSetStride` | `number` | Read every Nth result set (for multi-INSERT) |
|
|
108
|
+
|
|
109
|
+
## ColumnMeta
|
|
110
|
+
|
|
111
|
+
Column metadata generated by `ColumnBuilder`.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface ColumnMeta {
|
|
115
|
+
type: ColumnPrimitiveStr;
|
|
116
|
+
dataType: DataType;
|
|
117
|
+
autoIncrement?: boolean;
|
|
118
|
+
nullable?: boolean;
|
|
119
|
+
default?: ColumnPrimitive;
|
|
120
|
+
description?: string;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## DataType
|
|
125
|
+
|
|
126
|
+
SQL data type definition. Discriminated union on `type` field.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
type DataType =
|
|
130
|
+
| { type: "int" }
|
|
131
|
+
| { type: "bigint" }
|
|
132
|
+
| { type: "float" }
|
|
133
|
+
| { type: "double" }
|
|
134
|
+
| { type: "decimal"; precision: number; scale?: number }
|
|
135
|
+
| { type: "varchar"; length: number }
|
|
136
|
+
| { type: "char"; length: number }
|
|
137
|
+
| { type: "text" }
|
|
138
|
+
| { type: "binary" }
|
|
139
|
+
| { type: "boolean" }
|
|
140
|
+
| { type: "datetime" }
|
|
141
|
+
| { type: "date" }
|
|
142
|
+
| { type: "time" }
|
|
143
|
+
| { type: "uuid" };
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**DBMS Mapping:**
|
|
147
|
+
|
|
148
|
+
| DataType | MySQL | MSSQL | PostgreSQL |
|
|
149
|
+
|---|---|---|---|
|
|
150
|
+
| `int` | INT | INT | INT |
|
|
151
|
+
| `bigint` | BIGINT | BIGINT | BIGINT |
|
|
152
|
+
| `float` | FLOAT | REAL | REAL |
|
|
153
|
+
| `double` | DOUBLE | FLOAT | DOUBLE PRECISION |
|
|
154
|
+
| `decimal` | DECIMAL(p,s) | DECIMAL(p,s) | DECIMAL(p,s) |
|
|
155
|
+
| `varchar` | VARCHAR(n) | NVARCHAR(n) | VARCHAR(n) |
|
|
156
|
+
| `char` | CHAR(n) | NCHAR(n) | CHAR(n) |
|
|
157
|
+
| `text` | LONGTEXT | NVARCHAR(MAX) | TEXT |
|
|
158
|
+
| `binary` | LONGBLOB | VARBINARY(MAX) | BYTEA |
|
|
159
|
+
| `boolean` | TINYINT(1) | BIT | BOOLEAN |
|
|
160
|
+
| `datetime` | DATETIME | DATETIME2 | TIMESTAMP |
|
|
161
|
+
| `date` | DATE | DATE | DATE |
|
|
162
|
+
| `time` | TIME | TIME | TIME |
|
|
163
|
+
| `uuid` | BINARY(16) | UNIQUEIDENTIFIER | UUID |
|
|
164
|
+
|
|
165
|
+
## Column Primitive Types
|
|
166
|
+
|
|
167
|
+
### ColumnPrimitiveMap
|
|
168
|
+
|
|
169
|
+
Maps TypeScript type names to actual types.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
type ColumnPrimitiveMap = {
|
|
173
|
+
string: string;
|
|
174
|
+
number: number;
|
|
175
|
+
boolean: boolean;
|
|
176
|
+
DateTime: DateTime;
|
|
177
|
+
DateOnly: DateOnly;
|
|
178
|
+
Time: Time;
|
|
179
|
+
Uuid: Uuid;
|
|
180
|
+
Bytes: Bytes;
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### ColumnPrimitiveStr
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
type ColumnPrimitiveStr = keyof ColumnPrimitiveMap;
|
|
188
|
+
// "string" | "number" | "boolean" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Bytes"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### ColumnPrimitive
|
|
192
|
+
|
|
193
|
+
All primitive types that can be stored in columns. `undefined` represents NULL.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
type ColumnPrimitive = ColumnPrimitiveMap[ColumnPrimitiveStr] | undefined;
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### dataTypeStrToColumnPrimitiveStr
|
|
200
|
+
|
|
201
|
+
Constant mapping SQL DataType string to ColumnPrimitiveStr.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const dataTypeStrToColumnPrimitiveStr: Record<DataType["type"], ColumnPrimitiveStr>;
|
|
205
|
+
// { int: "number", bigint: "number", varchar: "string", datetime: "DateTime", ... }
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### InferColumnPrimitiveFromDataType
|
|
209
|
+
|
|
210
|
+
Infer TypeScript type from a `DataType`.
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
type InferColumnPrimitiveFromDataType<T extends DataType> = ColumnPrimitiveMap[...];
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### inferColumnPrimitiveStr
|
|
217
|
+
|
|
218
|
+
Infer `ColumnPrimitiveStr` from a runtime value.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
function inferColumnPrimitiveStr(value: ColumnPrimitive): ColumnPrimitiveStr;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## QueryDef Types
|
|
225
|
+
|
|
226
|
+
All query definition types used by the QueryBuilder.
|
|
227
|
+
|
|
228
|
+
### QueryDefObjectName
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
interface QueryDefObjectName {
|
|
232
|
+
database?: string;
|
|
233
|
+
schema?: string;
|
|
234
|
+
name: string;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### CudOutputDef
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
interface CudOutputDef {
|
|
242
|
+
columns: string[];
|
|
243
|
+
pkColNames: string[];
|
|
244
|
+
aiColName?: string;
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### SelectQueryDef
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
interface SelectQueryDef {
|
|
252
|
+
type: "select";
|
|
253
|
+
from?: QueryDefObjectName | SelectQueryDef | SelectQueryDef[] | string;
|
|
254
|
+
as: string;
|
|
255
|
+
select?: Record<string, Expr>;
|
|
256
|
+
distinct?: boolean;
|
|
257
|
+
top?: number;
|
|
258
|
+
lock?: boolean;
|
|
259
|
+
where?: WhereExpr[];
|
|
260
|
+
joins?: SelectQueryDefJoin[];
|
|
261
|
+
orderBy?: [Expr, ("ASC" | "DESC")?][];
|
|
262
|
+
limit?: [number, number];
|
|
263
|
+
groupBy?: Expr[];
|
|
264
|
+
having?: WhereExpr[];
|
|
265
|
+
with?: { name: string; base: SelectQueryDef; recursive: SelectQueryDef };
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### SelectQueryDefJoin
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
interface SelectQueryDefJoin extends SelectQueryDef {
|
|
273
|
+
isSingle?: boolean;
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### InsertQueryDef
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
interface InsertQueryDef {
|
|
281
|
+
type: "insert";
|
|
282
|
+
table: QueryDefObjectName;
|
|
283
|
+
records: Record<string, ColumnPrimitive>[];
|
|
284
|
+
overrideIdentity?: boolean;
|
|
285
|
+
output?: CudOutputDef;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### InsertIfNotExistsQueryDef
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
interface InsertIfNotExistsQueryDef {
|
|
293
|
+
type: "insertIfNotExists";
|
|
294
|
+
table: QueryDefObjectName;
|
|
295
|
+
record: Record<string, ColumnPrimitive>;
|
|
296
|
+
existsSelectQuery: Omit<SelectQueryDef, "select">;
|
|
297
|
+
output?: CudOutputDef;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### InsertIntoQueryDef
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
interface InsertIntoQueryDef {
|
|
305
|
+
type: "insertInto";
|
|
306
|
+
table: QueryDefObjectName;
|
|
307
|
+
recordsSelectQuery: SelectQueryDef;
|
|
308
|
+
output?: CudOutputDef;
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### UpdateQueryDef
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
interface UpdateQueryDef {
|
|
316
|
+
type: "update";
|
|
317
|
+
table: QueryDefObjectName;
|
|
318
|
+
as: string;
|
|
319
|
+
record: Record<string, Expr>;
|
|
320
|
+
top?: number;
|
|
321
|
+
where?: WhereExpr[];
|
|
322
|
+
joins?: SelectQueryDefJoin[];
|
|
323
|
+
limit?: [number, number];
|
|
324
|
+
output?: CudOutputDef;
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### DeleteQueryDef
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
interface DeleteQueryDef {
|
|
332
|
+
type: "delete";
|
|
333
|
+
table: QueryDefObjectName;
|
|
334
|
+
as: string;
|
|
335
|
+
top?: number;
|
|
336
|
+
where?: WhereExpr[];
|
|
337
|
+
joins?: SelectQueryDefJoin[];
|
|
338
|
+
limit?: [number, number];
|
|
339
|
+
output?: CudOutputDef;
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### UpsertQueryDef
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
interface UpsertQueryDef {
|
|
347
|
+
type: "upsert";
|
|
348
|
+
table: QueryDefObjectName;
|
|
349
|
+
existsSelectQuery: Omit<SelectQueryDef, "select">;
|
|
350
|
+
updateRecord: Record<string, Expr>;
|
|
351
|
+
insertRecord: Record<string, Expr>;
|
|
352
|
+
output?: CudOutputDef;
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### DDL QueryDef Types
|
|
357
|
+
|
|
358
|
+
| Type | Description |
|
|
359
|
+
|---|---|
|
|
360
|
+
| `CreateTableQueryDef` | CREATE TABLE |
|
|
361
|
+
| `DropTableQueryDef` | DROP TABLE |
|
|
362
|
+
| `RenameTableQueryDef` | RENAME TABLE |
|
|
363
|
+
| `TruncateQueryDef` | TRUNCATE TABLE |
|
|
364
|
+
| `AddColumnQueryDef` | ADD COLUMN |
|
|
365
|
+
| `DropColumnQueryDef` | DROP COLUMN |
|
|
366
|
+
| `ModifyColumnQueryDef` | ALTER COLUMN |
|
|
367
|
+
| `RenameColumnQueryDef` | RENAME COLUMN |
|
|
368
|
+
| `AddPrimaryKeyQueryDef` | ADD PRIMARY KEY |
|
|
369
|
+
| `DropPrimaryKeyQueryDef` | DROP PRIMARY KEY |
|
|
370
|
+
| `AddForeignKeyQueryDef` | ADD FOREIGN KEY |
|
|
371
|
+
| `DropForeignKeyQueryDef` | DROP FOREIGN KEY |
|
|
372
|
+
| `AddIndexQueryDef` | CREATE INDEX |
|
|
373
|
+
| `DropIndexQueryDef` | DROP INDEX |
|
|
374
|
+
| `CreateViewQueryDef` | CREATE VIEW |
|
|
375
|
+
| `DropViewQueryDef` | DROP VIEW |
|
|
376
|
+
| `CreateProcQueryDef` | CREATE PROCEDURE |
|
|
377
|
+
| `DropProcQueryDef` | DROP PROCEDURE |
|
|
378
|
+
| `ExecProcQueryDef` | EXECUTE PROCEDURE |
|
|
379
|
+
| `ClearSchemaQueryDef` | Clear all objects in schema |
|
|
380
|
+
| `SchemaExistsQueryDef` | Check schema existence |
|
|
381
|
+
| `SwitchFkQueryDef` | Enable/disable FK constraints |
|
|
382
|
+
|
|
383
|
+
### QueryDef (union)
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
type QueryDef = SelectQueryDef | InsertQueryDef | InsertIfNotExistsQueryDef
|
|
387
|
+
| InsertIntoQueryDef | UpdateQueryDef | DeleteQueryDef | UpsertQueryDef
|
|
388
|
+
| CreateTableQueryDef | DropTableQueryDef | RenameTableQueryDef
|
|
389
|
+
| TruncateQueryDef | AddColumnQueryDef | DropColumnQueryDef
|
|
390
|
+
| ModifyColumnQueryDef | RenameColumnQueryDef
|
|
391
|
+
| AddPrimaryKeyQueryDef | DropPrimaryKeyQueryDef
|
|
392
|
+
| AddForeignKeyQueryDef | DropForeignKeyQueryDef
|
|
393
|
+
| AddIndexQueryDef | DropIndexQueryDef
|
|
394
|
+
| CreateViewQueryDef | DropViewQueryDef
|
|
395
|
+
| CreateProcQueryDef | DropProcQueryDef | ExecProcQueryDef
|
|
396
|
+
| ClearSchemaQueryDef | SchemaExistsQueryDef | SwitchFkQueryDef;
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Expr Types
|
|
400
|
+
|
|
401
|
+
All expression AST node types. See [expression.md](expression.md) for the `expr` builder API.
|
|
402
|
+
|
|
403
|
+
### DateUnit
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
type DateUnit = "year" | "month" | "day" | "hour" | "minute" | "second";
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### WhereExpr
|
|
410
|
+
|
|
411
|
+
Union of all WHERE-clause expression types.
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
type WhereExpr =
|
|
415
|
+
| ExprEq | ExprGt | ExprLt | ExprGte | ExprLte | ExprBetween
|
|
416
|
+
| ExprIsNull | ExprLike | ExprRegexp | ExprIn | ExprInQuery | ExprExists
|
|
417
|
+
| ExprNot | ExprAnd | ExprOr;
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Expr
|
|
421
|
+
|
|
422
|
+
Union of all expression types (values, functions, aggregates, window, etc.).
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
type Expr =
|
|
426
|
+
| ExprColumn | ExprValue | ExprRaw
|
|
427
|
+
| ExprConcat | ExprLeft | ExprRight | ExprTrim | ExprPadStart | ExprReplace
|
|
428
|
+
| ExprUpper | ExprLower | ExprLength | ExprByteLength | ExprSubstring | ExprIndexOf
|
|
429
|
+
| ExprAbs | ExprRound | ExprCeil | ExprFloor
|
|
430
|
+
| ExprYear | ExprMonth | ExprDay | ExprHour | ExprMinute | ExprSecond
|
|
431
|
+
| ExprIsoWeek | ExprIsoWeekStartDate | ExprIsoYearMonth
|
|
432
|
+
| ExprDateDiff | ExprDateAdd | ExprFormatDate
|
|
433
|
+
| ExprCoalesce | ExprNullIf | ExprIs | ExprSwitch | ExprIf
|
|
434
|
+
| ExprCount | ExprSum | ExprAvg | ExprMax | ExprMin
|
|
435
|
+
| ExprGreatest | ExprLeast | ExprRowNum | ExprRandom | ExprCast
|
|
436
|
+
| ExprWindow | ExprSubquery;
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### WinSpec
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
interface WinSpec {
|
|
443
|
+
partitionBy?: Expr[];
|
|
444
|
+
orderBy?: [Expr, ("ASC" | "DESC")?][];
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### WinFn
|
|
449
|
+
|
|
450
|
+
Union of all window function types.
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
type WinFn =
|
|
454
|
+
| WinFnRowNumber | WinFnRank | WinFnDenseRank | WinFnNtile
|
|
455
|
+
| WinFnLag | WinFnLead | WinFnFirstValue | WinFnLastValue
|
|
456
|
+
| WinFnSum | WinFnAvg | WinFnCount | WinFnMin | WinFnMax;
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## parseQueryResult
|
|
460
|
+
|
|
461
|
+
Transforms raw DB query results into typed TypeScript objects using `ResultMeta`. Handles type parsing, flat-to-nested conversion, and JOIN grouping.
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
async function parseQueryResult<TRecord>(
|
|
465
|
+
rawResults: Record<string, unknown>[],
|
|
466
|
+
meta: ResultMeta,
|
|
467
|
+
): Promise<TRecord[] | undefined>;
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**Parameters:**
|
|
471
|
+
|
|
472
|
+
| Parameter | Type | Description |
|
|
473
|
+
|---|---|---|
|
|
474
|
+
| `rawResults` | `Record<string, unknown>[]` | Raw result rows from database |
|
|
475
|
+
| `meta` | `ResultMeta` | Type and JOIN structure metadata |
|
|
476
|
+
|
|
477
|
+
**Returns:** Typed and nested result array, or `undefined` if empty.
|
|
478
|
+
|
|
479
|
+
**Example:**
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
const raw = [
|
|
483
|
+
{ id: "1", name: "User1", "posts.id": "10", "posts.title": "Post1" },
|
|
484
|
+
{ id: "1", name: "User1", "posts.id": "11", "posts.title": "Post2" },
|
|
485
|
+
];
|
|
486
|
+
const meta = {
|
|
487
|
+
columns: { id: "number", name: "string", "posts.id": "number", "posts.title": "string" },
|
|
488
|
+
joins: { posts: { isSingle: false } },
|
|
489
|
+
};
|
|
490
|
+
const result = await parseQueryResult(raw, meta);
|
|
491
|
+
// [{ id: 1, name: "User1", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## _Migration
|
|
495
|
+
|
|
496
|
+
System migration table definition. Automatically added to every `DbContextDef` by `defineDbContext()`.
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
const _Migration: TableBuilder<{ code: ColumnBuilder<string, ...> }, {}>;
|
|
500
|
+
// Table: "_migration", columns: { code: varchar(255) }, primaryKey: "code"
|
|
501
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/orm-common",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.4",
|
|
4
4
|
"description": "심플리즘 패키지 - ORM (common)",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -14,10 +14,14 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"src"
|
|
17
|
+
"src",
|
|
18
|
+
"docs"
|
|
18
19
|
],
|
|
19
20
|
"sideEffects": false,
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^20.19.37"
|
|
23
|
+
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@simplysm/core-common": "14.0.
|
|
25
|
+
"@simplysm/core-common": "14.0.4"
|
|
22
26
|
}
|
|
23
27
|
}
|
package/src/exec/queryable.ts
CHANGED
|
@@ -647,16 +647,16 @@ export class Queryable<
|
|
|
647
647
|
});
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
// 1.
|
|
650
|
+
// 1. JOIN 별칭 생성
|
|
651
651
|
const joinAlias = `${this.meta.as}.${as}`;
|
|
652
652
|
|
|
653
|
-
// 2.
|
|
653
|
+
// 2. 대상을 Queryable로 변환 (별칭 전달)
|
|
654
654
|
const joinQr = new JoinQueryable(this.meta.db, joinAlias);
|
|
655
655
|
|
|
656
|
-
// 3.
|
|
656
|
+
// 3. fn 실행 (where 등 조건이 추가된 Queryable 반환)
|
|
657
657
|
const resultQr = fn(joinQr, this.meta.columns);
|
|
658
658
|
|
|
659
|
-
// 4.
|
|
659
|
+
// 4. JOIN 결과를 새 column에 추가
|
|
660
660
|
const joinColumns = transformColumnsAlias(resultQr.meta.columns, joinAlias);
|
|
661
661
|
|
|
662
662
|
return new Queryable({
|
|
@@ -703,16 +703,16 @@ export class Queryable<
|
|
|
703
703
|
});
|
|
704
704
|
}
|
|
705
705
|
|
|
706
|
-
// 1.
|
|
706
|
+
// 1. JOIN 별칭 생성
|
|
707
707
|
const joinAlias = `${this.meta.as}.${as}`;
|
|
708
708
|
|
|
709
|
-
// 2.
|
|
709
|
+
// 2. 대상을 Queryable로 변환 (별칭 전달)
|
|
710
710
|
const joinQr = new JoinQueryable(this.meta.db, joinAlias);
|
|
711
711
|
|
|
712
|
-
// 3.
|
|
712
|
+
// 3. fn 실행 (where 등 조건이 추가된 Queryable 반환)
|
|
713
713
|
const resultQr = fn(joinQr, this.meta.columns);
|
|
714
714
|
|
|
715
|
-
// 4.
|
|
715
|
+
// 4. JOIN 결과를 새 column에 추가
|
|
716
716
|
const joinColumns = transformColumnsAlias(resultQr.meta.columns, joinAlias);
|
|
717
717
|
|
|
718
718
|
return new Queryable({
|
|
@@ -803,7 +803,7 @@ export class Queryable<
|
|
|
803
803
|
|
|
804
804
|
if (relationDef instanceof ForeignKeyBuilder || relationDef instanceof RelationKeyBuilder) {
|
|
805
805
|
// FK/RelationKey (N:1): Post.user → User
|
|
806
|
-
//
|
|
806
|
+
// 조건: Post.userId = User.id
|
|
807
807
|
const targetTable = relationDef.meta.targetFn();
|
|
808
808
|
const fkColKeys = relationDef.meta.columns;
|
|
809
809
|
const targetPkColKeys = getMatchedPrimaryKeys(fkColKeys, targetTable);
|
|
@@ -811,7 +811,7 @@ export class Queryable<
|
|
|
811
811
|
result = result.joinSingle(chainParts.join("."), (joinQr, parentCols) => {
|
|
812
812
|
const qr = joinQr.from(targetTable);
|
|
813
813
|
|
|
814
|
-
// FKT
|
|
814
|
+
// FKT JOIN은 배열로 저장되므로, 배열이면 첫 번째 요소 사용
|
|
815
815
|
const srcColsRaw = parentChain ? parentCols[parentChain] : parentCols;
|
|
816
816
|
const srcCols = (
|
|
817
817
|
Array.isArray(srcColsRaw) ? srcColsRaw[0] : srcColsRaw
|
|
@@ -833,8 +833,8 @@ export class Queryable<
|
|
|
833
833
|
relationDef instanceof ForeignKeyTargetBuilder ||
|
|
834
834
|
relationDef instanceof RelationKeyTargetBuilder
|
|
835
835
|
) {
|
|
836
|
-
// FKT/RelationKeyTarget (1:N
|
|
837
|
-
//
|
|
836
|
+
// FKT/RelationKeyTarget (1:N 또는 1:1): User.posts → Post[]
|
|
837
|
+
// 조건: Post.userId = User.id
|
|
838
838
|
const targetTable = relationDef.meta.targetTableFn();
|
|
839
839
|
const fkRelName = relationDef.meta.relationName;
|
|
840
840
|
const sourceFk = targetTable.meta.relations?.[fkRelName];
|
|
@@ -853,7 +853,7 @@ export class Queryable<
|
|
|
853
853
|
const buildJoin = (joinQr: JoinQueryable, parentCols: QueryableRecord<DataRecord>) => {
|
|
854
854
|
const qr = joinQr.from(sourceTable);
|
|
855
855
|
|
|
856
|
-
// FKT
|
|
856
|
+
// FKT JOIN은 배열로 저장되므로, 배열이면 첫 번째 요소 사용
|
|
857
857
|
const srcColsRaw = parentChain ? parentCols[parentChain] : parentCols;
|
|
858
858
|
const srcCols = (
|
|
859
859
|
Array.isArray(srcColsRaw) ? srcColsRaw[0] : srcColsRaw
|
|
@@ -903,7 +903,7 @@ export class Queryable<
|
|
|
903
903
|
* ```
|
|
904
904
|
*/
|
|
905
905
|
wrap(): Queryable<TData, never> {
|
|
906
|
-
//
|
|
906
|
+
// 현재 Queryable을 서브쿼리로 래핑
|
|
907
907
|
const wrapAlias = this.meta.db.getNextAlias();
|
|
908
908
|
return new Queryable({
|
|
909
909
|
db: this.meta.db,
|
|
@@ -982,13 +982,13 @@ export class Queryable<
|
|
|
982
982
|
columns: transformColumnsAlias(newFroms[0].meta.columns, this.meta.as, ""),
|
|
983
983
|
});
|
|
984
984
|
}
|
|
985
|
-
//
|
|
985
|
+
// 동적 CTE 이름 생성
|
|
986
986
|
const cteName = this.meta.db.getNextAlias();
|
|
987
987
|
|
|
988
|
-
// 2.
|
|
988
|
+
// 2. 대상을 Queryable로 변환 (CTE 이름 전달)
|
|
989
989
|
const cteQr = new RecursiveQueryable(this, cteName);
|
|
990
990
|
|
|
991
|
-
// 3.
|
|
991
|
+
// 3. fn 실행 (where 등 조건이 추가된 Queryable 반환)
|
|
992
992
|
const resultQr = fn(cteQr);
|
|
993
993
|
|
|
994
994
|
return new Queryable({
|
|
@@ -998,7 +998,7 @@ export class Queryable<
|
|
|
998
998
|
columns: transformColumnsAlias(this.meta.columns, this.meta.as, ""),
|
|
999
999
|
with: {
|
|
1000
1000
|
name: cteName,
|
|
1001
|
-
base: this as any, //
|
|
1001
|
+
base: this as any, // 순환 참조 타입 추론 차단
|
|
1002
1002
|
recursive: resultQr,
|
|
1003
1003
|
},
|
|
1004
1004
|
});
|