@simplysm/orm-common 14.0.1 → 14.0.5
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 +163 -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 +157 -0
- package/docs/expression.md +220 -0
- package/docs/query-builder.md +150 -0
- package/docs/queryable.md +261 -0
- package/docs/schema-builders.md +294 -0
- package/docs/types.md +520 -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,520 @@
|
|
|
1
|
+
# Types
|
|
2
|
+
|
|
3
|
+
Core type definitions for the ORM.
|
|
4
|
+
|
|
5
|
+
## Database Types
|
|
6
|
+
|
|
7
|
+
### Dialect
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
type Dialect = "mysql" | "mssql" | "postgresql";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Supported database dialects. MySQL 8.0.14+, MSSQL 2012+, PostgreSQL 9.0+.
|
|
14
|
+
|
|
15
|
+
### dialects
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
const dialects: Dialect[] = ["mysql", "mssql", "postgresql"];
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Array of all supported dialects. Useful for parameterized tests.
|
|
22
|
+
|
|
23
|
+
### IsolationLevel
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
type IsolationLevel = "READ_UNCOMMITTED" | "READ_COMMITTED" | "REPEATABLE_READ" | "SERIALIZABLE";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### DataRecord
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
type DataRecord = {
|
|
33
|
+
[key: string]: ColumnPrimitive | DataRecord | DataRecord[];
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Recursive query result type. Supports nested relations via include/join.
|
|
38
|
+
|
|
39
|
+
### DbContextExecutor
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
interface DbContextExecutor {
|
|
43
|
+
connect(): Promise<void>;
|
|
44
|
+
close(): Promise<void>;
|
|
45
|
+
beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
|
|
46
|
+
commitTransaction(): Promise<void>;
|
|
47
|
+
rollbackTransaction(): Promise<void>;
|
|
48
|
+
executeDefs<T = DataRecord>(
|
|
49
|
+
defs: QueryDef[],
|
|
50
|
+
resultMetas?: (ResultMeta | undefined)[],
|
|
51
|
+
): Promise<T[][]>;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Query execution interface. Implemented by `NodeDbContextExecutor` (server) or service client executors.
|
|
56
|
+
|
|
57
|
+
### ResultMeta
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
interface ResultMeta {
|
|
61
|
+
columns: Record<string, ColumnPrimitiveStr>;
|
|
62
|
+
joins: Record<string, { isSingle: boolean }>;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
| Field | Type | Description |
|
|
67
|
+
|-------|------|-------------|
|
|
68
|
+
| `columns` | `Record<string, ColumnPrimitiveStr>` | Column name to type name mapping |
|
|
69
|
+
| `joins` | `Record<string, { isSingle: boolean }>` | JOIN alias to single/array flag |
|
|
70
|
+
|
|
71
|
+
### Migration
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface Migration {
|
|
75
|
+
name: string;
|
|
76
|
+
up: (db: DbContextBase & DbContextDdlMethods) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Field | Type | Description |
|
|
81
|
+
|-------|------|-------------|
|
|
82
|
+
| `name` | `string` | Unique migration name (timestamp recommended) |
|
|
83
|
+
| `up` | `(db) => Promise<void>` | Migration execution function |
|
|
84
|
+
|
|
85
|
+
### QueryBuildResult
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
interface QueryBuildResult {
|
|
89
|
+
sql: string;
|
|
90
|
+
resultSetIndex?: number;
|
|
91
|
+
resultSetStride?: number;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| Field | Type | Description |
|
|
96
|
+
|-------|------|-------------|
|
|
97
|
+
| `sql` | `string` | Generated SQL string |
|
|
98
|
+
| `resultSetIndex` | `number?` | Index of result set to use |
|
|
99
|
+
| `resultSetStride` | `number?` | Extract every Nth result set |
|
|
100
|
+
|
|
101
|
+
## DbContext Types
|
|
102
|
+
|
|
103
|
+
### DbContextDef
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
interface DbContextDef<TTables, TViews, TProcedures> {
|
|
107
|
+
readonly meta: {
|
|
108
|
+
readonly tables: TTables;
|
|
109
|
+
readonly views: TViews;
|
|
110
|
+
readonly procedures: TProcedures;
|
|
111
|
+
readonly migrations: Migration[];
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
DbContext blueprint created by `defineDbContext()`. Contains only schema metadata, no runtime state.
|
|
117
|
+
|
|
118
|
+
### DbContextBase
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
interface DbContextBase {
|
|
122
|
+
status: DbContextStatus;
|
|
123
|
+
readonly database: string | undefined;
|
|
124
|
+
readonly schema: string | undefined;
|
|
125
|
+
getNextAlias(): string;
|
|
126
|
+
resetAliasCounter(): void;
|
|
127
|
+
executeDefs<T = DataRecord>(defs: QueryDef[], resultMetas?: (ResultMeta | undefined)[]): Promise<T[][]>;
|
|
128
|
+
getQueryDefObjectName(tableOrView: TableBuilder | ViewBuilder): QueryDefObjectName;
|
|
129
|
+
switchFk(table: QueryDefObjectName, enabled: boolean): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Core interface used internally by Queryable, Executable, and ViewBuilder.
|
|
134
|
+
|
|
135
|
+
### DbContextStatus
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
type DbContextStatus = "ready" | "connect" | "transact";
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### DbContextInstance
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
type DbContextInstance<TDef extends DbContextDef<any, any, any>> =
|
|
145
|
+
DbContextBase &
|
|
146
|
+
DbContextConnectionMethods &
|
|
147
|
+
DbContextDdlMethods &
|
|
148
|
+
{ [K in keyof TDef["meta"]["tables"]]: () => Queryable<...> } &
|
|
149
|
+
{ [K in keyof TDef["meta"]["views"]]: () => Queryable<...> } &
|
|
150
|
+
{ [K in keyof TDef["meta"]["procedures"]]: () => Executable<...> } &
|
|
151
|
+
{ _migration: () => Queryable<{ code: string }, any> } &
|
|
152
|
+
{ initialize(options?: { dbs?: string[]; force?: boolean }): Promise<void> };
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Full DbContext instance type returned by `createDbContext()`. Includes queryable accessors for all tables/views, executable accessors for all procedures, connection methods, DDL methods, and `initialize()`.
|
|
156
|
+
|
|
157
|
+
### DbContextConnectionMethods
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
interface DbContextConnectionMethods {
|
|
161
|
+
connect<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
|
|
162
|
+
connectWithoutTransaction<TResult>(callback: () => Promise<TResult>): Promise<TResult>;
|
|
163
|
+
transaction<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### DbContextDdlMethods
|
|
168
|
+
|
|
169
|
+
See [Core - DDL Execution Methods](./core.md#ddl-execution-methods) and [Core - DDL QueryDef Generators](./core.md#ddl-querydef-generators) for the full list of 18 DDL execution methods and 22 QueryDef generator methods.
|
|
170
|
+
|
|
171
|
+
## Column Types
|
|
172
|
+
|
|
173
|
+
### DataType
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
type DataType =
|
|
177
|
+
| { type: "int" }
|
|
178
|
+
| { type: "bigint" }
|
|
179
|
+
| { type: "float" }
|
|
180
|
+
| { type: "double" }
|
|
181
|
+
| { type: "decimal"; precision: number; scale?: number }
|
|
182
|
+
| { type: "varchar"; length: number }
|
|
183
|
+
| { type: "char"; length: number }
|
|
184
|
+
| { type: "text" }
|
|
185
|
+
| { type: "binary" }
|
|
186
|
+
| { type: "boolean" }
|
|
187
|
+
| { type: "datetime" }
|
|
188
|
+
| { type: "date" }
|
|
189
|
+
| { type: "time" }
|
|
190
|
+
| { type: "uuid" };
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
SQL data type definition. Used in ColumnBuilder metadata, CAST expressions, and DDL generation.
|
|
194
|
+
|
|
195
|
+
### ColumnPrimitive
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
type ColumnPrimitive = string | number | boolean | DateTime | DateOnly | Time | Uuid | Bytes | undefined;
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
All storable column primitive types. `undefined` represents SQL NULL.
|
|
202
|
+
|
|
203
|
+
### ColumnPrimitiveStr
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
type ColumnPrimitiveStr = "string" | "number" | "boolean" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Bytes";
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### ColumnPrimitiveMap
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
type ColumnPrimitiveMap = {
|
|
213
|
+
string: string;
|
|
214
|
+
number: number;
|
|
215
|
+
boolean: boolean;
|
|
216
|
+
DateTime: DateTime;
|
|
217
|
+
DateOnly: DateOnly;
|
|
218
|
+
Time: Time;
|
|
219
|
+
Uuid: Uuid;
|
|
220
|
+
Bytes: Bytes;
|
|
221
|
+
};
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### ColumnMeta
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
interface ColumnMeta {
|
|
228
|
+
type: ColumnPrimitiveStr;
|
|
229
|
+
dataType: DataType;
|
|
230
|
+
autoIncrement?: boolean;
|
|
231
|
+
nullable?: boolean;
|
|
232
|
+
default?: ColumnPrimitive;
|
|
233
|
+
description?: string;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### dataTypeStrToColumnPrimitiveStr
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
const dataTypeStrToColumnPrimitiveStr: Record<DataType["type"], ColumnPrimitiveStr>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Maps SQL type names to TypeScript type names. For example: `"int"` -> `"number"`, `"datetime"` -> `"DateTime"`, `"varchar"` -> `"string"`.
|
|
244
|
+
|
|
245
|
+
### InferColumnPrimitiveFromDataType
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
type InferColumnPrimitiveFromDataType<TDataType extends DataType> = ColumnPrimitiveMap[...]
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Infers the TypeScript type from a DataType definition.
|
|
252
|
+
|
|
253
|
+
### inferColumnPrimitiveStr
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
function inferColumnPrimitiveStr(value: ColumnPrimitive): ColumnPrimitiveStr
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Infers the ColumnPrimitiveStr from a runtime value. Throws for unknown types.
|
|
260
|
+
|
|
261
|
+
## Column Builder Types
|
|
262
|
+
|
|
263
|
+
### ColumnBuilderRecord
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
type ColumnBuilderRecord = Record<string, ColumnBuilder<ColumnPrimitive, ColumnMeta>>;
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### InferColumns
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
type InferColumns<TBuilders extends ColumnBuilderRecord> = {
|
|
273
|
+
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? V : never;
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Extracts runtime value types from a column builder record.
|
|
278
|
+
|
|
279
|
+
### InferColumnExprs
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
type InferColumnExprs<TBuilders extends ColumnBuilderRecord> = {
|
|
283
|
+
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? ExprInput<V> : never;
|
|
284
|
+
};
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### InferInsertColumns
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
type InferInsertColumns<TBuilders> = Pick<InferColumns<TBuilders>, RequiredInsertKeys<TBuilders>> &
|
|
291
|
+
Partial<Pick<InferColumns<TBuilders>, OptionalInsertKeys<TBuilders>>>;
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
INSERT type: required columns are required, autoIncrement/nullable/default columns are optional.
|
|
295
|
+
|
|
296
|
+
### InferUpdateColumns
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
type InferUpdateColumns<TBuilders> = Partial<InferColumns<TBuilders>>;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
UPDATE type: all columns are optional.
|
|
303
|
+
|
|
304
|
+
### RequiredInsertKeys
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
type RequiredInsertKeys<TBuilders> = /* columns without autoIncrement, nullable, or default */
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### OptionalInsertKeys
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
type OptionalInsertKeys<TBuilders> = Exclude<keyof TBuilders, RequiredInsertKeys<TBuilders>>;
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### DataToColumnBuilderRecord
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
type DataToColumnBuilderRecord<TData extends DataRecord> = {
|
|
320
|
+
[K in keyof TData as TData[K] extends ColumnPrimitive ? K : never]: ColumnBuilder<TData[K], any>;
|
|
321
|
+
};
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Relation Types
|
|
325
|
+
|
|
326
|
+
### RelationBuilderRecord
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
type RelationBuilderRecord = Record<string,
|
|
330
|
+
ForeignKeyBuilder<any, any> | ForeignKeyTargetBuilder<any, any> |
|
|
331
|
+
RelationKeyBuilder<any, any> | RelationKeyTargetBuilder<any, any>>;
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### InferDeepRelations
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
type InferDeepRelations<TRelations extends RelationBuilderRecord> = {
|
|
338
|
+
[K in keyof TRelations]?: ExtractRelationTarget<TRelations[K]> | ExtractRelationTargetResult<TRelations[K]>;
|
|
339
|
+
};
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
All relations are optional (loaded only via `include()`).
|
|
343
|
+
|
|
344
|
+
### ExtractRelationTarget
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
type ExtractRelationTarget<TRelation> = /* Extracts N:1 target type (single object) */
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
For FK/RelationKey relations, extracts `InferColumns<TCols> & InferDeepRelations<TRels>` of the target table.
|
|
351
|
+
|
|
352
|
+
### ExtractRelationTargetResult
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
type ExtractRelationTargetResult<TRelation> = /* Extracts 1:N target type (array or single) */
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
For FKTarget/RelationKeyTarget relations, extracts an array type (or single object if `isSingle: true`).
|
|
359
|
+
|
|
360
|
+
## Expression Types
|
|
361
|
+
|
|
362
|
+
### DateUnit
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
type DateUnit = "year" | "month" | "day" | "hour" | "minute" | "second";
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### WhereExpr
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
type WhereExpr =
|
|
372
|
+
| ExprEq | ExprGt | ExprLt | ExprGte | ExprLte | ExprBetween
|
|
373
|
+
| ExprIsNull | ExprLike | ExprRegexp
|
|
374
|
+
| ExprIn | ExprInQuery | ExprExists
|
|
375
|
+
| ExprNot | ExprAnd | ExprOr;
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Union of all WHERE-clause expression types (comparison + logical).
|
|
379
|
+
|
|
380
|
+
### Expr
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
type Expr =
|
|
384
|
+
| ExprColumn | ExprValue | ExprRaw
|
|
385
|
+
| ExprConcat | ExprLeft | ExprRight | ExprTrim | ExprPadStart | ExprReplace
|
|
386
|
+
| ExprUpper | ExprLower | ExprLength | ExprByteLength | ExprSubstring | ExprIndexOf
|
|
387
|
+
| ExprAbs | ExprRound | ExprCeil | ExprFloor
|
|
388
|
+
| ExprYear | ExprMonth | ExprDay | ExprHour | ExprMinute | ExprSecond
|
|
389
|
+
| ExprIsoWeek | ExprIsoWeekStartDate | ExprIsoYearMonth
|
|
390
|
+
| ExprDateDiff | ExprDateAdd | ExprFormatDate
|
|
391
|
+
| ExprCoalesce | ExprNullIf | ExprIs | ExprSwitch | ExprIf
|
|
392
|
+
| ExprCount | ExprSum | ExprAvg | ExprMax | ExprMin
|
|
393
|
+
| ExprGreatest | ExprLeast | ExprRowNum | ExprRandom | ExprCast
|
|
394
|
+
| ExprWindow | ExprSubquery;
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Union of all expression types (value, string, number, date, conditional, aggregate, window, system).
|
|
398
|
+
|
|
399
|
+
### WinFn
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
type WinFn =
|
|
403
|
+
| WinFnRowNumber | WinFnRank | WinFnDenseRank | WinFnNtile
|
|
404
|
+
| WinFnLag | WinFnLead | WinFnFirstValue | WinFnLastValue
|
|
405
|
+
| WinFnSum | WinFnAvg | WinFnCount | WinFnMin | WinFnMax;
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### WinSpec
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
interface WinSpec {
|
|
412
|
+
partitionBy?: Expr[];
|
|
413
|
+
orderBy?: [Expr, ("ASC" | "DESC")?][];
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## QueryDef Types
|
|
418
|
+
|
|
419
|
+
### QueryDefObjectName
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
interface QueryDefObjectName {
|
|
423
|
+
database?: string;
|
|
424
|
+
schema?: string;
|
|
425
|
+
name: string;
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
DB object name. MySQL: `database.name`, MSSQL: `database.schema.name`, PostgreSQL: `schema.name`.
|
|
430
|
+
|
|
431
|
+
### QueryDef
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
type QueryDef =
|
|
435
|
+
// DML
|
|
436
|
+
| SelectQueryDef | InsertQueryDef | InsertIfNotExistsQueryDef | InsertIntoQueryDef
|
|
437
|
+
| UpdateQueryDef | DeleteQueryDef | UpsertQueryDef
|
|
438
|
+
// DDL
|
|
439
|
+
| ClearSchemaQueryDef | CreateTableQueryDef | DropTableQueryDef | RenameTableQueryDef
|
|
440
|
+
| TruncateQueryDef | AddColumnQueryDef | DropColumnQueryDef | ModifyColumnQueryDef
|
|
441
|
+
| RenameColumnQueryDef | DropPrimaryKeyQueryDef | AddPrimaryKeyQueryDef
|
|
442
|
+
| AddForeignKeyQueryDef | DropForeignKeyQueryDef | AddIndexQueryDef | DropIndexQueryDef
|
|
443
|
+
| CreateViewQueryDef | DropViewQueryDef | CreateProcQueryDef | DropProcQueryDef
|
|
444
|
+
// Utils/Meta
|
|
445
|
+
| ExecProcQueryDef | SwitchFkQueryDef | SchemaExistsQueryDef;
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### DDL_TYPES
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
const DDL_TYPES: readonly DdlType[]
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Array of all DDL query type strings. Used for blocking DDL inside transactions.
|
|
455
|
+
|
|
456
|
+
### DdlType
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
type DdlType = "clearSchema" | "createTable" | "dropTable" | "renameTable" | "truncate"
|
|
460
|
+
| "addColumn" | "dropColumn" | "modifyColumn" | "renameColumn"
|
|
461
|
+
| "dropPrimaryKey" | "addPrimaryKey" | "addForeignKey" | "dropForeignKey"
|
|
462
|
+
| "addIndex" | "dropIndex" | "createView" | "dropView" | "createProc" | "dropProc";
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### DML QueryDef Interfaces
|
|
466
|
+
|
|
467
|
+
| Interface | type field | Key fields |
|
|
468
|
+
|-----------|-----------|-------------|
|
|
469
|
+
| `SelectQueryDef` | `"select"` | `from`, `as`, `select`, `distinct`, `top`, `lock`, `where`, `joins`, `orderBy`, `limit`, `groupBy`, `having`, `with` |
|
|
470
|
+
| `SelectQueryDefJoin` | `"select"` | Extends SelectQueryDef + `isSingle` |
|
|
471
|
+
| `InsertQueryDef` | `"insert"` | `table`, `records`, `overrideIdentity`, `output` |
|
|
472
|
+
| `InsertIfNotExistsQueryDef` | `"insertIfNotExists"` | `table`, `record`, `existsSelectQuery`, `output` |
|
|
473
|
+
| `InsertIntoQueryDef` | `"insertInto"` | `table`, `recordsSelectQuery`, `output` |
|
|
474
|
+
| `UpdateQueryDef` | `"update"` | `table`, `as`, `record`, `top`, `where`, `joins`, `limit`, `output` |
|
|
475
|
+
| `DeleteQueryDef` | `"delete"` | `table`, `as`, `top`, `where`, `joins`, `limit`, `output` |
|
|
476
|
+
| `UpsertQueryDef` | `"upsert"` | `table`, `existsSelectQuery`, `insertRecord`, `updateRecord`, `output` |
|
|
477
|
+
| `ExecProcQueryDef` | `"execProc"` | `procedure`, `params` |
|
|
478
|
+
|
|
479
|
+
### DDL QueryDef Interfaces
|
|
480
|
+
|
|
481
|
+
| Interface | type field | Key fields |
|
|
482
|
+
|-----------|-----------|-------------|
|
|
483
|
+
| `ClearSchemaQueryDef` | `"clearSchema"` | `database`, `schema` |
|
|
484
|
+
| `CreateTableQueryDef` | `"createTable"` | `table`, `columns`, `primaryKey` |
|
|
485
|
+
| `DropTableQueryDef` | `"dropTable"` | `table` |
|
|
486
|
+
| `RenameTableQueryDef` | `"renameTable"` | `table`, `newName` |
|
|
487
|
+
| `TruncateQueryDef` | `"truncate"` | `table` |
|
|
488
|
+
| `AddColumnQueryDef` | `"addColumn"` | `table`, `column` |
|
|
489
|
+
| `DropColumnQueryDef` | `"dropColumn"` | `table`, `column` |
|
|
490
|
+
| `ModifyColumnQueryDef` | `"modifyColumn"` | `table`, `column` |
|
|
491
|
+
| `RenameColumnQueryDef` | `"renameColumn"` | `table`, `column`, `newName` |
|
|
492
|
+
| `AddPrimaryKeyQueryDef` | `"addPrimaryKey"` | `table`, `columns` |
|
|
493
|
+
| `DropPrimaryKeyQueryDef` | `"dropPrimaryKey"` | `table` |
|
|
494
|
+
| `AddForeignKeyQueryDef` | `"addForeignKey"` | `table`, `foreignKey` |
|
|
495
|
+
| `DropForeignKeyQueryDef` | `"dropForeignKey"` | `table`, `foreignKey` |
|
|
496
|
+
| `AddIndexQueryDef` | `"addIndex"` | `table`, `index` |
|
|
497
|
+
| `DropIndexQueryDef` | `"dropIndex"` | `table`, `index` |
|
|
498
|
+
| `CreateViewQueryDef` | `"createView"` | `view`, `queryDef` |
|
|
499
|
+
| `DropViewQueryDef` | `"dropView"` | `view` |
|
|
500
|
+
| `CreateProcQueryDef` | `"createProc"` | `procedure`, `params`, `returns`, `query` |
|
|
501
|
+
| `DropProcQueryDef` | `"dropProc"` | `procedure` |
|
|
502
|
+
|
|
503
|
+
### Utility QueryDef Interfaces
|
|
504
|
+
|
|
505
|
+
| Interface | type field | Key fields |
|
|
506
|
+
|-----------|-----------|-------------|
|
|
507
|
+
| `SwitchFkQueryDef` | `"switchFk"` | `table`, `enabled` |
|
|
508
|
+
| `SchemaExistsQueryDef` | `"schemaExists"` | `database`, `schema` |
|
|
509
|
+
|
|
510
|
+
### CudOutputDef
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
interface CudOutputDef {
|
|
514
|
+
columns: string[];
|
|
515
|
+
pkColNames: string[];
|
|
516
|
+
aiColName?: string;
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
OUTPUT clause definition for INSERT/UPDATE/DELETE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/orm-common",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.5",
|
|
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.5"
|
|
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
|
});
|