@simplysm/orm-node 13.0.0-beta.11
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 +418 -0
- package/dist/connections/mssql-db-conn.js +386 -0
- package/dist/connections/mssql-db-conn.js.map +7 -0
- package/dist/connections/mysql-db-conn.js +227 -0
- package/dist/connections/mysql-db-conn.js.map +7 -0
- package/dist/connections/postgresql-db-conn.js +191 -0
- package/dist/connections/postgresql-db-conn.js.map +7 -0
- package/dist/core-common/src/common.types.d.ts +74 -0
- package/dist/core-common/src/common.types.d.ts.map +1 -0
- package/dist/core-common/src/env.d.ts +6 -0
- package/dist/core-common/src/env.d.ts.map +1 -0
- package/dist/core-common/src/errors/argument-error.d.ts +25 -0
- package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
- package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/sd-error.d.ts +27 -0
- package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
- package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
- package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
- package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
- package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
- package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
- package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
- package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
- package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
- package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
- package/dist/core-common/src/features/event-emitter.d.ts +66 -0
- package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
- package/dist/core-common/src/features/serial-queue.d.ts +47 -0
- package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
- package/dist/core-common/src/index.d.ts +32 -0
- package/dist/core-common/src/index.d.ts.map +1 -0
- package/dist/core-common/src/types/date-only.d.ts +152 -0
- package/dist/core-common/src/types/date-only.d.ts.map +1 -0
- package/dist/core-common/src/types/date-time.d.ts +96 -0
- package/dist/core-common/src/types/date-time.d.ts.map +1 -0
- package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
- package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
- package/dist/core-common/src/types/time.d.ts +68 -0
- package/dist/core-common/src/types/time.d.ts.map +1 -0
- package/dist/core-common/src/types/uuid.d.ts +35 -0
- package/dist/core-common/src/types/uuid.d.ts.map +1 -0
- package/dist/core-common/src/utils/bytes.d.ts +51 -0
- package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
- package/dist/core-common/src/utils/date-format.d.ts +90 -0
- package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
- package/dist/core-common/src/utils/json.d.ts +34 -0
- package/dist/core-common/src/utils/json.d.ts.map +1 -0
- package/dist/core-common/src/utils/num.d.ts +60 -0
- package/dist/core-common/src/utils/num.d.ts.map +1 -0
- package/dist/core-common/src/utils/obj.d.ts +258 -0
- package/dist/core-common/src/utils/obj.d.ts.map +1 -0
- package/dist/core-common/src/utils/path.d.ts +23 -0
- package/dist/core-common/src/utils/path.d.ts.map +1 -0
- package/dist/core-common/src/utils/primitive.d.ts +18 -0
- package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
- package/dist/core-common/src/utils/str.d.ts +103 -0
- package/dist/core-common/src/utils/str.d.ts.map +1 -0
- package/dist/core-common/src/utils/template-strings.d.ts +84 -0
- package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
- package/dist/core-common/src/utils/transferable.d.ts +47 -0
- package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
- package/dist/core-common/src/utils/wait.d.ts +19 -0
- package/dist/core-common/src/utils/wait.d.ts.map +1 -0
- package/dist/core-common/src/utils/xml.d.ts +36 -0
- package/dist/core-common/src/utils/xml.d.ts.map +1 -0
- package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
- package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
- package/dist/db-conn-factory.js +88 -0
- package/dist/db-conn-factory.js.map +7 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +7 -0
- package/dist/node-db-context-executor.js +129 -0
- package/dist/node-db-context-executor.js.map +7 -0
- package/dist/orm-common/src/db-context.d.ts +669 -0
- package/dist/orm-common/src/db-context.d.ts.map +1 -0
- package/dist/orm-common/src/errors/db-transaction-error.d.ts +51 -0
- package/dist/orm-common/src/errors/db-transaction-error.d.ts.map +1 -0
- package/dist/orm-common/src/exec/executable.d.ts +79 -0
- package/dist/orm-common/src/exec/executable.d.ts.map +1 -0
- package/dist/orm-common/src/exec/queryable.d.ts +708 -0
- package/dist/orm-common/src/exec/queryable.d.ts.map +1 -0
- package/dist/orm-common/src/exec/search-parser.d.ts +72 -0
- package/dist/orm-common/src/exec/search-parser.d.ts.map +1 -0
- package/dist/orm-common/src/expr/expr-unit.d.ts +25 -0
- package/dist/orm-common/src/expr/expr-unit.d.ts.map +1 -0
- package/dist/orm-common/src/expr/expr.d.ts +1369 -0
- package/dist/orm-common/src/expr/expr.d.ts.map +1 -0
- package/dist/orm-common/src/index.d.ts +32 -0
- package/dist/orm-common/src/index.d.ts.map +1 -0
- package/dist/orm-common/src/models/system-migration.d.ts +10 -0
- package/dist/orm-common/src/models/system-migration.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts +95 -0
- package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts +66 -0
- package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts +45 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts +54 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts +52 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/query-builder.d.ts +7 -0
- package/dist/orm-common/src/query-builder/query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/column-builder.d.ts +394 -0
- package/dist/orm-common/src/schema/factory/column-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/index-builder.d.ts +151 -0
- package/dist/orm-common/src/schema/factory/index-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/relation-builder.d.ts +337 -0
- package/dist/orm-common/src/schema/factory/relation-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/procedure-builder.d.ts +202 -0
- package/dist/orm-common/src/schema/procedure-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/table-builder.d.ts +259 -0
- package/dist/orm-common/src/schema/table-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/view-builder.d.ts +183 -0
- package/dist/orm-common/src/schema/view-builder.d.ts.map +1 -0
- package/dist/orm-common/src/types/column.d.ts +172 -0
- package/dist/orm-common/src/types/column.d.ts.map +1 -0
- package/dist/orm-common/src/types/db.d.ts +175 -0
- package/dist/orm-common/src/types/db.d.ts.map +1 -0
- package/dist/orm-common/src/types/expr.d.ts +474 -0
- package/dist/orm-common/src/types/expr.d.ts.map +1 -0
- package/dist/orm-common/src/types/query-def.d.ts +351 -0
- package/dist/orm-common/src/types/query-def.d.ts.map +1 -0
- package/dist/orm-common/src/utils/result-parser.d.ts +38 -0
- package/dist/orm-common/src/utils/result-parser.d.ts.map +1 -0
- package/dist/orm-node/src/connections/mssql-db-conn.d.ts +44 -0
- package/dist/orm-node/src/connections/mssql-db-conn.d.ts.map +1 -0
- package/dist/orm-node/src/connections/mysql-db-conn.d.ts +38 -0
- package/dist/orm-node/src/connections/mysql-db-conn.d.ts.map +1 -0
- package/dist/orm-node/src/connections/postgresql-db-conn.d.ts +39 -0
- package/dist/orm-node/src/connections/postgresql-db-conn.d.ts.map +1 -0
- package/dist/orm-node/src/db-conn-factory.d.ts +25 -0
- package/dist/orm-node/src/db-conn-factory.d.ts.map +1 -0
- package/dist/orm-node/src/index.d.ts +9 -0
- package/dist/orm-node/src/index.d.ts.map +1 -0
- package/dist/orm-node/src/node-db-context-executor.d.ts +77 -0
- package/dist/orm-node/src/node-db-context-executor.d.ts.map +1 -0
- package/dist/orm-node/src/pooled-db-conn.d.ts +79 -0
- package/dist/orm-node/src/pooled-db-conn.d.ts.map +1 -0
- package/dist/orm-node/src/sd-orm.d.ts +78 -0
- package/dist/orm-node/src/sd-orm.d.ts.map +1 -0
- package/dist/orm-node/src/types/db-conn.d.ts +159 -0
- package/dist/orm-node/src/types/db-conn.d.ts.map +1 -0
- package/dist/pooled-db-conn.js +134 -0
- package/dist/pooled-db-conn.js.map +7 -0
- package/dist/sd-orm.js +44 -0
- package/dist/sd-orm.js.map +7 -0
- package/dist/types/db-conn.js +17 -0
- package/dist/types/db-conn.js.map +7 -0
- package/package.json +53 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
import { TableBuilder } from "../schema/table-builder";
|
|
2
|
+
import { ViewBuilder } from "../schema/view-builder";
|
|
3
|
+
import type { DataRecord, ResultMeta } from "../types/db";
|
|
4
|
+
import type { DeleteQueryDef, InsertIfNotExistsQueryDef, InsertIntoQueryDef, InsertQueryDef, SelectQueryDef, UpdateQueryDef, UpsertQueryDef } from "../types/query-def";
|
|
5
|
+
import type { DbContext } from "../db-context";
|
|
6
|
+
import { type DataToColumnBuilderRecord } from "../schema/factory/column-builder";
|
|
7
|
+
import type { ColumnPrimitive } from "../types/column";
|
|
8
|
+
import type { WhereExprUnit } from "../expr/expr-unit";
|
|
9
|
+
import { ExprUnit } from "../expr/expr-unit";
|
|
10
|
+
/**
|
|
11
|
+
* JOIN 쿼리 빌더
|
|
12
|
+
*
|
|
13
|
+
* join/joinSingle 메서드 내부에서 사용되며, 조인 대상 테이블을 지정하는 역할을 수행
|
|
14
|
+
*/
|
|
15
|
+
declare class JoinQueryable {
|
|
16
|
+
private readonly _db;
|
|
17
|
+
private readonly _joinAlias;
|
|
18
|
+
constructor(_db: DbContext, _joinAlias: string);
|
|
19
|
+
/**
|
|
20
|
+
* 조인할 테이블을 지정
|
|
21
|
+
*
|
|
22
|
+
* @param table - 조인 대상 테이블
|
|
23
|
+
* @returns 조인된 Queryable
|
|
24
|
+
*/
|
|
25
|
+
from<T extends TableBuilder<any, any>>(table: T): Queryable<T["$infer"], T>;
|
|
26
|
+
/**
|
|
27
|
+
* 조인 결과의 컬럼을 직접 지정
|
|
28
|
+
*
|
|
29
|
+
* @param columns - 커스텀 컬럼 정의
|
|
30
|
+
* @returns 커스텀 컬럼이 적용된 Queryable
|
|
31
|
+
*/
|
|
32
|
+
select<R extends DataRecord>(columns: QueryableRecord<R>): Queryable<R, never>;
|
|
33
|
+
/**
|
|
34
|
+
* 여러 Queryable을 UNION으로 결합
|
|
35
|
+
*
|
|
36
|
+
* @param queries - UNION할 Queryable 배열 (최소 2개)
|
|
37
|
+
* @returns UNION된 Queryable
|
|
38
|
+
* @throws 2개 미만의 queryable이 전달된 경우
|
|
39
|
+
*/
|
|
40
|
+
union<TData extends DataRecord>(...queries: Queryable<TData, any>[]): Queryable<TData, never>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 재귀 CTE(Common Table Expression) 빌더
|
|
44
|
+
*
|
|
45
|
+
* recursive() 메서드 내부에서 사용되며, 재귀 쿼리의 본문을 정의하는 역할을 수행
|
|
46
|
+
*
|
|
47
|
+
* @template TBaseData - 기본 쿼리의 데이터 타입
|
|
48
|
+
*/
|
|
49
|
+
declare class RecursiveQueryable<TBaseData extends DataRecord> {
|
|
50
|
+
private readonly _baseQr;
|
|
51
|
+
private readonly _cteName;
|
|
52
|
+
constructor(_baseQr: Queryable<TBaseData, any>, _cteName: string);
|
|
53
|
+
/**
|
|
54
|
+
* 재귀 쿼리의 대상 테이블을 지정
|
|
55
|
+
*
|
|
56
|
+
* @param table - 재귀할 대상 테이블
|
|
57
|
+
* @returns self 속성이 추가된 Queryable (자기 참조용)
|
|
58
|
+
*/
|
|
59
|
+
from<T extends TableBuilder<any, any>>(table: T): Queryable<T["$infer"] & {
|
|
60
|
+
self?: TBaseData[];
|
|
61
|
+
}, T>;
|
|
62
|
+
/**
|
|
63
|
+
* 재귀 쿼리의 컬럼을 직접 지정
|
|
64
|
+
*
|
|
65
|
+
* @param columns - 커스텀 컬럼 정의
|
|
66
|
+
* @returns self 속성이 추가된 Queryable
|
|
67
|
+
*/
|
|
68
|
+
select<R extends DataRecord>(columns: QueryableRecord<R>): Queryable<R & {
|
|
69
|
+
self?: TBaseData[];
|
|
70
|
+
}, never>;
|
|
71
|
+
/**
|
|
72
|
+
* 여러 Queryable을 UNION으로 결합 (재귀 쿼리용)
|
|
73
|
+
*
|
|
74
|
+
* @param queries - UNION할 Queryable 배열 (최소 2개)
|
|
75
|
+
* @returns self 속성이 추가된 UNION Queryable
|
|
76
|
+
* @throws 2개 미만의 queryable이 전달된 경우
|
|
77
|
+
*/
|
|
78
|
+
union<TData extends DataRecord>(...queries: Queryable<TData, any>[]): Queryable<TData & {
|
|
79
|
+
self?: TBaseData[];
|
|
80
|
+
}, never>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 쿼리 빌더 클래스
|
|
84
|
+
*
|
|
85
|
+
* 테이블/뷰에 대한 SELECT, INSERT, UPDATE, DELETE 등의 쿼리를 체이닝 방식으로 구성
|
|
86
|
+
*
|
|
87
|
+
* @template TData - 쿼리 결과의 데이터 타입
|
|
88
|
+
* @template TFrom - 원본 테이블 (CUD 작업에 필요)
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // 기본 조회
|
|
93
|
+
* const users = await db.user()
|
|
94
|
+
* .where((u) => [expr.eq(u.isActive, true)])
|
|
95
|
+
* .orderBy((u) => u.name)
|
|
96
|
+
* .result();
|
|
97
|
+
*
|
|
98
|
+
* // JOIN 조회
|
|
99
|
+
* const posts = await db.post()
|
|
100
|
+
* .include((p) => p.user)
|
|
101
|
+
* .result();
|
|
102
|
+
*
|
|
103
|
+
* // INSERT
|
|
104
|
+
* await db.user().insert([{ name: "홍길동", email: "test@test.com" }]);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare class Queryable<TData extends DataRecord, TFrom extends TableBuilder<any, any> | never> {
|
|
108
|
+
readonly meta: QueryableMeta<TData>;
|
|
109
|
+
constructor(meta: QueryableMeta<TData>);
|
|
110
|
+
/**
|
|
111
|
+
* SELECT할 컬럼을 지정합니다.
|
|
112
|
+
*
|
|
113
|
+
* @param fn - 컬럼 매핑 함수. 원본 컬럼을 받아 새 컬럼 구조를 반환
|
|
114
|
+
* @returns 새로운 컬럼 구조가 적용된 Queryable
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* db.user().select((u) => ({
|
|
119
|
+
* userName: u.name,
|
|
120
|
+
* userEmail: u.email,
|
|
121
|
+
* }))
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
select<R extends DataRecord>(fn: (columns: QueryableRecord<TData>) => QueryableRecord<R>): Queryable<R, never>;
|
|
125
|
+
/**
|
|
126
|
+
* DISTINCT 옵션을 적용하여 중복 행을 제거
|
|
127
|
+
*
|
|
128
|
+
* @returns DISTINCT가 적용된 Queryable
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* db.user()
|
|
133
|
+
* .select((u) => ({ name: u.name }))
|
|
134
|
+
* .distinct()
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
distinct(): Queryable<TData, never>;
|
|
138
|
+
/**
|
|
139
|
+
* 행 잠금(FOR UPDATE)을 적용
|
|
140
|
+
*
|
|
141
|
+
* 트랜잭션 내에서 선택된 행에 대한 배타적 잠금을 획득
|
|
142
|
+
*
|
|
143
|
+
* @returns 잠금이 적용된 Queryable
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* await db.connect(async () => {
|
|
148
|
+
* const user = await db.user()
|
|
149
|
+
* .where((u) => [expr.eq(u.id, 1)])
|
|
150
|
+
* .lock()
|
|
151
|
+
* .single();
|
|
152
|
+
* });
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
lock(): Queryable<TData, TFrom>;
|
|
156
|
+
/**
|
|
157
|
+
* 상위 N개의 행만 조회 (ORDER BY 없이 사용 가능)
|
|
158
|
+
*
|
|
159
|
+
* @param count - 조회할 행 수
|
|
160
|
+
* @returns TOP이 적용된 Queryable
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* // 최신 사용자 10명
|
|
165
|
+
* db.user()
|
|
166
|
+
* .orderBy((u) => u.createdAt, "DESC")
|
|
167
|
+
* .top(10)
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
top(count: number): Queryable<TData, TFrom>;
|
|
171
|
+
/**
|
|
172
|
+
* 페이지네이션을 위한 LIMIT/OFFSET을 설정합니다.
|
|
173
|
+
* 반드시 orderBy()를 먼저 호출해야 합니다.
|
|
174
|
+
*
|
|
175
|
+
* @param skip - 건너뛸 행 수 (OFFSET)
|
|
176
|
+
* @param take - 가져올 행 수 (LIMIT)
|
|
177
|
+
* @returns 페이지네이션이 적용된 Queryable
|
|
178
|
+
* @throws ORDER BY 절이 없으면 에러
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* db.user
|
|
183
|
+
* .orderBy((u) => u.createdAt)
|
|
184
|
+
* .limit(0, 20) // 첫 20개
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
limit(skip: number, take: number): Queryable<TData, TFrom>;
|
|
188
|
+
/**
|
|
189
|
+
* 정렬 조건을 추가합니다. 여러 번 호출하면 순서대로 적용됩니다.
|
|
190
|
+
*
|
|
191
|
+
* @param fn - 정렬 기준 컬럼을 반환하는 함수
|
|
192
|
+
* @param orderBy - 정렬 방향 (ASC/DESC). 기본값: ASC
|
|
193
|
+
* @returns 정렬 조건이 추가된 Queryable
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* db.user
|
|
198
|
+
* .orderBy((u) => u.name) // 이름 ASC
|
|
199
|
+
* .orderBy((u) => u.age, "DESC") // 나이 DESC
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
orderBy(fn: (columns: QueryableRecord<TData>) => ExprUnit<ColumnPrimitive>, orderBy?: "ASC" | "DESC"): Queryable<TData, TFrom>;
|
|
203
|
+
/**
|
|
204
|
+
* WHERE 조건을 추가합니다. 여러 번 호출하면 AND로 결합됩니다.
|
|
205
|
+
*
|
|
206
|
+
* @param predicate - 조건 배열을 반환하는 함수
|
|
207
|
+
* @returns 조건이 추가된 Queryable
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* db.user
|
|
212
|
+
* .where((u) => [expr.eq(u.isActive, true)])
|
|
213
|
+
* .where((u) => [expr.gte(u.age, 18)])
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
where(predicate: (columns: QueryableRecord<TData>) => WhereExprUnit[]): Queryable<TData, TFrom>;
|
|
217
|
+
/**
|
|
218
|
+
* 텍스트 검색을 수행
|
|
219
|
+
*
|
|
220
|
+
* 검색 문법은 {@link parseSearchQuery}를 참조
|
|
221
|
+
* - 공백으로 구분된 단어는 OR 조건
|
|
222
|
+
* - `+`로 시작하는 단어는 필수 포함 (AND 조건)
|
|
223
|
+
* - `-`로 시작하는 단어는 제외 (NOT 조건)
|
|
224
|
+
*
|
|
225
|
+
* @param fn - 검색 대상 컬럼을 반환하는 함수
|
|
226
|
+
* @param searchText - 검색 텍스트
|
|
227
|
+
* @returns 검색 조건이 추가된 Queryable
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* db.user()
|
|
232
|
+
* .search((u) => [u.name, u.email], "홍길동 -탈퇴")
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
search(fn: (columns: QueryableRecord<TData>) => ExprUnit<string | undefined>[], searchText: string): Queryable<TData, TFrom>;
|
|
236
|
+
/**
|
|
237
|
+
* GROUP BY 절을 추가
|
|
238
|
+
*
|
|
239
|
+
* @param fn - 그룹화 기준 컬럼을 반환하는 함수
|
|
240
|
+
* @returns GROUP BY가 적용된 Queryable
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* db.order()
|
|
245
|
+
* .select((o) => ({
|
|
246
|
+
* userId: o.userId,
|
|
247
|
+
* totalAmount: expr.sum(o.amount),
|
|
248
|
+
* }))
|
|
249
|
+
* .groupBy((o) => [o.userId])
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
groupBy(fn: (columns: QueryableRecord<TData>) => ExprUnit<ColumnPrimitive>[]): Queryable<TData, never>;
|
|
253
|
+
/**
|
|
254
|
+
* HAVING 절을 추가 (GROUP BY 후 필터링)
|
|
255
|
+
*
|
|
256
|
+
* @param predicate - 조건 배열을 반환하는 함수
|
|
257
|
+
* @returns HAVING이 적용된 Queryable
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* db.order()
|
|
262
|
+
* .select((o) => ({
|
|
263
|
+
* userId: o.userId,
|
|
264
|
+
* totalAmount: expr.sum(o.amount),
|
|
265
|
+
* }))
|
|
266
|
+
* .groupBy((o) => [o.userId])
|
|
267
|
+
* .having((o) => [expr.gte(o.totalAmount, 10000)])
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
having(predicate: (columns: QueryableRecord<TData>) => WhereExprUnit[]): Queryable<TData, never>;
|
|
271
|
+
/**
|
|
272
|
+
* 1:N 관계의 LEFT OUTER JOIN을 수행 (배열로 결과 추가)
|
|
273
|
+
*
|
|
274
|
+
* @param as - 결과에 추가할 속성 이름
|
|
275
|
+
* @param fwd - 조인 조건을 정의하는 콜백 함수
|
|
276
|
+
* @returns 조인 결과가 배열로 추가된 Queryable
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* db.user()
|
|
281
|
+
* .join("posts", (qr, u) =>
|
|
282
|
+
* qr.from(Post)
|
|
283
|
+
* .where((p) => [expr.eq(p.userId, u.id)])
|
|
284
|
+
* )
|
|
285
|
+
* // 결과: { id, name, posts: [{ id, title }, ...] }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
join<A extends string, R extends DataRecord>(as: A, fwd: (qr: JoinQueryable, cols: QueryableRecord<TData>) => Queryable<R, any>): Queryable<TData & {
|
|
289
|
+
[K in A]?: R[];
|
|
290
|
+
}, TFrom>;
|
|
291
|
+
/**
|
|
292
|
+
* N:1 또는 1:1 관계의 LEFT OUTER JOIN을 수행 (단일 객체로 결과 추가)
|
|
293
|
+
*
|
|
294
|
+
* @param as - 결과에 추가할 속성 이름
|
|
295
|
+
* @param fwd - 조인 조건을 정의하는 콜백 함수
|
|
296
|
+
* @returns 조인 결과가 단일 객체로 추가된 Queryable
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* db.post()
|
|
301
|
+
* .joinSingle("user", (qr, p) =>
|
|
302
|
+
* qr.from(User)
|
|
303
|
+
* .where((u) => [expr.eq(u.id, p.userId)])
|
|
304
|
+
* )
|
|
305
|
+
* // 결과: { id, title, user: { id, name } | undefined }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
joinSingle<A extends string, R extends DataRecord>(as: A, fwd: (qr: JoinQueryable, cols: QueryableRecord<TData>) => Queryable<R, any>): Queryable<{
|
|
309
|
+
[K in keyof TData as K extends A ? never : K]: TData[K];
|
|
310
|
+
} & {
|
|
311
|
+
[K in A]?: R;
|
|
312
|
+
}, TFrom>;
|
|
313
|
+
/**
|
|
314
|
+
* 관계된 테이블을 자동으로 JOIN합니다.
|
|
315
|
+
* TableBuilder에 정의된 FK/FKT 관계를 기반으로 동작합니다.
|
|
316
|
+
*
|
|
317
|
+
* @param fn - 포함할 관계를 선택하는 함수 (PathProxy를 통해 타입 체크됨)
|
|
318
|
+
* @returns JOIN이 추가된 Queryable
|
|
319
|
+
* @throws 관계가 정의되지 않은 경우 에러
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* // 단일 관계 포함
|
|
324
|
+
* db.post.include((p) => p.user)
|
|
325
|
+
*
|
|
326
|
+
* // 중첩 관계 포함
|
|
327
|
+
* db.post.include((p) => p.user.company)
|
|
328
|
+
*
|
|
329
|
+
* // 다중 관계 포함
|
|
330
|
+
* db.user
|
|
331
|
+
* .include((u) => u.company)
|
|
332
|
+
* .include((u) => u.posts)
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
include(fn: (item: PathProxy<TData>) => PathProxy<any>): Queryable<TData, TFrom>;
|
|
336
|
+
private _include;
|
|
337
|
+
/**
|
|
338
|
+
* 현재 Queryable을 서브쿼리로 감싸기
|
|
339
|
+
*
|
|
340
|
+
* distinct() 또는 groupBy() 후 count() 사용 시 필요
|
|
341
|
+
*
|
|
342
|
+
* @returns 서브쿼리로 감싸진 Queryable
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```typescript
|
|
346
|
+
* // DISTINCT 후 카운트
|
|
347
|
+
* const count = await db.user()
|
|
348
|
+
* .select((u) => ({ name: u.name }))
|
|
349
|
+
* .distinct()
|
|
350
|
+
* .wrap()
|
|
351
|
+
* .count();
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
wrap(): Queryable<TData, never>;
|
|
355
|
+
/**
|
|
356
|
+
* 여러 Queryable을 UNION으로 결합 (중복 제거)
|
|
357
|
+
*
|
|
358
|
+
* @param queries - UNION할 Queryable 배열 (최소 2개)
|
|
359
|
+
* @returns UNION된 Queryable
|
|
360
|
+
* @throws 2개 미만의 queryable이 전달된 경우
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```typescript
|
|
364
|
+
* const combined = Queryable.union(
|
|
365
|
+
* db.user().where((u) => [expr.eq(u.type, "admin")]),
|
|
366
|
+
* db.user().where((u) => [expr.eq(u.type, "manager")]),
|
|
367
|
+
* );
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
static union<TData extends DataRecord>(...queries: Queryable<TData, any>[]): Queryable<TData, never>;
|
|
371
|
+
/**
|
|
372
|
+
* 재귀 CTE(Common Table Expression)를 생성
|
|
373
|
+
*
|
|
374
|
+
* 계층 구조 데이터(조직도, 카테고리 트리 등)를 조회할 때 사용
|
|
375
|
+
*
|
|
376
|
+
* @param fwd - 재귀 부분을 정의하는 콜백 함수
|
|
377
|
+
* @returns 재귀 CTE가 적용된 Queryable
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* // 조직도 계층 조회
|
|
382
|
+
* db.employee()
|
|
383
|
+
* .where((e) => [expr.null(e.managerId)]) // 루트 노드
|
|
384
|
+
* .recursive((cte) =>
|
|
385
|
+
* cte.from(Employee)
|
|
386
|
+
* .where((e) => [expr.eq(e.managerId, e.self[0].id)])
|
|
387
|
+
* )
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
recursive(fwd: (qr: RecursiveQueryable<TData>) => Queryable<TData, any>): Queryable<TData, never>;
|
|
391
|
+
/**
|
|
392
|
+
* SELECT 쿼리를 실행하고 결과 배열을 반환
|
|
393
|
+
*
|
|
394
|
+
* @returns 쿼리 결과 배열
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```typescript
|
|
398
|
+
* const users = await db.user()
|
|
399
|
+
* .where((u) => [expr.eq(u.isActive, true)])
|
|
400
|
+
* .result();
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
result(): Promise<TData[]>;
|
|
404
|
+
/**
|
|
405
|
+
* 단일 결과를 반환 (2개 이상이면 에러)
|
|
406
|
+
*
|
|
407
|
+
* @returns 단일 결과 또는 undefined
|
|
408
|
+
* @throws 2개 이상의 결과가 반환된 경우
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```typescript
|
|
412
|
+
* const user = await db.user()
|
|
413
|
+
* .where((u) => [expr.eq(u.id, 1)])
|
|
414
|
+
* .single();
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
single(): Promise<TData | undefined>;
|
|
418
|
+
/**
|
|
419
|
+
* 쿼리 소스 이름 반환 (에러 메시지용)
|
|
420
|
+
*/
|
|
421
|
+
private _getSourceName;
|
|
422
|
+
/**
|
|
423
|
+
* 첫 번째 결과를 반환 (여러 개여도 첫 번째만)
|
|
424
|
+
*
|
|
425
|
+
* @returns 첫 번째 결과 또는 undefined
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* ```typescript
|
|
429
|
+
* const latestUser = await db.user()
|
|
430
|
+
* .orderBy((u) => u.createdAt, "DESC")
|
|
431
|
+
* .first();
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
first(): Promise<TData | undefined>;
|
|
435
|
+
/**
|
|
436
|
+
* 결과 행 수를 반환
|
|
437
|
+
*
|
|
438
|
+
* @param fwd - 카운트할 컬럼을 지정하는 함수 (선택)
|
|
439
|
+
* @returns 행 수
|
|
440
|
+
* @throws distinct() 또는 groupBy() 후 직접 호출 시 에러 (wrap() 필요)
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```typescript
|
|
444
|
+
* const count = await db.user()
|
|
445
|
+
* .where((u) => [expr.eq(u.isActive, true)])
|
|
446
|
+
* .count();
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
count(fwd?: (cols: QueryableRecord<TData>) => ExprUnit<ColumnPrimitive>): Promise<number>;
|
|
450
|
+
/**
|
|
451
|
+
* 조건에 맞는 데이터 존재 여부를 확인
|
|
452
|
+
*
|
|
453
|
+
* @returns 존재하면 true, 없으면 false
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```typescript
|
|
457
|
+
* const hasAdmin = await db.user()
|
|
458
|
+
* .where((u) => [expr.eq(u.role, "admin")])
|
|
459
|
+
* .exists();
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
exists(): Promise<boolean>;
|
|
463
|
+
getSelectQueryDef(): SelectQueryDef;
|
|
464
|
+
private _buildFromDef;
|
|
465
|
+
private _buildSelectDef;
|
|
466
|
+
private _buildJoinDefs;
|
|
467
|
+
getResultMeta(outputColumns?: string[]): ResultMeta;
|
|
468
|
+
/**
|
|
469
|
+
* INSERT 쿼리를 실행
|
|
470
|
+
*
|
|
471
|
+
* MSSQL의 1000개 제한을 위해 자동으로 1000개씩 청크로 분할하여 실행
|
|
472
|
+
*
|
|
473
|
+
* @param records - 삽입할 레코드 배열
|
|
474
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
475
|
+
* @returns outputColumns 지정 시 삽입된 레코드 배열 반환
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```typescript
|
|
479
|
+
* // 단순 삽입
|
|
480
|
+
* await db.user().insert([
|
|
481
|
+
* { name: "홍길동", email: "hong@test.com" },
|
|
482
|
+
* ]);
|
|
483
|
+
*
|
|
484
|
+
* // 삽입 후 ID 반환
|
|
485
|
+
* const [inserted] = await db.user().insert(
|
|
486
|
+
* [{ name: "홍길동" }],
|
|
487
|
+
* ["id"],
|
|
488
|
+
* );
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
insert(records: TFrom["$inferInsert"][]): Promise<void>;
|
|
492
|
+
insert<K extends keyof TFrom["$inferColumns"] & string>(records: TFrom["$inferInsert"][], outputColumns: K[]): Promise<Pick<TFrom["$inferColumns"], K>[]>;
|
|
493
|
+
/**
|
|
494
|
+
* WHERE 조건에 맞는 데이터가 없으면 INSERT
|
|
495
|
+
*
|
|
496
|
+
* @param record - 삽입할 레코드
|
|
497
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
498
|
+
* @returns outputColumns 지정 시 삽입된 레코드 반환
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* ```typescript
|
|
502
|
+
* await db.user()
|
|
503
|
+
* .where((u) => [expr.eq(u.email, "test@test.com")])
|
|
504
|
+
* .insertIfNotExists({ name: "테스트", email: "test@test.com" });
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
insertIfNotExists(record: TFrom["$inferInsert"]): Promise<void>;
|
|
508
|
+
insertIfNotExists<K extends keyof TFrom["$inferColumns"] & string>(record: TFrom["$inferInsert"], outputColumns: K[]): Promise<Pick<TFrom["$inferColumns"], K>>;
|
|
509
|
+
/**
|
|
510
|
+
* INSERT INTO ... SELECT (현재 SELECT 결과를 다른 테이블에 INSERT)
|
|
511
|
+
*
|
|
512
|
+
* @param targetTable - 삽입 대상 테이블
|
|
513
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
514
|
+
* @returns outputColumns 지정 시 삽입된 레코드 배열 반환
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```typescript
|
|
518
|
+
* await db.user()
|
|
519
|
+
* .select((u) => ({ name: u.name, createdAt: u.createdAt }))
|
|
520
|
+
* .where((u) => [expr.eq(u.isArchived, false)])
|
|
521
|
+
* .insertInto(ArchivedUser);
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
insertInto<TTable extends TableBuilder<DataToColumnBuilderRecord<TData>, any>>(targetTable: TTable): Promise<void>;
|
|
525
|
+
insertInto<TTable extends TableBuilder<DataToColumnBuilderRecord<TData>, any>, TOut extends keyof TTable["$inferColumns"] & string>(targetTable: TTable, outputColumns: TOut[]): Promise<Pick<TData, TOut>[]>;
|
|
526
|
+
getInsertQueryDef(records: TFrom["$inferInsert"][], outputColumns?: (keyof TFrom["$inferColumns"] & string)[]): InsertQueryDef;
|
|
527
|
+
getInsertIfNotExistsQueryDef(record: TFrom["$inferInsert"], outputColumns?: (keyof TFrom["$inferColumns"] & string)[]): InsertIfNotExistsQueryDef;
|
|
528
|
+
getInsertIntoQueryDef<TTable extends TableBuilder<DataToColumnBuilderRecord<TData>, any>>(targetTable: TTable, outputColumns?: (keyof TTable["$inferColumns"] & string)[]): InsertIntoQueryDef;
|
|
529
|
+
/**
|
|
530
|
+
* UPDATE 쿼리를 실행
|
|
531
|
+
*
|
|
532
|
+
* @param recordFwd - 업데이트할 컬럼과 값을 반환하는 함수
|
|
533
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
534
|
+
* @returns outputColumns 지정 시 업데이트된 레코드 배열 반환
|
|
535
|
+
*
|
|
536
|
+
* @example
|
|
537
|
+
* ```typescript
|
|
538
|
+
* // 단순 업데이트
|
|
539
|
+
* await db.user()
|
|
540
|
+
* .where((u) => [expr.eq(u.id, 1)])
|
|
541
|
+
* .update((u) => ({
|
|
542
|
+
* name: expr.val("string", "새이름"),
|
|
543
|
+
* updatedAt: expr.val("DateTime", DateTime.now()),
|
|
544
|
+
* }));
|
|
545
|
+
*
|
|
546
|
+
* // 기존 값 참조
|
|
547
|
+
* await db.product()
|
|
548
|
+
* .update((p) => ({
|
|
549
|
+
* price: expr.mul(p.price, expr.val("number", 1.1)),
|
|
550
|
+
* }));
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
update(recordFwd: (cols: QueryableRecord<TData>) => QueryableRecord<TFrom["$inferUpdate"]>): Promise<void>;
|
|
554
|
+
update<K extends keyof TFrom["$columns"] & string>(recordFwd: (cols: QueryableRecord<TData>) => QueryableRecord<TFrom["$inferUpdate"]>, outputColumns: K[]): Promise<Pick<TFrom["$columns"], K>[]>;
|
|
555
|
+
/**
|
|
556
|
+
* DELETE 쿼리를 실행
|
|
557
|
+
*
|
|
558
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
559
|
+
* @returns outputColumns 지정 시 삭제된 레코드 배열 반환
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```typescript
|
|
563
|
+
* // 단순 삭제
|
|
564
|
+
* await db.user()
|
|
565
|
+
* .where((u) => [expr.eq(u.id, 1)])
|
|
566
|
+
* .delete();
|
|
567
|
+
*
|
|
568
|
+
* // 삭제된 데이터 반환
|
|
569
|
+
* const deleted = await db.user()
|
|
570
|
+
* .where((u) => [expr.eq(u.isExpired, true)])
|
|
571
|
+
* .delete(["id", "name"]);
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
delete(): Promise<void>;
|
|
575
|
+
delete<K extends keyof TFrom["$columns"] & string>(outputColumns: K[]): Promise<Pick<TFrom["$columns"], K>[]>;
|
|
576
|
+
getUpdateQueryDef(recordFwd: (cols: QueryableRecord<TData>) => QueryableRecord<TFrom["$inferUpdate"]>, outputColumns?: (keyof TFrom["$inferColumns"] & string)[]): UpdateQueryDef;
|
|
577
|
+
getDeleteQueryDef(outputColumns?: (keyof TFrom["$inferColumns"] & string)[]): DeleteQueryDef;
|
|
578
|
+
/**
|
|
579
|
+
* UPSERT (UPDATE or INSERT) 쿼리를 실행
|
|
580
|
+
*
|
|
581
|
+
* WHERE 조건에 맞는 데이터가 있으면 UPDATE, 없으면 INSERT
|
|
582
|
+
*
|
|
583
|
+
* @param updateFwd - 업데이트할 컬럼과 값을 반환하는 함수
|
|
584
|
+
* @param insertFwd - 삽입할 레코드를 반환하는 함수 (선택, 미지정 시 updateFwd와 동일)
|
|
585
|
+
* @param outputColumns - 반환받을 컬럼 이름 배열 (선택)
|
|
586
|
+
* @returns outputColumns 지정 시 영향받은 레코드 배열 반환
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```typescript
|
|
590
|
+
* // UPDATE/INSERT 동일 데이터
|
|
591
|
+
* await db.user()
|
|
592
|
+
* .where((u) => [expr.eq(u.email, "test@test.com")])
|
|
593
|
+
* .upsert(() => ({
|
|
594
|
+
* name: expr.val("string", "테스트"),
|
|
595
|
+
* email: expr.val("string", "test@test.com"),
|
|
596
|
+
* }));
|
|
597
|
+
*
|
|
598
|
+
* // UPDATE/INSERT 다른 데이터
|
|
599
|
+
* await db.user()
|
|
600
|
+
* .where((u) => [expr.eq(u.email, "test@test.com")])
|
|
601
|
+
* .upsert(
|
|
602
|
+
* () => ({ loginCount: expr.val("number", 1) }),
|
|
603
|
+
* (update) => ({ ...update, email: expr.val("string", "test@test.com") }),
|
|
604
|
+
* );
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
upsert(updateFwd: (cols: QueryableRecord<TData>) => QueryableRecord<TFrom["$inferUpdate"]>): Promise<void>;
|
|
608
|
+
upsert<K extends keyof TFrom["$inferColumns"] & string>(insertFwd: (cols: QueryableRecord<TData>) => QueryableRecord<TFrom["$inferInsert"]>, outputColumns?: K[]): Promise<Pick<TFrom["$inferColumns"], K>[]>;
|
|
609
|
+
upsert<U extends QueryableRecord<TFrom["$inferUpdate"]>>(updateFwd: (cols: QueryableRecord<TData>) => U, insertFwd: (updateRecord: U) => QueryableRecord<TFrom["$inferInsert"]>): Promise<void>;
|
|
610
|
+
upsert<U extends QueryableRecord<TFrom["$inferUpdate"]>, K extends keyof TFrom["$inferColumns"] & string>(updateFwd: (cols: QueryableRecord<TData>) => U, insertFwd: (updateRecord: U) => QueryableRecord<TFrom["$inferInsert"]>, outputColumns?: K[]): Promise<Pick<TFrom["$inferColumns"], K>[]>;
|
|
611
|
+
getUpsertQueryDef<U extends QueryableRecord<TFrom["$inferUpdate"]>>(updateRecordFwd: (cols: QueryableRecord<TData>) => U, insertRecordFwd: (updateRecord: U) => QueryableRecord<TFrom["$inferInsert"]>, outputColumns?: (keyof TFrom["$inferColumns"] & string)[]): UpsertQueryDef;
|
|
612
|
+
/**
|
|
613
|
+
* FK 제약조건 on/off (트랜잭션 내 사용 가능)
|
|
614
|
+
*/
|
|
615
|
+
switchFk(switch_: "on" | "off"): Promise<void>;
|
|
616
|
+
private _getCudOutputDef;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* FK 컬럼 배열과 대상 테이블의 PK를 매칭하여 PK 컬럼명 배열을 반환
|
|
620
|
+
*
|
|
621
|
+
* @param fkCols - FK 컬럼명 배열
|
|
622
|
+
* @param targetTable - 참조 대상 테이블 빌더
|
|
623
|
+
* @returns 매칭된 PK 컬럼명 배열
|
|
624
|
+
* @throws FK/PK 컬럼 수 불일치 시
|
|
625
|
+
*/
|
|
626
|
+
export declare function getMatchedPrimaryKeys(fkCols: string[], targetTable: TableBuilder<any, any>): string[];
|
|
627
|
+
interface QueryableMeta<TData extends DataRecord> {
|
|
628
|
+
db: DbContext;
|
|
629
|
+
from?: TableBuilder<any, any> | ViewBuilder<any, any, any> | Queryable<any, any> | Queryable<TData, any>[] | string;
|
|
630
|
+
as: string;
|
|
631
|
+
columns: QueryableRecord<TData>;
|
|
632
|
+
isCustomColumns?: boolean;
|
|
633
|
+
distinct?: boolean;
|
|
634
|
+
top?: number;
|
|
635
|
+
lock?: boolean;
|
|
636
|
+
where?: WhereExprUnit[];
|
|
637
|
+
joins?: QueryableMetaJoin[];
|
|
638
|
+
orderBy?: [ExprUnit<ColumnPrimitive>, ("ASC" | "DESC")?][];
|
|
639
|
+
limit?: [number, number];
|
|
640
|
+
groupBy?: ExprUnit<ColumnPrimitive>[];
|
|
641
|
+
having?: WhereExprUnit[];
|
|
642
|
+
with?: {
|
|
643
|
+
name: string;
|
|
644
|
+
base: Queryable<any, any>;
|
|
645
|
+
recursive: Queryable<any, any>;
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
interface QueryableMetaJoin {
|
|
649
|
+
queryable: Queryable<any, any>;
|
|
650
|
+
isSingle: boolean;
|
|
651
|
+
}
|
|
652
|
+
export type QueryableRecord<TData extends DataRecord> = {
|
|
653
|
+
[K in keyof TData]: TData[K] extends ColumnPrimitive ? ExprUnit<TData[K]> : TData[K] extends (infer U)[] ? U extends DataRecord ? QueryableRecord<U>[] : never : TData[K] extends (infer U)[] | undefined ? U extends DataRecord ? QueryableRecord<U>[] | undefined : never : TData[K] extends DataRecord ? QueryableRecord<TData[K]> : TData[K] extends DataRecord | undefined ? QueryableRecord<Exclude<TData[K], undefined>> | undefined : never;
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* include()에서 관계 경로를 타입 안전하게 지정하기 위한 Proxy 타입
|
|
657
|
+
* ColumnPrimitive가 아닌 필드(FK, FKT 관계)만 접근 가능
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```typescript
|
|
661
|
+
* // item.user.company 접근 시 내부적으로 ["user", "company"] 경로 수집
|
|
662
|
+
* db.post.include(item => item.user.company)
|
|
663
|
+
*
|
|
664
|
+
* // item.title은 string(ColumnPrimitive)이므로 컴파일 에러
|
|
665
|
+
* db.post.include(item => item.title) // ❌ 에러
|
|
666
|
+
* ```
|
|
667
|
+
*/
|
|
668
|
+
/**
|
|
669
|
+
* 배열이면 요소 타입 추출
|
|
670
|
+
*/
|
|
671
|
+
type UnwrapArray<T> = T extends (infer U)[] ? U : T;
|
|
672
|
+
declare const PATH_SYMBOL: unique symbol;
|
|
673
|
+
/**
|
|
674
|
+
* include()용 타입 안전 경로 프록시
|
|
675
|
+
*/
|
|
676
|
+
export type PathProxy<T> = {
|
|
677
|
+
[K in keyof T as T[K] extends ColumnPrimitive ? never : K]-?: PathProxy<UnwrapArray<T[K]>>;
|
|
678
|
+
} & {
|
|
679
|
+
readonly [PATH_SYMBOL]: string[];
|
|
680
|
+
};
|
|
681
|
+
/**
|
|
682
|
+
* 테이블 또는 뷰에 대한 Queryable 팩토리 함수를 생성
|
|
683
|
+
*
|
|
684
|
+
* DbContext에서 테이블/뷰별 getter를 정의할 때 사용
|
|
685
|
+
*
|
|
686
|
+
* @param db - DbContext 인스턴스
|
|
687
|
+
* @param tableOrView - TableBuilder 또는 ViewBuilder 인스턴스
|
|
688
|
+
* @param as - alias 지정 (선택, 미지정 시 자동 생성)
|
|
689
|
+
* @returns Queryable을 반환하는 팩토리 함수
|
|
690
|
+
*
|
|
691
|
+
* @example
|
|
692
|
+
* ```typescript
|
|
693
|
+
* class AppDbContext extends DbContext {
|
|
694
|
+
* // 호출 시마다 새로운 alias 할당
|
|
695
|
+
* user = queryable(this, User);
|
|
696
|
+
*
|
|
697
|
+
* // 사용 예시
|
|
698
|
+
* async getActiveUsers() {
|
|
699
|
+
* return this.user()
|
|
700
|
+
* .where((u) => [expr.eq(u.isActive, true)])
|
|
701
|
+
* .result();
|
|
702
|
+
* }
|
|
703
|
+
* }
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
706
|
+
export declare function queryable<T extends TableBuilder<any, any> | ViewBuilder<any, any, any>>(db: DbContext, tableOrView: T, as?: string): () => Queryable<T["$infer"], T extends TableBuilder<any, any> ? T : never>;
|
|
707
|
+
export {};
|
|
708
|
+
//# sourceMappingURL=queryable.d.ts.map
|