@simplysm/orm-common 13.0.69 → 13.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +54 -1447
  2. package/dist/create-db-context.d.ts +10 -10
  3. package/dist/create-db-context.js +9 -9
  4. package/dist/create-db-context.js.map +1 -1
  5. package/dist/ddl/column-ddl.d.ts +4 -4
  6. package/dist/ddl/initialize.d.ts +17 -17
  7. package/dist/ddl/initialize.js +2 -2
  8. package/dist/ddl/initialize.js.map +1 -1
  9. package/dist/ddl/relation-ddl.d.ts +6 -6
  10. package/dist/ddl/schema-ddl.d.ts +4 -4
  11. package/dist/ddl/table-ddl.d.ts +24 -24
  12. package/dist/ddl/table-ddl.js +4 -4
  13. package/dist/ddl/table-ddl.js.map +1 -1
  14. package/dist/errors/db-transaction-error.d.ts +15 -15
  15. package/dist/errors/db-transaction-error.d.ts.map +1 -1
  16. package/dist/exec/executable.d.ts +23 -23
  17. package/dist/exec/executable.js +3 -3
  18. package/dist/exec/executable.js.map +1 -1
  19. package/dist/exec/queryable.d.ts +160 -160
  20. package/dist/exec/queryable.js +119 -119
  21. package/dist/exec/queryable.js.map +1 -1
  22. package/dist/exec/search-parser.d.ts +37 -37
  23. package/dist/exec/search-parser.d.ts.map +1 -1
  24. package/dist/expr/expr-unit.d.ts +4 -4
  25. package/dist/expr/expr.d.ts +257 -257
  26. package/dist/expr/expr.js +265 -265
  27. package/dist/expr/expr.js.map +1 -1
  28. package/dist/query-builder/base/expr-renderer-base.d.ts +9 -9
  29. package/dist/query-builder/base/expr-renderer-base.js +2 -2
  30. package/dist/query-builder/base/expr-renderer-base.js.map +1 -1
  31. package/dist/query-builder/base/query-builder-base.d.ts +26 -26
  32. package/dist/query-builder/base/query-builder-base.d.ts.map +1 -1
  33. package/dist/query-builder/base/query-builder-base.js +22 -22
  34. package/dist/query-builder/base/query-builder-base.js.map +1 -1
  35. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +4 -4
  36. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
  37. package/dist/query-builder/mssql/mssql-expr-renderer.js +18 -18
  38. package/dist/query-builder/mssql/mssql-expr-renderer.js.map +1 -1
  39. package/dist/query-builder/mssql/mssql-query-builder.d.ts +2 -2
  40. package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
  41. package/dist/query-builder/mssql/mssql-query-builder.js +11 -11
  42. package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -1
  43. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +4 -4
  44. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
  45. package/dist/query-builder/mysql/mysql-expr-renderer.js +17 -17
  46. package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -1
  47. package/dist/query-builder/mysql/mysql-query-builder.d.ts +8 -8
  48. package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
  49. package/dist/query-builder/mysql/mysql-query-builder.js +5 -5
  50. package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -1
  51. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +4 -4
  52. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
  53. package/dist/query-builder/postgresql/postgresql-expr-renderer.js +17 -17
  54. package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -1
  55. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +5 -5
  56. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
  57. package/dist/query-builder/postgresql/postgresql-query-builder.js +8 -8
  58. package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -1
  59. package/dist/query-builder/query-builder.d.ts +1 -1
  60. package/dist/schema/factory/column-builder.d.ts +79 -79
  61. package/dist/schema/factory/column-builder.js +42 -42
  62. package/dist/schema/factory/index-builder.d.ts +39 -39
  63. package/dist/schema/factory/index-builder.js +26 -26
  64. package/dist/schema/factory/relation-builder.d.ts +99 -99
  65. package/dist/schema/factory/relation-builder.d.ts.map +1 -1
  66. package/dist/schema/factory/relation-builder.js +38 -38
  67. package/dist/schema/procedure-builder.d.ts +49 -49
  68. package/dist/schema/procedure-builder.d.ts.map +1 -1
  69. package/dist/schema/procedure-builder.js +33 -33
  70. package/dist/schema/table-builder.d.ts +59 -59
  71. package/dist/schema/table-builder.d.ts.map +1 -1
  72. package/dist/schema/table-builder.js +43 -43
  73. package/dist/schema/view-builder.d.ts +49 -49
  74. package/dist/schema/view-builder.d.ts.map +1 -1
  75. package/dist/schema/view-builder.js +32 -32
  76. package/dist/types/column.d.ts +22 -22
  77. package/dist/types/column.js +1 -1
  78. package/dist/types/column.js.map +1 -1
  79. package/dist/types/db.d.ts +40 -40
  80. package/dist/types/expr.d.ts +59 -59
  81. package/dist/types/expr.d.ts.map +1 -1
  82. package/dist/types/query-def.d.ts +44 -44
  83. package/dist/types/query-def.d.ts.map +1 -1
  84. package/dist/utils/result-parser.d.ts +11 -11
  85. package/dist/utils/result-parser.js +3 -3
  86. package/dist/utils/result-parser.js.map +1 -1
  87. package/package.json +5 -5
  88. package/src/create-db-context.ts +20 -20
  89. package/src/ddl/column-ddl.ts +4 -4
  90. package/src/ddl/initialize.ts +259 -259
  91. package/src/ddl/relation-ddl.ts +89 -89
  92. package/src/ddl/schema-ddl.ts +4 -4
  93. package/src/ddl/table-ddl.ts +189 -189
  94. package/src/errors/db-transaction-error.ts +13 -13
  95. package/src/exec/executable.ts +25 -25
  96. package/src/exec/queryable.ts +2033 -2033
  97. package/src/exec/search-parser.ts +57 -57
  98. package/src/expr/expr-unit.ts +4 -4
  99. package/src/expr/expr.ts +2140 -2140
  100. package/src/query-builder/base/expr-renderer-base.ts +237 -237
  101. package/src/query-builder/base/query-builder-base.ts +213 -213
  102. package/src/query-builder/mssql/mssql-expr-renderer.ts +607 -607
  103. package/src/query-builder/mssql/mssql-query-builder.ts +650 -650
  104. package/src/query-builder/mysql/mysql-expr-renderer.ts +613 -613
  105. package/src/query-builder/mysql/mysql-query-builder.ts +759 -759
  106. package/src/query-builder/postgresql/postgresql-expr-renderer.ts +611 -611
  107. package/src/query-builder/postgresql/postgresql-query-builder.ts +686 -686
  108. package/src/query-builder/query-builder.ts +19 -19
  109. package/src/schema/factory/column-builder.ts +423 -423
  110. package/src/schema/factory/index-builder.ts +164 -164
  111. package/src/schema/factory/relation-builder.ts +453 -453
  112. package/src/schema/procedure-builder.ts +232 -232
  113. package/src/schema/table-builder.ts +319 -319
  114. package/src/schema/view-builder.ts +221 -221
  115. package/src/types/column.ts +188 -188
  116. package/src/types/db.ts +208 -208
  117. package/src/types/expr.ts +697 -697
  118. package/src/types/query-def.ts +513 -513
  119. package/src/utils/result-parser.ts +458 -458
  120. package/tests/db-context/create-db-context.spec.ts +224 -0
  121. package/tests/db-context/define-db-context.spec.ts +68 -0
  122. package/tests/ddl/basic.expected.ts +341 -0
  123. package/tests/ddl/basic.spec.ts +714 -0
  124. package/tests/ddl/column-builder.expected.ts +310 -0
  125. package/tests/ddl/column-builder.spec.ts +637 -0
  126. package/tests/ddl/index-builder.expected.ts +38 -0
  127. package/tests/ddl/index-builder.spec.ts +202 -0
  128. package/tests/ddl/procedure-builder.expected.ts +52 -0
  129. package/tests/ddl/procedure-builder.spec.ts +234 -0
  130. package/tests/ddl/relation-builder.expected.ts +36 -0
  131. package/tests/ddl/relation-builder.spec.ts +372 -0
  132. package/tests/ddl/table-builder.expected.ts +113 -0
  133. package/tests/ddl/table-builder.spec.ts +433 -0
  134. package/tests/ddl/view-builder.expected.ts +38 -0
  135. package/tests/ddl/view-builder.spec.ts +176 -0
  136. package/tests/dml/delete.expected.ts +96 -0
  137. package/tests/dml/delete.spec.ts +160 -0
  138. package/tests/dml/insert.expected.ts +192 -0
  139. package/tests/dml/insert.spec.ts +288 -0
  140. package/tests/dml/update.expected.ts +176 -0
  141. package/tests/dml/update.spec.ts +318 -0
  142. package/tests/dml/upsert.expected.ts +215 -0
  143. package/tests/dml/upsert.spec.ts +242 -0
  144. package/tests/errors/queryable-errors.spec.ts +177 -0
  145. package/tests/escape.spec.ts +100 -0
  146. package/tests/examples/pivot.expected.ts +211 -0
  147. package/tests/examples/pivot.spec.ts +533 -0
  148. package/tests/examples/sampling.expected.ts +69 -0
  149. package/tests/examples/sampling.spec.ts +104 -0
  150. package/tests/examples/unpivot.expected.ts +120 -0
  151. package/tests/examples/unpivot.spec.ts +226 -0
  152. package/tests/exec/search-parser.spec.ts +283 -0
  153. package/tests/executable/basic.expected.ts +18 -0
  154. package/tests/executable/basic.spec.ts +54 -0
  155. package/tests/expr/comparison.expected.ts +282 -0
  156. package/tests/expr/comparison.spec.ts +400 -0
  157. package/tests/expr/conditional.expected.ts +134 -0
  158. package/tests/expr/conditional.spec.ts +276 -0
  159. package/tests/expr/date.expected.ts +332 -0
  160. package/tests/expr/date.spec.ts +526 -0
  161. package/tests/expr/math.expected.ts +62 -0
  162. package/tests/expr/math.spec.ts +106 -0
  163. package/tests/expr/string.expected.ts +218 -0
  164. package/tests/expr/string.spec.ts +356 -0
  165. package/tests/expr/utility.expected.ts +147 -0
  166. package/tests/expr/utility.spec.ts +182 -0
  167. package/tests/select/basic.expected.ts +322 -0
  168. package/tests/select/basic.spec.ts +502 -0
  169. package/tests/select/filter.expected.ts +357 -0
  170. package/tests/select/filter.spec.ts +1068 -0
  171. package/tests/select/group.expected.ts +169 -0
  172. package/tests/select/group.spec.ts +244 -0
  173. package/tests/select/join.expected.ts +582 -0
  174. package/tests/select/join.spec.ts +805 -0
  175. package/tests/select/order.expected.ts +150 -0
  176. package/tests/select/order.spec.ts +189 -0
  177. package/tests/select/recursive-cte.expected.ts +244 -0
  178. package/tests/select/recursive-cte.spec.ts +514 -0
  179. package/tests/select/result-meta.spec.ts +270 -0
  180. package/tests/select/subquery.expected.ts +363 -0
  181. package/tests/select/subquery.spec.ts +537 -0
  182. package/tests/select/view.expected.ts +155 -0
  183. package/tests/select/view.spec.ts +235 -0
  184. package/tests/select/window.expected.ts +345 -0
  185. package/tests/select/window.spec.ts +618 -0
  186. package/tests/setup/MockExecutor.ts +18 -0
  187. package/tests/setup/TestDbContext.ts +59 -0
  188. package/tests/setup/models/Company.ts +13 -0
  189. package/tests/setup/models/Employee.ts +10 -0
  190. package/tests/setup/models/MonthlySales.ts +11 -0
  191. package/tests/setup/models/Post.ts +16 -0
  192. package/tests/setup/models/Sales.ts +10 -0
  193. package/tests/setup/models/User.ts +19 -0
  194. package/tests/setup/procedure/GetAllUsers.ts +9 -0
  195. package/tests/setup/procedure/GetUserById.ts +12 -0
  196. package/tests/setup/test-utils.ts +72 -0
  197. package/tests/setup/views/ActiveUsers.ts +8 -0
  198. package/tests/setup/views/UserSummary.ts +11 -0
  199. package/tests/types/nullable-queryable-record.spec.ts +145 -0
  200. package/tests/utils/result-parser-perf.spec.ts +210 -0
  201. package/tests/utils/result-parser.spec.ts +701 -0
  202. package/docs/expressions.md +0 -172
  203. package/docs/queries.md +0 -444
  204. 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
- * // DbContext에서 사용
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 - 스키마 이름 (MSSQL/PostgreSQL)
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 - 설명 (DDL 주석으로 사용)
84
- * @returns ViewBuilder 인스턴스
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 ViewBuilder 인스턴스
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, PostgreSQL에서 사용
109
- *
110
- * @param schema - 스키마 이름 (MSSQL: dbo, PostgreSQL: public)
111
- * @returns ViewBuilder 인스턴스
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 ViewBuilder 인스턴스
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 ViewBuilder 인스턴스
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 타입 파라미터와 새로 생성되는 관계 타입 T 간의 타입 불일치 해결
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
+ }