@simplysm/orm-common 13.0.69 → 13.0.71
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 +54 -1447
- package/dist/create-db-context.d.ts +10 -10
- package/dist/create-db-context.js +9 -9
- package/dist/create-db-context.js.map +1 -1
- package/dist/ddl/column-ddl.d.ts +4 -4
- package/dist/ddl/initialize.d.ts +17 -17
- package/dist/ddl/initialize.js +2 -2
- package/dist/ddl/initialize.js.map +1 -1
- package/dist/ddl/relation-ddl.d.ts +6 -6
- package/dist/ddl/schema-ddl.d.ts +4 -4
- package/dist/ddl/table-ddl.d.ts +24 -24
- package/dist/ddl/table-ddl.js +4 -4
- package/dist/ddl/table-ddl.js.map +1 -1
- package/dist/errors/db-transaction-error.d.ts +15 -15
- package/dist/errors/db-transaction-error.d.ts.map +1 -1
- package/dist/exec/executable.d.ts +23 -23
- package/dist/exec/executable.js +3 -3
- package/dist/exec/executable.js.map +1 -1
- package/dist/exec/queryable.d.ts +160 -160
- package/dist/exec/queryable.js +119 -119
- package/dist/exec/queryable.js.map +1 -1
- package/dist/exec/search-parser.d.ts +37 -37
- package/dist/exec/search-parser.d.ts.map +1 -1
- package/dist/expr/expr-unit.d.ts +4 -4
- package/dist/expr/expr.d.ts +257 -257
- package/dist/expr/expr.js +265 -265
- package/dist/expr/expr.js.map +1 -1
- package/dist/query-builder/base/expr-renderer-base.d.ts +9 -9
- package/dist/query-builder/base/expr-renderer-base.js +2 -2
- package/dist/query-builder/base/expr-renderer-base.js.map +1 -1
- package/dist/query-builder/base/query-builder-base.d.ts +26 -26
- package/dist/query-builder/base/query-builder-base.d.ts.map +1 -1
- package/dist/query-builder/base/query-builder-base.js +22 -22
- package/dist/query-builder/base/query-builder-base.js.map +1 -1
- package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +4 -4
- package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/mssql/mssql-expr-renderer.js +18 -18
- 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 +11 -11
- package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -1
- package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +4 -4
- package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/mysql/mysql-expr-renderer.js +17 -17
- package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -1
- package/dist/query-builder/mysql/mysql-query-builder.d.ts +8 -8
- package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
- package/dist/query-builder/mysql/mysql-query-builder.js +5 -5
- package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -1
- package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +4 -4
- package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
- package/dist/query-builder/postgresql/postgresql-expr-renderer.js +17 -17
- package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -1
- package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +5 -5
- package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
- package/dist/query-builder/postgresql/postgresql-query-builder.js +8 -8
- package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -1
- package/dist/query-builder/query-builder.d.ts +1 -1
- package/dist/schema/factory/column-builder.d.ts +79 -79
- package/dist/schema/factory/column-builder.js +42 -42
- package/dist/schema/factory/index-builder.d.ts +39 -39
- package/dist/schema/factory/index-builder.js +26 -26
- package/dist/schema/factory/relation-builder.d.ts +99 -99
- package/dist/schema/factory/relation-builder.d.ts.map +1 -1
- package/dist/schema/factory/relation-builder.js +38 -38
- package/dist/schema/procedure-builder.d.ts +49 -49
- package/dist/schema/procedure-builder.d.ts.map +1 -1
- package/dist/schema/procedure-builder.js +33 -33
- package/dist/schema/table-builder.d.ts +59 -59
- package/dist/schema/table-builder.d.ts.map +1 -1
- package/dist/schema/table-builder.js +43 -43
- package/dist/schema/view-builder.d.ts +49 -49
- package/dist/schema/view-builder.d.ts.map +1 -1
- package/dist/schema/view-builder.js +32 -32
- package/dist/types/column.d.ts +22 -22
- package/dist/types/column.js +1 -1
- package/dist/types/column.js.map +1 -1
- package/dist/types/db.d.ts +40 -40
- package/dist/types/expr.d.ts +59 -59
- package/dist/types/expr.d.ts.map +1 -1
- package/dist/types/query-def.d.ts +44 -44
- package/dist/types/query-def.d.ts.map +1 -1
- package/dist/utils/result-parser.d.ts +11 -11
- package/dist/utils/result-parser.js +3 -3
- package/dist/utils/result-parser.js.map +1 -1
- package/package.json +5 -5
- package/src/create-db-context.ts +20 -20
- package/src/ddl/column-ddl.ts +4 -4
- package/src/ddl/initialize.ts +259 -259
- package/src/ddl/relation-ddl.ts +89 -89
- package/src/ddl/schema-ddl.ts +4 -4
- package/src/ddl/table-ddl.ts +189 -189
- package/src/errors/db-transaction-error.ts +13 -13
- package/src/exec/executable.ts +25 -25
- package/src/exec/queryable.ts +2033 -2033
- package/src/exec/search-parser.ts +57 -57
- package/src/expr/expr-unit.ts +4 -4
- package/src/expr/expr.ts +2140 -2140
- package/src/query-builder/base/expr-renderer-base.ts +237 -237
- package/src/query-builder/base/query-builder-base.ts +213 -213
- package/src/query-builder/mssql/mssql-expr-renderer.ts +607 -607
- package/src/query-builder/mssql/mssql-query-builder.ts +650 -650
- package/src/query-builder/mysql/mysql-expr-renderer.ts +613 -613
- package/src/query-builder/mysql/mysql-query-builder.ts +759 -759
- package/src/query-builder/postgresql/postgresql-expr-renderer.ts +611 -611
- package/src/query-builder/postgresql/postgresql-query-builder.ts +686 -686
- package/src/query-builder/query-builder.ts +19 -19
- package/src/schema/factory/column-builder.ts +423 -423
- package/src/schema/factory/index-builder.ts +164 -164
- package/src/schema/factory/relation-builder.ts +453 -453
- package/src/schema/procedure-builder.ts +232 -232
- package/src/schema/table-builder.ts +319 -319
- package/src/schema/view-builder.ts +221 -221
- package/src/types/column.ts +188 -188
- package/src/types/db.ts +208 -208
- package/src/types/expr.ts +697 -697
- package/src/types/query-def.ts +513 -513
- package/src/utils/result-parser.ts +458 -458
- package/tests/db-context/create-db-context.spec.ts +224 -0
- package/tests/db-context/define-db-context.spec.ts +68 -0
- package/tests/ddl/basic.expected.ts +341 -0
- package/tests/ddl/basic.spec.ts +714 -0
- package/tests/ddl/column-builder.expected.ts +310 -0
- package/tests/ddl/column-builder.spec.ts +637 -0
- package/tests/ddl/index-builder.expected.ts +38 -0
- package/tests/ddl/index-builder.spec.ts +202 -0
- package/tests/ddl/procedure-builder.expected.ts +52 -0
- package/tests/ddl/procedure-builder.spec.ts +234 -0
- package/tests/ddl/relation-builder.expected.ts +36 -0
- package/tests/ddl/relation-builder.spec.ts +372 -0
- package/tests/ddl/table-builder.expected.ts +113 -0
- package/tests/ddl/table-builder.spec.ts +433 -0
- package/tests/ddl/view-builder.expected.ts +38 -0
- package/tests/ddl/view-builder.spec.ts +176 -0
- package/tests/dml/delete.expected.ts +96 -0
- package/tests/dml/delete.spec.ts +160 -0
- package/tests/dml/insert.expected.ts +192 -0
- package/tests/dml/insert.spec.ts +288 -0
- package/tests/dml/update.expected.ts +176 -0
- package/tests/dml/update.spec.ts +318 -0
- package/tests/dml/upsert.expected.ts +215 -0
- package/tests/dml/upsert.spec.ts +242 -0
- package/tests/errors/queryable-errors.spec.ts +177 -0
- package/tests/escape.spec.ts +100 -0
- package/tests/examples/pivot.expected.ts +211 -0
- package/tests/examples/pivot.spec.ts +533 -0
- package/tests/examples/sampling.expected.ts +69 -0
- package/tests/examples/sampling.spec.ts +105 -0
- package/tests/examples/unpivot.expected.ts +120 -0
- package/tests/examples/unpivot.spec.ts +226 -0
- package/tests/exec/search-parser.spec.ts +283 -0
- package/tests/executable/basic.expected.ts +18 -0
- package/tests/executable/basic.spec.ts +54 -0
- package/tests/expr/comparison.expected.ts +282 -0
- package/tests/expr/comparison.spec.ts +400 -0
- package/tests/expr/conditional.expected.ts +134 -0
- package/tests/expr/conditional.spec.ts +276 -0
- package/tests/expr/date.expected.ts +332 -0
- package/tests/expr/date.spec.ts +526 -0
- package/tests/expr/math.expected.ts +62 -0
- package/tests/expr/math.spec.ts +106 -0
- package/tests/expr/string.expected.ts +218 -0
- package/tests/expr/string.spec.ts +356 -0
- package/tests/expr/utility.expected.ts +147 -0
- package/tests/expr/utility.spec.ts +182 -0
- package/tests/select/basic.expected.ts +322 -0
- package/tests/select/basic.spec.ts +502 -0
- package/tests/select/filter.expected.ts +357 -0
- package/tests/select/filter.spec.ts +1068 -0
- package/tests/select/group.expected.ts +169 -0
- package/tests/select/group.spec.ts +244 -0
- package/tests/select/join.expected.ts +582 -0
- package/tests/select/join.spec.ts +805 -0
- package/tests/select/order.expected.ts +150 -0
- package/tests/select/order.spec.ts +189 -0
- package/tests/select/recursive-cte.expected.ts +244 -0
- package/tests/select/recursive-cte.spec.ts +514 -0
- package/tests/select/result-meta.spec.ts +270 -0
- package/tests/select/subquery.expected.ts +363 -0
- package/tests/select/subquery.spec.ts +537 -0
- package/tests/select/view.expected.ts +155 -0
- package/tests/select/view.spec.ts +235 -0
- package/tests/select/window.expected.ts +345 -0
- package/tests/select/window.spec.ts +618 -0
- package/tests/setup/MockExecutor.ts +18 -0
- package/tests/setup/TestDbContext.ts +59 -0
- package/tests/setup/models/Company.ts +13 -0
- package/tests/setup/models/Employee.ts +10 -0
- package/tests/setup/models/MonthlySales.ts +11 -0
- package/tests/setup/models/Post.ts +16 -0
- package/tests/setup/models/Sales.ts +10 -0
- package/tests/setup/models/User.ts +19 -0
- package/tests/setup/procedure/GetAllUsers.ts +9 -0
- package/tests/setup/procedure/GetUserById.ts +12 -0
- package/tests/setup/test-utils.ts +72 -0
- package/tests/setup/views/ActiveUsers.ts +8 -0
- package/tests/setup/views/UserSummary.ts +11 -0
- package/tests/types/nullable-queryable-record.spec.ts +145 -0
- package/tests/utils/result-parser-perf.spec.ts +210 -0
- package/tests/utils/result-parser.spec.ts +701 -0
- package/docs/expressions.md +0 -172
- package/docs/queries.md +0 -444
- package/docs/schema.md +0 -245
|
@@ -1,221 +1,221 @@
|
|
|
1
|
-
import type { DbContextBase } from "../types/db-context-def";
|
|
2
|
-
import type { Queryable } from "../exec/queryable";
|
|
3
|
-
import type { DataRecord } from "../types/db";
|
|
4
|
-
import {
|
|
5
|
-
createRelationFactory,
|
|
6
|
-
type InferDeepRelations,
|
|
7
|
-
type RelationBuilderRecord,
|
|
8
|
-
} from "./factory/relation-builder";
|
|
9
|
-
|
|
10
|
-
// ============================================
|
|
11
|
-
// ViewBuilder
|
|
12
|
-
// ============================================
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* Fluent API를 통해
|
|
18
|
-
* DbContext에서 queryable()과 함께 사용하여
|
|
19
|
-
*
|
|
20
|
-
* @template TDbContext - DbContext
|
|
21
|
-
* @template TData -
|
|
22
|
-
* @template TRelations -
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```typescript
|
|
26
|
-
* //
|
|
27
|
-
* const UserSummary = View("UserSummary")
|
|
28
|
-
* .database("mydb")
|
|
29
|
-
* .query((db: MyDb) =>
|
|
30
|
-
* db.user()
|
|
31
|
-
* .select(u => ({
|
|
32
|
-
* id: u.id,
|
|
33
|
-
* name: u.name,
|
|
34
|
-
* postCount: expr.subquery(
|
|
35
|
-
* db.post().where(p => [expr.eq(p.authorId, u.id)]),
|
|
36
|
-
* q => expr.count(q.id)
|
|
37
|
-
* ),
|
|
38
|
-
* }))
|
|
39
|
-
* );
|
|
40
|
-
*
|
|
41
|
-
* //
|
|
42
|
-
* class MyDb extends DbContext {
|
|
43
|
-
* readonly userSummary = queryable(this, UserSummary);
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* @see {@link View}
|
|
48
|
-
* @see {@link queryable} Queryable
|
|
49
|
-
*/
|
|
50
|
-
export class ViewBuilder<
|
|
51
|
-
TDbContext extends DbContextBase,
|
|
52
|
-
TData extends DataRecord,
|
|
53
|
-
TRelations extends RelationBuilderRecord,
|
|
54
|
-
> {
|
|
55
|
-
/**
|
|
56
|
-
readonly $relations!: TRelations;
|
|
57
|
-
/** 전체
|
|
58
|
-
readonly $infer!: TData;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @param meta -
|
|
62
|
-
* @param meta.name -
|
|
63
|
-
* @param meta.description -
|
|
64
|
-
* @param meta.database -
|
|
65
|
-
* @param meta.schema -
|
|
66
|
-
* @param meta.viewFn -
|
|
67
|
-
* @param meta.relations -
|
|
68
|
-
*/
|
|
69
|
-
constructor(
|
|
70
|
-
readonly meta: {
|
|
71
|
-
name: string;
|
|
72
|
-
description?: string;
|
|
73
|
-
database?: string;
|
|
74
|
-
schema?: string;
|
|
75
|
-
viewFn?: (db: TDbContext) => Queryable<TData, any>;
|
|
76
|
-
relations?: TRelations;
|
|
77
|
-
},
|
|
78
|
-
) {}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* @param desc -
|
|
84
|
-
* @returns
|
|
85
|
-
*/
|
|
86
|
-
description(desc: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
87
|
-
return new ViewBuilder({ ...this.meta, description: desc });
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* @param db -
|
|
94
|
-
* @returns
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```typescript
|
|
98
|
-
* const UserSummary = View("UserSummary").database("mydb");
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
database(db: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
102
|
-
return new ViewBuilder({ ...this.meta, database: db });
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* MSSQL,
|
|
109
|
-
*
|
|
110
|
-
* @param schema -
|
|
111
|
-
* @returns
|
|
112
|
-
*/
|
|
113
|
-
schema(schema: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
114
|
-
return new ViewBuilder({ ...this.meta, schema });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* SELECT
|
|
121
|
-
*
|
|
122
|
-
* @template TViewData -
|
|
123
|
-
* @template TDb - DbContext
|
|
124
|
-
* @param viewFn - DbContext를 받아 Queryable을 반환하는
|
|
125
|
-
* @returns
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```typescript
|
|
129
|
-
* const ActiveUsers = View("ActiveUsers")
|
|
130
|
-
* .database("mydb")
|
|
131
|
-
* .query((db: MyDb) =>
|
|
132
|
-
* db.user()
|
|
133
|
-
* .where(u => [expr.eq(u.status, "active")])
|
|
134
|
-
* .select(u => ({
|
|
135
|
-
* id: u.id,
|
|
136
|
-
* name: u.name,
|
|
137
|
-
* email: u.email,
|
|
138
|
-
* }))
|
|
139
|
-
* );
|
|
140
|
-
* ```
|
|
141
|
-
*/
|
|
142
|
-
query<TViewData extends DataRecord, TDb extends DbContextBase>(
|
|
143
|
-
viewFn: (db: TDb) => Queryable<TViewData, any>,
|
|
144
|
-
): ViewBuilder<TDb, TViewData, TRelations> {
|
|
145
|
-
return new ViewBuilder({ ...this.meta, viewFn });
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* 다른
|
|
152
|
-
*
|
|
153
|
-
* @template T -
|
|
154
|
-
* @param fn -
|
|
155
|
-
* @returns
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```typescript
|
|
159
|
-
* const UserSummary = View("UserSummary")
|
|
160
|
-
* .query((db: MyDb) => db.user().select(...))
|
|
161
|
-
* .relations((r) => ({
|
|
162
|
-
* posts: r.foreignKeyTarget(Post, "author"),
|
|
163
|
-
* }));
|
|
164
|
-
* ```
|
|
165
|
-
*
|
|
166
|
-
* @see {@link ForeignKeyBuilder} FK
|
|
167
|
-
* @see {@link ForeignKeyTargetBuilder} FK 역참조
|
|
168
|
-
*/
|
|
169
|
-
relations<T extends RelationBuilderRecord>(
|
|
170
|
-
fn: (r: ReturnType<typeof createRelationFactory<this, keyof TData & string>>) => T,
|
|
171
|
-
): ViewBuilder<TDbContext, TData & InferDeepRelations<T>, TRelations> {
|
|
172
|
-
// TypeScript의
|
|
173
|
-
// TRelations
|
|
174
|
-
return new ViewBuilder({
|
|
175
|
-
...this.meta,
|
|
176
|
-
relations: fn(createRelationFactory<this, keyof TData & string>(() => this)),
|
|
177
|
-
}) as any;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// ============================================
|
|
182
|
-
// View
|
|
183
|
-
// ============================================
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* ViewBuilder를 생성하여 Fluent API로
|
|
189
|
-
*
|
|
190
|
-
* @param name -
|
|
191
|
-
* @returns ViewBuilder
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```typescript
|
|
195
|
-
* //
|
|
196
|
-
* const ActiveUsers = View("ActiveUsers")
|
|
197
|
-
* .database("mydb")
|
|
198
|
-
* .query((db: MyDb) =>
|
|
199
|
-
* db.user()
|
|
200
|
-
* .where(u => [expr.eq(u.status, "active")])
|
|
201
|
-
* .select(u => ({ id: u.id, name: u.name }))
|
|
202
|
-
* );
|
|
203
|
-
*
|
|
204
|
-
* //
|
|
205
|
-
* const UserStats = View("UserStats")
|
|
206
|
-
* .database("mydb")
|
|
207
|
-
* .query((db: MyDb) =>
|
|
208
|
-
* db.user()
|
|
209
|
-
* .groupBy(u => ({ status: u.status }))
|
|
210
|
-
* .select(u => ({
|
|
211
|
-
* status: u.status,
|
|
212
|
-
* count: expr.count(u.id),
|
|
213
|
-
* }))
|
|
214
|
-
* );
|
|
215
|
-
* ```
|
|
216
|
-
*
|
|
217
|
-
* @see {@link ViewBuilder}
|
|
218
|
-
*/
|
|
219
|
-
export function View(name: string) {
|
|
220
|
-
return new ViewBuilder({ name });
|
|
221
|
-
}
|
|
1
|
+
import type { DbContextBase } from "../types/db-context-def";
|
|
2
|
+
import type { Queryable } from "../exec/queryable";
|
|
3
|
+
import type { DataRecord } from "../types/db";
|
|
4
|
+
import {
|
|
5
|
+
createRelationFactory,
|
|
6
|
+
type InferDeepRelations,
|
|
7
|
+
type RelationBuilderRecord,
|
|
8
|
+
} from "./factory/relation-builder";
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// ViewBuilder
|
|
12
|
+
// ============================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Database View definition builder
|
|
16
|
+
*
|
|
17
|
+
* Fluent API를 통해 View의 query, 관계를 definition
|
|
18
|
+
* DbContext에서 queryable()과 함께 사용하여 type 안전한 query 작성
|
|
19
|
+
*
|
|
20
|
+
* @template TDbContext - DbContext type
|
|
21
|
+
* @template TData - View data record type
|
|
22
|
+
* @template TRelations - relationship definition record type
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // View definition
|
|
27
|
+
* const UserSummary = View("UserSummary")
|
|
28
|
+
* .database("mydb")
|
|
29
|
+
* .query((db: MyDb) =>
|
|
30
|
+
* db.user()
|
|
31
|
+
* .select(u => ({
|
|
32
|
+
* id: u.id,
|
|
33
|
+
* name: u.name,
|
|
34
|
+
* postCount: expr.subquery(
|
|
35
|
+
* db.post().where(p => [expr.eq(p.authorId, u.id)]),
|
|
36
|
+
* q => expr.count(q.id)
|
|
37
|
+
* ),
|
|
38
|
+
* }))
|
|
39
|
+
* );
|
|
40
|
+
*
|
|
41
|
+
* // DbContextused in
|
|
42
|
+
* class MyDb extends DbContext {
|
|
43
|
+
* readonly userSummary = queryable(this, UserSummary);
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @see {@link View} factory function
|
|
48
|
+
* @see {@link queryable} Queryable Generate
|
|
49
|
+
*/
|
|
50
|
+
export class ViewBuilder<
|
|
51
|
+
TDbContext extends DbContextBase,
|
|
52
|
+
TData extends DataRecord,
|
|
53
|
+
TRelations extends RelationBuilderRecord,
|
|
54
|
+
> {
|
|
55
|
+
/** relationship definition (type for inference) */
|
|
56
|
+
readonly $relations!: TRelations;
|
|
57
|
+
/** 전체 Type inference */
|
|
58
|
+
readonly $infer!: TData;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param meta - View Metadata
|
|
62
|
+
* @param meta.name - View 이름
|
|
63
|
+
* @param meta.description - View description (주석)
|
|
64
|
+
* @param meta.database - Database 이름
|
|
65
|
+
* @param meta.schema - Schema 이름 (MSSQL/PostgreSQL)
|
|
66
|
+
* @param meta.viewFn - View Query definition function
|
|
67
|
+
* @param meta.relations - relationship definition
|
|
68
|
+
*/
|
|
69
|
+
constructor(
|
|
70
|
+
readonly meta: {
|
|
71
|
+
name: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
database?: string;
|
|
74
|
+
schema?: string;
|
|
75
|
+
viewFn?: (db: TDbContext) => Queryable<TData, any>;
|
|
76
|
+
relations?: TRelations;
|
|
77
|
+
},
|
|
78
|
+
) {}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* View set description
|
|
82
|
+
*
|
|
83
|
+
* @param desc - View description (DDL Comment으로 사용)
|
|
84
|
+
* @returns new ViewBuilder instance
|
|
85
|
+
*/
|
|
86
|
+
description(desc: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
87
|
+
return new ViewBuilder({ ...this.meta, description: desc });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Database set name
|
|
92
|
+
*
|
|
93
|
+
* @param db - Database 이름
|
|
94
|
+
* @returns new ViewBuilder instance
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const UserSummary = View("UserSummary").database("mydb");
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
database(db: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
102
|
+
return new ViewBuilder({ ...this.meta, database: db });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* schema set name
|
|
107
|
+
*
|
|
108
|
+
* MSSQL, PostgreSQLused in
|
|
109
|
+
*
|
|
110
|
+
* @param schema - Schema 이름 (MSSQL: dbo, PostgreSQL: public)
|
|
111
|
+
* @returns new ViewBuilder instance
|
|
112
|
+
*/
|
|
113
|
+
schema(schema: string): ViewBuilder<TDbContext, TData, TRelations> {
|
|
114
|
+
return new ViewBuilder({ ...this.meta, schema });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* View Query definition
|
|
119
|
+
*
|
|
120
|
+
* SELECT query를 통해 View의 data 소스 definition
|
|
121
|
+
*
|
|
122
|
+
* @template TViewData - View data type
|
|
123
|
+
* @template TDb - DbContext type
|
|
124
|
+
* @param viewFn - DbContext를 받아 Queryable을 반환하는 function
|
|
125
|
+
* @returns new ViewBuilder instance
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const ActiveUsers = View("ActiveUsers")
|
|
130
|
+
* .database("mydb")
|
|
131
|
+
* .query((db: MyDb) =>
|
|
132
|
+
* db.user()
|
|
133
|
+
* .where(u => [expr.eq(u.status, "active")])
|
|
134
|
+
* .select(u => ({
|
|
135
|
+
* id: u.id,
|
|
136
|
+
* name: u.name,
|
|
137
|
+
* email: u.email,
|
|
138
|
+
* }))
|
|
139
|
+
* );
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
query<TViewData extends DataRecord, TDb extends DbContextBase>(
|
|
143
|
+
viewFn: (db: TDb) => Queryable<TViewData, any>,
|
|
144
|
+
): ViewBuilder<TDb, TViewData, TRelations> {
|
|
145
|
+
return new ViewBuilder({ ...this.meta, viewFn });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* relationship definition
|
|
150
|
+
*
|
|
151
|
+
* 다른 Table/View와의 relationship 설정
|
|
152
|
+
*
|
|
153
|
+
* @template T - relationship definition type
|
|
154
|
+
* @param fn - relationship factory를 받아 relationship 정의를 반환하는 function
|
|
155
|
+
* @returns new ViewBuilder instance
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* const UserSummary = View("UserSummary")
|
|
160
|
+
* .query((db: MyDb) => db.user().select(...))
|
|
161
|
+
* .relations((r) => ({
|
|
162
|
+
* posts: r.foreignKeyTarget(Post, "author"),
|
|
163
|
+
* }));
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @see {@link ForeignKeyBuilder} FK builder
|
|
167
|
+
* @see {@link ForeignKeyTargetBuilder} FK 역참조 builder
|
|
168
|
+
*/
|
|
169
|
+
relations<T extends RelationBuilderRecord>(
|
|
170
|
+
fn: (r: ReturnType<typeof createRelationFactory<this, keyof TData & string>>) => T,
|
|
171
|
+
): ViewBuilder<TDbContext, TData & InferDeepRelations<T>, TRelations> {
|
|
172
|
+
// TypeScript의 generic Type inference 한계로 인해 캐스팅 불가피
|
|
173
|
+
// TRelations type 파라미터와 새로 생성되는 relationship type T 간의 type 불일치 해결
|
|
174
|
+
return new ViewBuilder({
|
|
175
|
+
...this.meta,
|
|
176
|
+
relations: fn(createRelationFactory<this, keyof TData & string>(() => this)),
|
|
177
|
+
}) as any;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ============================================
|
|
182
|
+
// View function
|
|
183
|
+
// ============================================
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* View builder Generate factory function
|
|
187
|
+
*
|
|
188
|
+
* ViewBuilder를 생성하여 Fluent API로 View schema definition
|
|
189
|
+
*
|
|
190
|
+
* @param name - View 이름
|
|
191
|
+
* @returns ViewBuilder instance
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* // Basic 사용
|
|
196
|
+
* const ActiveUsers = View("ActiveUsers")
|
|
197
|
+
* .database("mydb")
|
|
198
|
+
* .query((db: MyDb) =>
|
|
199
|
+
* db.user()
|
|
200
|
+
* .where(u => [expr.eq(u.status, "active")])
|
|
201
|
+
* .select(u => ({ id: u.id, name: u.name }))
|
|
202
|
+
* );
|
|
203
|
+
*
|
|
204
|
+
* // aggregation View
|
|
205
|
+
* const UserStats = View("UserStats")
|
|
206
|
+
* .database("mydb")
|
|
207
|
+
* .query((db: MyDb) =>
|
|
208
|
+
* db.user()
|
|
209
|
+
* .groupBy(u => ({ status: u.status }))
|
|
210
|
+
* .select(u => ({
|
|
211
|
+
* status: u.status,
|
|
212
|
+
* count: expr.count(u.id),
|
|
213
|
+
* }))
|
|
214
|
+
* );
|
|
215
|
+
* ```
|
|
216
|
+
*
|
|
217
|
+
* @see {@link ViewBuilder} builder class
|
|
218
|
+
*/
|
|
219
|
+
export function View(name: string) {
|
|
220
|
+
return new ViewBuilder({ name });
|
|
221
|
+
}
|