@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.
- 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 +104 -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,423 +1,423 @@
|
|
|
1
|
-
import type { Bytes, DateOnly, DateTime, Time, Uuid } from "@simplysm/core-common";
|
|
2
|
-
import type { ColumnMeta, ColumnPrimitive } from "../../types/column";
|
|
3
|
-
import type { ExprInput } from "../../expr/expr-unit";
|
|
4
|
-
import type { DataRecord } from "../../types/db";
|
|
5
|
-
|
|
6
|
-
// ============================================
|
|
7
|
-
// ColumnBuilder
|
|
8
|
-
// ============================================
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Fluent API를 통해
|
|
14
|
-
* TableBuilder.columns()
|
|
15
|
-
*
|
|
16
|
-
* @template TValue -
|
|
17
|
-
* @template TMeta -
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* Table("User")
|
|
22
|
-
* .columns((c) => ({
|
|
23
|
-
* id: c.bigint().autoIncrement(), // bigint, auto increment
|
|
24
|
-
* name: c.varchar(100), // varchar(100), required
|
|
25
|
-
* email: c.varchar(200).nullable(), // varchar(200), nullable
|
|
26
|
-
* status: c.varchar(20).default("active"), // varchar(20), default
|
|
27
|
-
* createdAt: c.datetime().description("생성일시"),
|
|
28
|
-
* }));
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @see {@link createColumnFactory}
|
|
32
|
-
* @see {@link TableBuilder}
|
|
33
|
-
*/
|
|
34
|
-
export class ColumnBuilder<TValue extends ColumnPrimitive, TMeta extends ColumnMeta> {
|
|
35
|
-
/**
|
|
36
|
-
* @param meta -
|
|
37
|
-
*/
|
|
38
|
-
constructor(readonly meta: TMeta) {}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Auto Increment 설정
|
|
42
|
-
*
|
|
43
|
-
* INSERT 시
|
|
44
|
-
*
|
|
45
|
-
* @returns
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```typescript
|
|
49
|
-
* id: c.bigint().autoIncrement()
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
autoIncrement(): ColumnBuilder<TValue, Omit<TMeta, "autoIncrement"> & { autoIncrement: true }> {
|
|
53
|
-
return new ColumnBuilder({ ...this.meta, autoIncrement: true });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Nullable 설정
|
|
58
|
-
*
|
|
59
|
-
* NULL
|
|
60
|
-
*
|
|
61
|
-
* @returns
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```typescript
|
|
65
|
-
* email: c.varchar(200).nullable() // string | undefined
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
nullable(): ColumnBuilder<TValue | undefined, Omit<TMeta, "nullable"> & { nullable: true }> {
|
|
69
|
-
return new ColumnBuilder({ ...this.meta, nullable: true });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* INSERT 시
|
|
76
|
-
*
|
|
77
|
-
* @param value -
|
|
78
|
-
* @returns
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```typescript
|
|
82
|
-
* status: c.varchar(20).default("active")
|
|
83
|
-
* createdAt: c.datetime().default("CURRENT_TIMESTAMP")
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
default(
|
|
87
|
-
value: TValue,
|
|
88
|
-
): ColumnBuilder<TValue, Omit<TMeta, "default"> & { default: typeof value }> {
|
|
89
|
-
return new ColumnBuilder({ ...this.meta, default: value });
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* @param desc -
|
|
96
|
-
* @returns
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* createdAt: c.datetime().description("레코드
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
description(desc: string): ColumnBuilder<TValue, TMeta & { description: string }> {
|
|
104
|
-
return new ColumnBuilder({ ...this.meta, description: desc });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ============================================
|
|
109
|
-
//
|
|
110
|
-
// ============================================
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* TableBuilder.columns()
|
|
116
|
-
* 모든
|
|
117
|
-
*
|
|
118
|
-
* @returns
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```typescript
|
|
122
|
-
* Table("User")
|
|
123
|
-
* .columns((c) => ({
|
|
124
|
-
* //
|
|
125
|
-
* id: c.bigint().autoIncrement(),
|
|
126
|
-
* count: c.int(),
|
|
127
|
-
* price: c.decimal(10, 2),
|
|
128
|
-
*
|
|
129
|
-
* // 문자열
|
|
130
|
-
* name: c.varchar(100),
|
|
131
|
-
* code: c.char(10),
|
|
132
|
-
* content: c.text(),
|
|
133
|
-
*
|
|
134
|
-
* //
|
|
135
|
-
* createdAt: c.datetime(),
|
|
136
|
-
* birthDate: c.date(),
|
|
137
|
-
* startTime: c.time(),
|
|
138
|
-
*
|
|
139
|
-
* //
|
|
140
|
-
* isActive: c.boolean(),
|
|
141
|
-
* data: c.binary(),
|
|
142
|
-
* uuid: c.uuid(),
|
|
143
|
-
* }));
|
|
144
|
-
* ```
|
|
145
|
-
*
|
|
146
|
-
* @see {@link ColumnBuilder}
|
|
147
|
-
*/
|
|
148
|
-
export function createColumnFactory() {
|
|
149
|
-
return {
|
|
150
|
-
/**
|
|
151
|
-
* INT
|
|
152
|
-
*
|
|
153
|
-
* @returns ColumnBuilder
|
|
154
|
-
*/
|
|
155
|
-
int(): ColumnBuilder<number, { type: "number"; dataType: { type: "int" } }> {
|
|
156
|
-
return new ColumnBuilder({ type: "number", dataType: { type: "int" } });
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* BIGINT
|
|
161
|
-
*
|
|
162
|
-
* @returns ColumnBuilder
|
|
163
|
-
*/
|
|
164
|
-
bigint(): ColumnBuilder<number, { type: "number"; dataType: { type: "bigint" } }> {
|
|
165
|
-
return new ColumnBuilder({ type: "number", dataType: { type: "bigint" } });
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* FLOAT
|
|
170
|
-
*
|
|
171
|
-
* @returns ColumnBuilder
|
|
172
|
-
*/
|
|
173
|
-
float(): ColumnBuilder<number, { type: "number"; dataType: { type: "float" } }> {
|
|
174
|
-
return new ColumnBuilder({ type: "number", dataType: { type: "float" } });
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* DOUBLE
|
|
179
|
-
*
|
|
180
|
-
* @returns ColumnBuilder
|
|
181
|
-
*/
|
|
182
|
-
double(): ColumnBuilder<number, { type: "number"; dataType: { type: "double" } }> {
|
|
183
|
-
return new ColumnBuilder({ type: "number", dataType: { type: "double" } });
|
|
184
|
-
},
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* DECIMAL
|
|
188
|
-
*
|
|
189
|
-
* @param precision - 전체 자릿수
|
|
190
|
-
* @param scale - 소수점 이하 자릿수 (
|
|
191
|
-
* @returns ColumnBuilder
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```typescript
|
|
195
|
-
* price: c.decimal(10, 2) // DECIMAL(10, 2)
|
|
196
|
-
* ```
|
|
197
|
-
*/
|
|
198
|
-
decimal(
|
|
199
|
-
precision: number,
|
|
200
|
-
scale?: number,
|
|
201
|
-
): ColumnBuilder<
|
|
202
|
-
number,
|
|
203
|
-
{ type: "number"; dataType: { type: "decimal"; precision: number; scale?: number } }
|
|
204
|
-
> {
|
|
205
|
-
return new ColumnBuilder({ type: "number", dataType: { type: "decimal", precision, scale } });
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* VARCHAR
|
|
210
|
-
*
|
|
211
|
-
* @param length - 최대 길이
|
|
212
|
-
* @returns ColumnBuilder
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* ```typescript
|
|
216
|
-
* name: c.varchar(100) // VARCHAR(100)
|
|
217
|
-
* ```
|
|
218
|
-
*/
|
|
219
|
-
varchar(
|
|
220
|
-
length: number,
|
|
221
|
-
): ColumnBuilder<string, { type: "string"; dataType: { type: "varchar"; length: number } }> {
|
|
222
|
-
return new ColumnBuilder({ type: "string", dataType: { type: "varchar", length } });
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* CHAR
|
|
227
|
-
*
|
|
228
|
-
* @param length - 고정 길이
|
|
229
|
-
* @returns ColumnBuilder
|
|
230
|
-
*
|
|
231
|
-
* @example
|
|
232
|
-
* ```typescript
|
|
233
|
-
* countryCode: c.char(2) // CHAR(2)
|
|
234
|
-
* ```
|
|
235
|
-
*/
|
|
236
|
-
char(
|
|
237
|
-
length: number,
|
|
238
|
-
): ColumnBuilder<string, { type: "string"; dataType: { type: "char"; length: number } }> {
|
|
239
|
-
return new ColumnBuilder({ type: "string", dataType: { type: "char" as const, length } });
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* TEXT
|
|
244
|
-
*
|
|
245
|
-
* @returns ColumnBuilder
|
|
246
|
-
*/
|
|
247
|
-
text(): ColumnBuilder<string, { type: "string"; dataType: { type: "text" } }> {
|
|
248
|
-
return new ColumnBuilder({ type: "string", dataType: { type: "text" } });
|
|
249
|
-
},
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* BINARY
|
|
253
|
-
*
|
|
254
|
-
* DBMS별: MySQL=LONGBLOB, MSSQL=VARBINARY(MAX), PostgreSQL=BYTEA
|
|
255
|
-
*
|
|
256
|
-
* @returns ColumnBuilder
|
|
257
|
-
*/
|
|
258
|
-
binary(): ColumnBuilder<Bytes, { type: "Bytes"; dataType: { type: "binary" } }> {
|
|
259
|
-
return new ColumnBuilder({ type: "Bytes", dataType: { type: "binary" } });
|
|
260
|
-
},
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* BOOLEAN
|
|
264
|
-
*
|
|
265
|
-
* DBMS별: MySQL=TINYINT(1), MSSQL=BIT, PostgreSQL=BOOLEAN
|
|
266
|
-
*
|
|
267
|
-
* @returns ColumnBuilder
|
|
268
|
-
*/
|
|
269
|
-
boolean(): ColumnBuilder<boolean, { type: "boolean"; dataType: { type: "boolean" } }> {
|
|
270
|
-
return new ColumnBuilder({ type: "boolean", dataType: { type: "boolean" } });
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* DATETIME
|
|
275
|
-
*
|
|
276
|
-
* @returns ColumnBuilder
|
|
277
|
-
*/
|
|
278
|
-
datetime(): ColumnBuilder<DateTime, { type: "DateTime"; dataType: { type: "datetime" } }> {
|
|
279
|
-
return new ColumnBuilder({ type: "DateTime", dataType: { type: "datetime" } });
|
|
280
|
-
},
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* DATE
|
|
284
|
-
*
|
|
285
|
-
* @returns ColumnBuilder
|
|
286
|
-
*/
|
|
287
|
-
date(): ColumnBuilder<DateOnly, { type: "DateOnly"; dataType: { type: "date" } }> {
|
|
288
|
-
return new ColumnBuilder({ type: "DateOnly", dataType: { type: "date" } });
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* TIME
|
|
293
|
-
*
|
|
294
|
-
* @returns ColumnBuilder
|
|
295
|
-
*/
|
|
296
|
-
time(): ColumnBuilder<Time, { type: "Time"; dataType: { type: "time" } }> {
|
|
297
|
-
return new ColumnBuilder({ type: "Time", dataType: { type: "time" } });
|
|
298
|
-
},
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* UUID
|
|
302
|
-
*
|
|
303
|
-
* DBMS별: MySQL=BINARY(16), MSSQL=UNIQUEIDENTIFIER, PostgreSQL=UUID
|
|
304
|
-
*
|
|
305
|
-
* @returns ColumnBuilder
|
|
306
|
-
*/
|
|
307
|
-
uuid(): ColumnBuilder<Uuid, { type: "Uuid"; dataType: { type: "uuid" } }> {
|
|
308
|
-
return new ColumnBuilder({ type: "Uuid", dataType: { type: "uuid" } });
|
|
309
|
-
},
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// ============================================
|
|
314
|
-
// ColumnDefRecord -
|
|
315
|
-
// ============================================
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* TableBuilder.columns()의
|
|
321
|
-
*/
|
|
322
|
-
export type ColumnBuilderRecord = Record<string, ColumnBuilder<ColumnPrimitive, ColumnMeta>>;
|
|
323
|
-
|
|
324
|
-
// ============================================
|
|
325
|
-
// Infer -
|
|
326
|
-
// ============================================
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
* @template T -
|
|
332
|
-
*
|
|
333
|
-
* @example
|
|
334
|
-
* ```typescript
|
|
335
|
-
* type UserColumns = InferColumns<typeof User.$columns>;
|
|
336
|
-
* // { id: number; name: string; email: string | undefined; }
|
|
337
|
-
* ```
|
|
338
|
-
*/
|
|
339
|
-
export type InferColumns<TBuilders extends ColumnBuilderRecord> = {
|
|
340
|
-
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? V : never;
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
* @template T -
|
|
347
|
-
*/
|
|
348
|
-
export type InferColumnExprs<TBuilders extends ColumnBuilderRecord> = {
|
|
349
|
-
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? ExprInput<V> : never;
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* INSERT 시
|
|
354
|
-
*
|
|
355
|
-
* autoIncrement, nullable, default가 없는
|
|
356
|
-
*
|
|
357
|
-
* @template T -
|
|
358
|
-
*/
|
|
359
|
-
export type RequiredInsertKeys<TBuilders extends ColumnBuilderRecord> = {
|
|
360
|
-
[K in keyof TBuilders]: TBuilders[K]["meta"] extends infer M extends ColumnMeta
|
|
361
|
-
? M["autoIncrement"] extends true
|
|
362
|
-
? never
|
|
363
|
-
: M["nullable"] extends true
|
|
364
|
-
? never
|
|
365
|
-
: M["default"] extends undefined
|
|
366
|
-
? K
|
|
367
|
-
: never
|
|
368
|
-
: never;
|
|
369
|
-
}[keyof TBuilders];
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* INSERT 시
|
|
373
|
-
*
|
|
374
|
-
* autoIncrement, nullable, default가 있는
|
|
375
|
-
*
|
|
376
|
-
* @template T -
|
|
377
|
-
*/
|
|
378
|
-
export type OptionalInsertKeys<TBuilders extends ColumnBuilderRecord> = Exclude<
|
|
379
|
-
keyof TBuilders,
|
|
380
|
-
RequiredInsertKeys<TBuilders>
|
|
381
|
-
>;
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* INSERT용
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
* @template T -
|
|
389
|
-
*
|
|
390
|
-
* @example
|
|
391
|
-
* ```typescript
|
|
392
|
-
* type UserInsert = InferInsertColumns<typeof User.$columns>;
|
|
393
|
-
* // { name: string; } & { id?: number; email?: string; status?: string; }
|
|
394
|
-
* ```
|
|
395
|
-
*/
|
|
396
|
-
export type InferInsertColumns<TBuilders extends ColumnBuilderRecord> = Pick<
|
|
397
|
-
InferColumns<TBuilders>,
|
|
398
|
-
RequiredInsertKeys<TBuilders>
|
|
399
|
-
> &
|
|
400
|
-
Partial<Pick<InferColumns<TBuilders>, OptionalInsertKeys<TBuilders>>>;
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* UPDATE용
|
|
404
|
-
*
|
|
405
|
-
* 모든
|
|
406
|
-
*
|
|
407
|
-
* @template T -
|
|
408
|
-
*/
|
|
409
|
-
export type InferUpdateColumns<TBuilders extends ColumnBuilderRecord> = Partial<
|
|
410
|
-
InferColumns<TBuilders>
|
|
411
|
-
>;
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
* @template TData -
|
|
417
|
-
*/
|
|
418
|
-
export type DataToColumnBuilderRecord<TData extends DataRecord> = {
|
|
419
|
-
[K in keyof TData as TData[K] extends ColumnPrimitive ? K : never]: ColumnBuilder<
|
|
420
|
-
TData[K] extends ColumnPrimitive ? TData[K] : never,
|
|
421
|
-
any
|
|
422
|
-
>;
|
|
423
|
-
};
|
|
1
|
+
import type { Bytes, DateOnly, DateTime, Time, Uuid } from "@simplysm/core-common";
|
|
2
|
+
import type { ColumnMeta, ColumnPrimitive } from "../../types/column";
|
|
3
|
+
import type { ExprInput } from "../../expr/expr-unit";
|
|
4
|
+
import type { DataRecord } from "../../types/db";
|
|
5
|
+
|
|
6
|
+
// ============================================
|
|
7
|
+
// ColumnBuilder
|
|
8
|
+
// ============================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Column definition builder
|
|
12
|
+
*
|
|
13
|
+
* Fluent API를 통해 column의 type, nullable, autoIncrement, default, description을 definition
|
|
14
|
+
* TableBuilder.columns()used in
|
|
15
|
+
*
|
|
16
|
+
* @template TValue - Column value type
|
|
17
|
+
* @template TMeta - Column Metadata type
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* Table("User")
|
|
22
|
+
* .columns((c) => ({
|
|
23
|
+
* id: c.bigint().autoIncrement(), // bigint, auto increment
|
|
24
|
+
* name: c.varchar(100), // varchar(100), required
|
|
25
|
+
* email: c.varchar(200).nullable(), // varchar(200), nullable
|
|
26
|
+
* status: c.varchar(20).default("active"), // varchar(20), default value
|
|
27
|
+
* createdAt: c.datetime().description("생성일시"),
|
|
28
|
+
* }));
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @see {@link createColumnFactory} column factory
|
|
32
|
+
* @see {@link TableBuilder} Table builder
|
|
33
|
+
*/
|
|
34
|
+
export class ColumnBuilder<TValue extends ColumnPrimitive, TMeta extends ColumnMeta> {
|
|
35
|
+
/**
|
|
36
|
+
* @param meta - Column Metadata
|
|
37
|
+
*/
|
|
38
|
+
constructor(readonly meta: TMeta) {}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Auto Increment 설정
|
|
42
|
+
*
|
|
43
|
+
* INSERT 시 Auto increment. INSERT용 Type inference에서 optional로 processing
|
|
44
|
+
*
|
|
45
|
+
* @returns new ColumnBuilder instance
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* id: c.bigint().autoIncrement()
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
autoIncrement(): ColumnBuilder<TValue, Omit<TMeta, "autoIncrement"> & { autoIncrement: true }> {
|
|
53
|
+
return new ColumnBuilder({ ...this.meta, autoIncrement: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Nullable 설정
|
|
58
|
+
*
|
|
59
|
+
* Allow NULL. value 타입에 undefined Add
|
|
60
|
+
*
|
|
61
|
+
* @returns new ColumnBuilder instance
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* email: c.varchar(200).nullable() // string | undefined
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
nullable(): ColumnBuilder<TValue | undefined, Omit<TMeta, "nullable"> & { nullable: true }> {
|
|
69
|
+
return new ColumnBuilder({ ...this.meta, nullable: true });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Default value 설정
|
|
74
|
+
*
|
|
75
|
+
* INSERT 시 value 미지정 시 사용. INSERT용 Type inference에서 optional로 processing
|
|
76
|
+
*
|
|
77
|
+
* @param value - Default value
|
|
78
|
+
* @returns new ColumnBuilder instance
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* status: c.varchar(20).default("active")
|
|
83
|
+
* createdAt: c.datetime().default("CURRENT_TIMESTAMP")
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
default(
|
|
87
|
+
value: TValue,
|
|
88
|
+
): ColumnBuilder<TValue, Omit<TMeta, "default"> & { default: typeof value }> {
|
|
89
|
+
return new ColumnBuilder({ ...this.meta, default: value });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* column set description
|
|
94
|
+
*
|
|
95
|
+
* @param desc - Column description (DDL Comment으로 사용)
|
|
96
|
+
* @returns new ColumnBuilder instance
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* createdAt: c.datetime().description("레코드 Generate 일시")
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
description(desc: string): ColumnBuilder<TValue, TMeta & { description: string }> {
|
|
104
|
+
return new ColumnBuilder({ ...this.meta, description: desc });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================
|
|
109
|
+
// column factory
|
|
110
|
+
// ============================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Column builder factory Generate
|
|
114
|
+
*
|
|
115
|
+
* TableBuilder.columns()used in하는 Column type factory
|
|
116
|
+
* 모든 Basic data type에 대한 builder Generate method 제공
|
|
117
|
+
*
|
|
118
|
+
* @returns Column type별 builder Generate 메서드를 포함한 object
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* Table("User")
|
|
123
|
+
* .columns((c) => ({
|
|
124
|
+
* // Number type
|
|
125
|
+
* id: c.bigint().autoIncrement(),
|
|
126
|
+
* count: c.int(),
|
|
127
|
+
* price: c.decimal(10, 2),
|
|
128
|
+
*
|
|
129
|
+
* // 문자열 type
|
|
130
|
+
* name: c.varchar(100),
|
|
131
|
+
* code: c.char(10),
|
|
132
|
+
* content: c.text(),
|
|
133
|
+
*
|
|
134
|
+
* // Date/시간 type
|
|
135
|
+
* createdAt: c.datetime(),
|
|
136
|
+
* birthDate: c.date(),
|
|
137
|
+
* startTime: c.time(),
|
|
138
|
+
*
|
|
139
|
+
* // Other type
|
|
140
|
+
* isActive: c.boolean(),
|
|
141
|
+
* data: c.binary(),
|
|
142
|
+
* uuid: c.uuid(),
|
|
143
|
+
* }));
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @see {@link ColumnBuilder} Column builder class
|
|
147
|
+
*/
|
|
148
|
+
export function createColumnFactory() {
|
|
149
|
+
return {
|
|
150
|
+
/**
|
|
151
|
+
* INT column (4 bytes, -2^31 ~ 2^31-1)
|
|
152
|
+
*
|
|
153
|
+
* @returns ColumnBuilder instance
|
|
154
|
+
*/
|
|
155
|
+
int(): ColumnBuilder<number, { type: "number"; dataType: { type: "int" } }> {
|
|
156
|
+
return new ColumnBuilder({ type: "number", dataType: { type: "int" } });
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* BIGINT column (8 bytes, -2^63 ~ 2^63-1)
|
|
161
|
+
*
|
|
162
|
+
* @returns ColumnBuilder instance
|
|
163
|
+
*/
|
|
164
|
+
bigint(): ColumnBuilder<number, { type: "number"; dataType: { type: "bigint" } }> {
|
|
165
|
+
return new ColumnBuilder({ type: "number", dataType: { type: "bigint" } });
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* FLOAT column (4 bytes, 단정밀도 부동소수점)
|
|
170
|
+
*
|
|
171
|
+
* @returns ColumnBuilder instance
|
|
172
|
+
*/
|
|
173
|
+
float(): ColumnBuilder<number, { type: "number"; dataType: { type: "float" } }> {
|
|
174
|
+
return new ColumnBuilder({ type: "number", dataType: { type: "float" } });
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* DOUBLE column (8 bytes, 배정밀도 부동소수점)
|
|
179
|
+
*
|
|
180
|
+
* @returns ColumnBuilder instance
|
|
181
|
+
*/
|
|
182
|
+
double(): ColumnBuilder<number, { type: "number"; dataType: { type: "double" } }> {
|
|
183
|
+
return new ColumnBuilder({ type: "number", dataType: { type: "double" } });
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* DECIMAL column (고정 소수점)
|
|
188
|
+
*
|
|
189
|
+
* @param precision - 전체 자릿수
|
|
190
|
+
* @param scale - 소수점 이하 자릿수 (Select)
|
|
191
|
+
* @returns ColumnBuilder instance
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* price: c.decimal(10, 2) // DECIMAL(10, 2)
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
decimal(
|
|
199
|
+
precision: number,
|
|
200
|
+
scale?: number,
|
|
201
|
+
): ColumnBuilder<
|
|
202
|
+
number,
|
|
203
|
+
{ type: "number"; dataType: { type: "decimal"; precision: number; scale?: number } }
|
|
204
|
+
> {
|
|
205
|
+
return new ColumnBuilder({ type: "number", dataType: { type: "decimal", precision, scale } });
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* VARCHAR column (가변 길이 문자열)
|
|
210
|
+
*
|
|
211
|
+
* @param length - 최대 길이
|
|
212
|
+
* @returns ColumnBuilder instance
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* name: c.varchar(100) // VARCHAR(100)
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
varchar(
|
|
220
|
+
length: number,
|
|
221
|
+
): ColumnBuilder<string, { type: "string"; dataType: { type: "varchar"; length: number } }> {
|
|
222
|
+
return new ColumnBuilder({ type: "string", dataType: { type: "varchar", length } });
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* CHAR column (고정 길이 문자열)
|
|
227
|
+
*
|
|
228
|
+
* @param length - 고정 길이
|
|
229
|
+
* @returns ColumnBuilder instance
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* countryCode: c.char(2) // CHAR(2)
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
char(
|
|
237
|
+
length: number,
|
|
238
|
+
): ColumnBuilder<string, { type: "string"; dataType: { type: "char"; length: number } }> {
|
|
239
|
+
return new ColumnBuilder({ type: "string", dataType: { type: "char" as const, length } });
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* TEXT column (대용량 문자열)
|
|
244
|
+
*
|
|
245
|
+
* @returns ColumnBuilder instance
|
|
246
|
+
*/
|
|
247
|
+
text(): ColumnBuilder<string, { type: "string"; dataType: { type: "text" } }> {
|
|
248
|
+
return new ColumnBuilder({ type: "string", dataType: { type: "text" } });
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* BINARY column (바이너리 data)
|
|
253
|
+
*
|
|
254
|
+
* DBMS별: MySQL=LONGBLOB, MSSQL=VARBINARY(MAX), PostgreSQL=BYTEA
|
|
255
|
+
*
|
|
256
|
+
* @returns ColumnBuilder instance
|
|
257
|
+
*/
|
|
258
|
+
binary(): ColumnBuilder<Bytes, { type: "Bytes"; dataType: { type: "binary" } }> {
|
|
259
|
+
return new ColumnBuilder({ type: "Bytes", dataType: { type: "binary" } });
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* BOOLEAN column
|
|
264
|
+
*
|
|
265
|
+
* DBMS별: MySQL=TINYINT(1), MSSQL=BIT, PostgreSQL=BOOLEAN
|
|
266
|
+
*
|
|
267
|
+
* @returns ColumnBuilder instance
|
|
268
|
+
*/
|
|
269
|
+
boolean(): ColumnBuilder<boolean, { type: "boolean"; dataType: { type: "boolean" } }> {
|
|
270
|
+
return new ColumnBuilder({ type: "boolean", dataType: { type: "boolean" } });
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* DATETIME column (Date + 시간)
|
|
275
|
+
*
|
|
276
|
+
* @returns ColumnBuilder instance
|
|
277
|
+
*/
|
|
278
|
+
datetime(): ColumnBuilder<DateTime, { type: "DateTime"; dataType: { type: "datetime" } }> {
|
|
279
|
+
return new ColumnBuilder({ type: "DateTime", dataType: { type: "datetime" } });
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* DATE column (Date만)
|
|
284
|
+
*
|
|
285
|
+
* @returns ColumnBuilder instance
|
|
286
|
+
*/
|
|
287
|
+
date(): ColumnBuilder<DateOnly, { type: "DateOnly"; dataType: { type: "date" } }> {
|
|
288
|
+
return new ColumnBuilder({ type: "DateOnly", dataType: { type: "date" } });
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* TIME column (시간만)
|
|
293
|
+
*
|
|
294
|
+
* @returns ColumnBuilder instance
|
|
295
|
+
*/
|
|
296
|
+
time(): ColumnBuilder<Time, { type: "Time"; dataType: { type: "time" } }> {
|
|
297
|
+
return new ColumnBuilder({ type: "Time", dataType: { type: "time" } });
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* UUID column
|
|
302
|
+
*
|
|
303
|
+
* DBMS별: MySQL=BINARY(16), MSSQL=UNIQUEIDENTIFIER, PostgreSQL=UUID
|
|
304
|
+
*
|
|
305
|
+
* @returns ColumnBuilder instance
|
|
306
|
+
*/
|
|
307
|
+
uuid(): ColumnBuilder<Uuid, { type: "Uuid"; dataType: { type: "uuid" } }> {
|
|
308
|
+
return new ColumnBuilder({ type: "Uuid", dataType: { type: "uuid" } });
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ============================================
|
|
314
|
+
// ColumnDefRecord - Column builder 레코드
|
|
315
|
+
// ============================================
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Column builder record type
|
|
319
|
+
*
|
|
320
|
+
* TableBuilder.columns()의 return 타입으로 사용
|
|
321
|
+
*/
|
|
322
|
+
export type ColumnBuilderRecord = Record<string, ColumnBuilder<ColumnPrimitive, ColumnMeta>>;
|
|
323
|
+
|
|
324
|
+
// ============================================
|
|
325
|
+
// Infer - Type inference 유틸리티
|
|
326
|
+
// ============================================
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Column builder 레코드에서 실제 value Type inference
|
|
330
|
+
*
|
|
331
|
+
* @template T - Column builder record type
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```typescript
|
|
335
|
+
* type UserColumns = InferColumns<typeof User.$columns>;
|
|
336
|
+
* // { id: number; name: string; email: string | undefined; }
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
export type InferColumns<TBuilders extends ColumnBuilderRecord> = {
|
|
340
|
+
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? V : never;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Column builder 레코드에서 expression 입력 Type inference
|
|
345
|
+
*
|
|
346
|
+
* @template T - Column builder record type
|
|
347
|
+
*/
|
|
348
|
+
export type InferColumnExprs<TBuilders extends ColumnBuilderRecord> = {
|
|
349
|
+
[K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? ExprInput<V> : never;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* INSERT 시 required column key 추출
|
|
354
|
+
*
|
|
355
|
+
* autoIncrement, nullable, default가 없는 column만 required
|
|
356
|
+
*
|
|
357
|
+
* @template T - Column builder record type
|
|
358
|
+
*/
|
|
359
|
+
export type RequiredInsertKeys<TBuilders extends ColumnBuilderRecord> = {
|
|
360
|
+
[K in keyof TBuilders]: TBuilders[K]["meta"] extends infer M extends ColumnMeta
|
|
361
|
+
? M["autoIncrement"] extends true
|
|
362
|
+
? never
|
|
363
|
+
: M["nullable"] extends true
|
|
364
|
+
? never
|
|
365
|
+
: M["default"] extends undefined
|
|
366
|
+
? K
|
|
367
|
+
: never
|
|
368
|
+
: never;
|
|
369
|
+
}[keyof TBuilders];
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* INSERT 시 optional column key 추출
|
|
373
|
+
*
|
|
374
|
+
* autoIncrement, nullable, default가 있는 column은 optional
|
|
375
|
+
*
|
|
376
|
+
* @template T - Column builder record type
|
|
377
|
+
*/
|
|
378
|
+
export type OptionalInsertKeys<TBuilders extends ColumnBuilderRecord> = Exclude<
|
|
379
|
+
keyof TBuilders,
|
|
380
|
+
RequiredInsertKeys<TBuilders>
|
|
381
|
+
>;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* INSERT용 Type inference
|
|
385
|
+
*
|
|
386
|
+
* required column은 required, optional column은 Partial
|
|
387
|
+
*
|
|
388
|
+
* @template T - Column builder record type
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```typescript
|
|
392
|
+
* type UserInsert = InferInsertColumns<typeof User.$columns>;
|
|
393
|
+
* // { name: string; } & { id?: number; email?: string; status?: string; }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
export type InferInsertColumns<TBuilders extends ColumnBuilderRecord> = Pick<
|
|
397
|
+
InferColumns<TBuilders>,
|
|
398
|
+
RequiredInsertKeys<TBuilders>
|
|
399
|
+
> &
|
|
400
|
+
Partial<Pick<InferColumns<TBuilders>, OptionalInsertKeys<TBuilders>>>;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* UPDATE용 Type inference
|
|
404
|
+
*
|
|
405
|
+
* 모든 column이 optional
|
|
406
|
+
*
|
|
407
|
+
* @template T - Column builder record type
|
|
408
|
+
*/
|
|
409
|
+
export type InferUpdateColumns<TBuilders extends ColumnBuilderRecord> = Partial<
|
|
410
|
+
InferColumns<TBuilders>
|
|
411
|
+
>;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* data 레코드에서 Column builder 레코드로 Transform
|
|
415
|
+
*
|
|
416
|
+
* @template TData - data record type
|
|
417
|
+
*/
|
|
418
|
+
export type DataToColumnBuilderRecord<TData extends DataRecord> = {
|
|
419
|
+
[K in keyof TData as TData[K] extends ColumnPrimitive ? K : never]: ColumnBuilder<
|
|
420
|
+
TData[K] extends ColumnPrimitive ? TData[K] : never,
|
|
421
|
+
any
|
|
422
|
+
>;
|
|
423
|
+
};
|