@simplysm/orm-common 14.0.51 → 14.0.52

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.
@@ -1,94 +0,0 @@
1
- # Table
2
-
3
- Fluent API로 Database Table 스키마를 정의하는 빌더 팩토리 함수. 반환된 `TableBuilder`에 컬럼, PK, 인덱스, 관계를 메서드 체이닝으로 정의한다. 각 메서드는 새 인스턴스를 반환하므로 불변(immutable)이다.
4
-
5
- ```typescript
6
- export function Table(name: string): TableBuilder<never, never>;
7
- ```
8
-
9
- ## Parameters
10
-
11
- | Param | Type | Description |
12
- |-------|------|-------------|
13
- | `name` | `string` | 테이블 이름 |
14
-
15
- ## Returns
16
-
17
- `TableBuilder<never, never>` — 빈 TableBuilder 인스턴스
18
-
19
- ## Related Types
20
-
21
- ### `TableBuilder<TColumns, TRelations>`
22
-
23
- ```typescript
24
- export class TableBuilder<
25
- TColumns extends ColumnBuilderRecord,
26
- TRelations extends RelationBuilderRecord,
27
- > {
28
- readonly $inferSelect!: InferColumns<TColumns> & InferDeepRelations<TRelations>;
29
- readonly $inferColumns!: InferColumns<TColumns>;
30
- readonly $inferInsert!: InferInsertColumns<TColumns>;
31
- readonly $inferUpdate!: InferUpdateColumns<TColumns>;
32
- }
33
- ```
34
-
35
- #### 타입 추론 프로퍼티
36
-
37
- | 프로퍼티 | 설명 |
38
- |----------|------|
39
- | `$inferSelect` | SELECT 결과 타입 (컬럼 + 관계 포함) |
40
- | `$inferColumns` | 컬럼만의 타입 |
41
- | `$inferInsert` | INSERT 입력 타입 (autoIncrement 제외, nullable/default는 optional) |
42
- | `$inferUpdate` | UPDATE 입력 타입 (모든 필드 optional) |
43
-
44
- #### 빌더 메서드
45
-
46
- | 메서드 | 설명 |
47
- |--------|------|
48
- | `description(desc)` | 테이블 설명 설정 (DDL Comment) |
49
- | `database(db)` | Database 이름 설정 |
50
- | `schema(schema)` | Schema 이름 설정 (MSSQL: dbo, PostgreSQL: public) |
51
- | `columns(fn)` | 컬럼 정의. `fn(c) => ({ name: c.varchar(100), ... })` |
52
- | `primaryKey(...columns)` | PK 설정. 복합 PK는 여러 인자 전달 |
53
- | `indexes(fn)` | 인덱스 정의. `fn(i) => [i.index("email").unique(), ...]` |
54
- | `relations(fn)` | 관계 정의. `fn(r) => ({ company: r.foreignKey(...), ... })` |
55
-
56
- ## Usage
57
-
58
- ```typescript
59
- const User = Table("User")
60
- .database("mydb")
61
- .columns((c) => ({
62
- id: c.bigint().autoIncrement(),
63
- name: c.varchar(100),
64
- email: c.varchar(200).nullable(),
65
- isActive: c.boolean().default(true),
66
- companyId: c.bigint().nullable(),
67
- createdAt: c.datetime(),
68
- }))
69
- .primaryKey("id")
70
- .indexes((i) => [
71
- i.index("email").unique(),
72
- i.index("name", "createdAt").orderBy("ASC", "DESC"),
73
- ])
74
- .relations((r) => ({
75
- company: r.foreignKey(["companyId"], () => Company, { description: "소속회사" }),
76
- posts: r.foreignKeyTarget(() => Post, "user"),
77
- profile: r.foreignKeyTarget(() => Profile, "user", { single: true }),
78
- }));
79
-
80
- // 복합 PK
81
- const UserRole = Table("UserRole")
82
- .columns((c) => ({
83
- userId: c.bigint(),
84
- roleId: c.bigint(),
85
- }))
86
- .primaryKey("userId", "roleId");
87
- ```
88
-
89
- ## 권장사항
90
-
91
- ### `isDeleted` 컬럼
92
-
93
- - **기초정보(마스터 데이터) 테이블**: `isDeleted: c.boolean().default(false)` 컬럼을 포함한다. 삭제 시 `isDeleted: true`로 soft-delete하고, 복구 기능을 제공한다.
94
- - **일반 데이터(트랜잭션 데이터 등) 테이블**: `isDeleted` 컬럼을 두지 않는다. 삭제 시 물리 삭제(row DELETE)로 처리한다.
@@ -1,71 +0,0 @@
1
- # View
2
-
3
- Fluent API로 Database View 스키마를 정의하는 빌더 팩토리 함수. 반환된 `ViewBuilder`에 쿼리와 관계를 메서드 체이닝으로 정의한다.
4
-
5
- ```typescript
6
- export function View(name: string): ViewBuilder<never, never, never>;
7
- ```
8
-
9
- ## Parameters
10
-
11
- | Param | Type | Description |
12
- |-------|------|-------------|
13
- | `name` | `string` | View 이름 |
14
-
15
- ## Returns
16
-
17
- `ViewBuilder<never, never, never>` — 빈 ViewBuilder 인스턴스
18
-
19
- ## Related Types
20
-
21
- ### `ViewBuilder<TDbContext, TData, TRelations>`
22
-
23
- ```typescript
24
- export class ViewBuilder<
25
- TDbContext extends DbContextBase,
26
- TData extends DataRecord,
27
- TRelations extends RelationBuilderRecord,
28
- > {
29
- readonly $inferSelect!: TData;
30
- }
31
- ```
32
-
33
- #### 빌더 메서드
34
-
35
- | 메서드 | 설명 |
36
- |--------|------|
37
- | `description(desc)` | View 설명 설정 (DDL Comment) |
38
- | `database(db)` | Database 이름 설정 |
39
- | `schema(schema)` | Schema 이름 설정 |
40
- | `query(viewFn)` | View 쿼리 정의. `(db: TDb) => Queryable<TViewData, any>` |
41
- | `relations(fn)` | 관계 정의 (`relationKey`/`relationKeyTarget`만 사용 가능) |
42
-
43
- ## Usage
44
-
45
- ```typescript
46
- // 단순 필터 View
47
- const ActiveUsers = View("ActiveUsers")
48
- .database("mydb")
49
- .query((db: MainDb) =>
50
- db.user()
51
- .where((u) => [expr.eq(u.isActive, true)])
52
- .select((u) => ({ id: u.id, name: u.name }))
53
- );
54
-
55
- // 집계 View
56
- const UserStats = View("UserStats")
57
- .database("mydb")
58
- .query((db: MainDb) =>
59
- db.user()
60
- .groupBy((u) => [u.companyId])
61
- .select((u) => ({
62
- companyId: u.companyId,
63
- userCount: expr.count(u.id),
64
- }))
65
- );
66
-
67
- // DbContext에 등록
68
- class MainDb extends DbContext {
69
- activeUsers = this.queryable(ActiveUsers);
70
- }
71
- ```
@@ -1,146 +0,0 @@
1
- # DataType
2
-
3
- SQL 데이터 타입 및 TypeScript 타입 매핑 관련 타입/상수 모음.
4
-
5
- ## `DataType`
6
-
7
- SQL 데이터 타입 정의 discriminated union.
8
-
9
- ```typescript
10
- export type DataType =
11
- | { type: "int" }
12
- | { type: "bigint" }
13
- | { type: "float" }
14
- | { type: "double" }
15
- | { type: "decimal"; precision: number; scale?: number }
16
- | { type: "varchar"; length: number }
17
- | { type: "char"; length: number }
18
- | { type: "text" }
19
- | { type: "binary" }
20
- | { type: "boolean" }
21
- | { type: "datetime" }
22
- | { type: "date" }
23
- | { type: "time" }
24
- | { type: "uuid" };
25
- ```
26
-
27
- | `type` | MySQL | MSSQL | PostgreSQL | TypeScript |
28
- |--------|-------|-------|------------|------------|
29
- | `int` | INT | INT | INTEGER | `number` |
30
- | `bigint` | BIGINT | BIGINT | BIGINT | `number` |
31
- | `float` | FLOAT | REAL | REAL | `number` |
32
- | `double` | DOUBLE | FLOAT | DOUBLE PRECISION | `number` |
33
- | `decimal` | DECIMAL(p,s) | DECIMAL(p,s) | NUMERIC(p,s) | `number` |
34
- | `varchar` | VARCHAR(n) | NVARCHAR(n) | VARCHAR(n) | `string` |
35
- | `char` | CHAR(n) | NCHAR(n) | CHAR(n) | `string` |
36
- | `text` | LONGTEXT | NVARCHAR(MAX) | TEXT | `string` |
37
- | `binary` | LONGBLOB | VARBINARY(MAX) | BYTEA | `Bytes` |
38
- | `boolean` | TINYINT(1) | BIT | BOOLEAN | `boolean` |
39
- | `datetime` | DATETIME | DATETIME2 | TIMESTAMP | `DateTime` |
40
- | `date` | DATE | DATE | DATE | `DateOnly` |
41
- | `time` | TIME | TIME | TIME | `Time` |
42
- | `uuid` | BINARY(16) | UNIQUEIDENTIFIER | UUID | `Uuid` |
43
-
44
- ## `ColumnPrimitiveMap`
45
-
46
- TypeScript 타입 이름(문자열) → 실제 TypeScript 타입 매핑.
47
-
48
- ```typescript
49
- export type ColumnPrimitiveMap = {
50
- string: string;
51
- number: number;
52
- boolean: boolean;
53
- DateTime: DateTime;
54
- DateOnly: DateOnly;
55
- Time: Time;
56
- Uuid: Uuid;
57
- Bytes: Bytes;
58
- };
59
- ```
60
-
61
- ## `ColumnPrimitiveStr`
62
-
63
- Column 원시 타입 이름 문자열. `keyof ColumnPrimitiveMap`.
64
-
65
- ```typescript
66
- export type ColumnPrimitiveStr = keyof ColumnPrimitiveMap;
67
- // "string" | "number" | "boolean" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Bytes"
68
- ```
69
-
70
- ## `ColumnPrimitive`
71
-
72
- Column에 저장 가능한 모든 원시 타입. `undefined`는 NULL을 나타낸다.
73
-
74
- ```typescript
75
- export type ColumnPrimitive = ColumnPrimitiveMap[ColumnPrimitiveStr] | undefined;
76
- ```
77
-
78
- ## `dataTypeStrToColumnPrimitiveStr`
79
-
80
- SQL DataType의 `type` 문자열 → `ColumnPrimitiveStr` 매핑 상수.
81
-
82
- ```typescript
83
- export const dataTypeStrToColumnPrimitiveStr: {
84
- int: "number";
85
- bigint: "number";
86
- float: "number";
87
- double: "number";
88
- decimal: "number";
89
- varchar: "string";
90
- char: "string";
91
- text: "string";
92
- binary: "Bytes";
93
- boolean: "boolean";
94
- datetime: "DateTime";
95
- date: "DateOnly";
96
- time: "Time";
97
- uuid: "Uuid";
98
- };
99
- ```
100
-
101
- ## `InferColumnPrimitiveFromDataType<T>`
102
-
103
- `DataType`으로부터 TypeScript 타입을 추론하는 제네릭 타입.
104
-
105
- ```typescript
106
- export type InferColumnPrimitiveFromDataType<TDataType extends DataType> =
107
- ColumnPrimitiveMap[(typeof dataTypeStrToColumnPrimitiveStr)[TDataType["type"]]];
108
-
109
- // 예시
110
- type IntType = InferColumnPrimitiveFromDataType<{ type: "int" }>; // number
111
- type VarcharType = InferColumnPrimitiveFromDataType<{ type: "varchar"; length: 100 }>; // string
112
- ```
113
-
114
- ## `inferColumnPrimitiveStr`
115
-
116
- 런타임 값에서 `ColumnPrimitiveStr`을 추론하는 함수.
117
-
118
- ```typescript
119
- export function inferColumnPrimitiveStr(value: ColumnPrimitive): ColumnPrimitiveStr;
120
- ```
121
-
122
- - `undefined`/`null`이면 에러를 던진다.
123
-
124
- ## `ColumnMeta`
125
-
126
- `ColumnBuilder`에서 생성되어 `TableBuilder`에 전달되는 Column 메타데이터.
127
-
128
- ```typescript
129
- export interface ColumnMeta {
130
- type: ColumnPrimitiveStr;
131
- dataType: DataType;
132
- autoIncrement?: boolean;
133
- nullable?: boolean;
134
- default?: ColumnPrimitive;
135
- description?: string;
136
- }
137
- ```
138
-
139
- | 필드 | 타입 | 설명 |
140
- |------|------|------|
141
- | `type` | `ColumnPrimitiveStr` | TypeScript 타입 이름 |
142
- | `dataType` | `DataType` | SQL 데이터 타입 |
143
- | `autoIncrement` | `boolean \| undefined` | AUTO_INCREMENT 여부 |
144
- | `nullable` | `boolean \| undefined` | NULL 허용 여부 |
145
- | `default` | `ColumnPrimitive \| undefined` | 기본값 |
146
- | `description` | `string \| undefined` | Column 설명 (DDL Comment) |
@@ -1,151 +0,0 @@
1
- # Dialect
2
-
3
- 지원하는 DB 방언 타입 및 관련 런타임 타입 모음.
4
-
5
- ## `Dialect`
6
-
7
- ```typescript
8
- export type Dialect = "mysql" | "mssql" | "postgresql";
9
- ```
10
-
11
- | 값 | 지원 버전 |
12
- |----|-----------|
13
- | `"mysql"` | MySQL 8.0.14+ |
14
- | `"mssql"` | Microsoft SQL Server 2012+ |
15
- | `"postgresql"` | PostgreSQL 9.0+ |
16
-
17
- ## `dialects`
18
-
19
- 모든 dialect 목록 배열. 테스트에서 dialect별 검증에 사용한다.
20
-
21
- ```typescript
22
- export const dialects: Dialect[] = ["mysql", "mssql", "postgresql"];
23
- ```
24
-
25
- ## `IsolationLevel`
26
-
27
- 트랜잭션 격리 수준.
28
-
29
- ```typescript
30
- export type IsolationLevel =
31
- | "READ_UNCOMMITTED"
32
- | "READ_COMMITTED"
33
- | "REPEATABLE_READ"
34
- | "SERIALIZABLE";
35
- ```
36
-
37
- | 값 | 설명 |
38
- |----|------|
39
- | `READ_UNCOMMITTED` | 커밋되지 않은 데이터 읽기 가능 (Dirty Read) |
40
- | `READ_COMMITTED` | 커밋된 데이터만 읽기 (기본값) |
41
- | `REPEATABLE_READ` | 트랜잭션 내 동일 쿼리가 동일 결과 보장 |
42
- | `SERIALIZABLE` | 완전 직렬화 (가장 엄격) |
43
-
44
- ## `DataRecord`
45
-
46
- 쿼리 결과 데이터 레코드 타입. 재귀적 구조로 중첩 관계(`include`) 결과를 표현한다.
47
-
48
- ```typescript
49
- export type DataRecord = {
50
- [key: string]: ColumnPrimitive | DataRecord | DataRecord[];
51
- };
52
- ```
53
-
54
- ## `DbContextExecutor`
55
-
56
- 실제 DB 연결과 쿼리 실행을 담당하는 인터페이스. `orm-node`의 `NodeDbContextExecutor` 또는 서비스 클라이언트 구현체가 이 인터페이스를 구현한다.
57
-
58
- ```typescript
59
- export interface DbContextExecutor {
60
- connect(): Promise<void>;
61
- close(): Promise<void>;
62
- beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
63
- commitTransaction(): Promise<void>;
64
- rollbackTransaction(): Promise<void>;
65
- executeDefs<T = DataRecord>(
66
- defs: QueryDef[],
67
- resultMetas?: (ResultMeta | undefined)[],
68
- ): Promise<T[][]>;
69
- }
70
- ```
71
-
72
- | 메서드 | 설명 |
73
- |--------|------|
74
- | `connect()` | DB 연결 수립 |
75
- | `close()` | DB 연결 종료 |
76
- | `beginTransaction(isolationLevel?)` | 트랜잭션 시작 |
77
- | `commitTransaction()` | 트랜잭션 커밋 |
78
- | `rollbackTransaction()` | 트랜잭션 롤백 |
79
- | `executeDefs(defs, resultMetas?)` | QueryDef 배열 실행, 결과 배열 반환 |
80
-
81
- ## `QueryBuildResult`
82
-
83
- `QueryBuilderBase.build()` 반환 타입.
84
-
85
- ```typescript
86
- export interface QueryBuildResult {
87
- sql: string;
88
- resultSetIndex?: number;
89
- resultSetStride?: number;
90
- }
91
- ```
92
-
93
- | 필드 | 타입 | 설명 |
94
- |------|------|------|
95
- | `sql` | `string` | 빌드된 SQL 문자열 |
96
- | `resultSetIndex` | `number \| undefined` | 결과를 가져올 결과 셋 인덱스. 기본값 0 |
97
- | `resultSetStride` | `number \| undefined` | stride 간격으로 다중 결과 셋 수집. MySQL 배치 INSERT에 사용 |
98
-
99
- ## `ResultMeta`
100
-
101
- SELECT 결과를 TypeScript 객체로 변환할 때 사용하는 메타데이터.
102
-
103
- ```typescript
104
- export interface ResultMeta {
105
- columns: Record<string, ColumnPrimitiveStr>;
106
- joins: Record<string, { isSingle: boolean }>;
107
- }
108
- ```
109
-
110
- | 필드 | 타입 | 설명 |
111
- |------|------|------|
112
- | `columns` | `Record<string, ColumnPrimitiveStr>` | 컬럼 이름 → 타입 이름 매핑 |
113
- | `joins` | `Record<string, { isSingle: boolean }>` | JOIN 별칭 → 단일/배열 구분 |
114
-
115
- ## `Migration`
116
-
117
- DB 마이그레이션 정의.
118
-
119
- ```typescript
120
- export interface Migration {
121
- name: string;
122
- up: (db: DbContextBase & DbContextDdlMethods) => Promise<void>;
123
- }
124
- ```
125
-
126
- | 필드 | 타입 | 설명 |
127
- |------|------|------|
128
- | `name` | `string` | 고유 마이그레이션 이름. 타임스탬프 형식 권장 |
129
- | `up` | `(db) => Promise<void>` | 마이그레이션 실행 함수 |
130
-
131
- ```typescript
132
- const migrations: Migration[] = [
133
- {
134
- name: "20260105_001_create_user_table",
135
- up: async (db) => {
136
- await db.createTable(User);
137
- },
138
- },
139
- ];
140
- ```
141
-
142
- ## `pickResultSets`
143
-
144
- 다중 결과 셋에서 `QueryBuildResult` 메타데이터에 따라 필요한 결과만 추출한다. MySQL 배치 INSERT 후 OUTPUT 추출에 사용된다.
145
-
146
- ```typescript
147
- export function pickResultSets<T>(
148
- rawResults: T[][],
149
- buildResult: Pick<QueryBuildResult, "resultSetIndex" | "resultSetStride">,
150
- ): T[];
151
- ```
@@ -1,175 +0,0 @@
1
- # Expr
2
-
3
- SQL 표현식 AST 타입 모음. `expr.*` 함수들이 내부적으로 생성하며, `QueryBuilderBase`가 SQL 문자열로 변환한다.
4
-
5
- ## `Expr`
6
-
7
- 모든 SELECT 표현식 AST의 유니온 타입.
8
-
9
- ```typescript
10
- export type Expr =
11
- | ExprColumn
12
- | ExprValue
13
- | ExprRaw
14
- | ExprConcat
15
- | ExprLeft
16
- | ExprRight
17
- | ExprTrim
18
- | ExprPadStart
19
- | ExprReplace
20
- | ExprUpper
21
- | ExprLower
22
- | ExprLength
23
- | ExprByteLength
24
- | ExprSubstring
25
- | ExprIndexOf
26
- | ExprAbs
27
- | ExprRound
28
- | ExprCeil
29
- | ExprFloor
30
- | ExprAdd
31
- | ExprSub
32
- | ExprMul
33
- | ExprDiv
34
- | ExprMod
35
- | ExprYear
36
- | ExprMonth
37
- | ExprDay
38
- | ExprHour
39
- | ExprMinute
40
- | ExprSecond
41
- | ExprDateDiff
42
- | ExprDateAdd
43
- | ExprCount
44
- | ExprSum
45
- | ExprAvg
46
- | ExprMax
47
- | ExprMin
48
- | ExprRowNumber
49
- | ExprRank
50
- | ExprDenseRank
51
- | ExprLag
52
- | ExprLead
53
- | ExprSumOver
54
- | ExprCountOver
55
- | ExprAvgOver
56
- | ExprMaxOver
57
- | ExprMinOver
58
- | ExprFirstValue
59
- | ExprLastValue
60
- | ExprNtile
61
- | ExprSubquery
62
- | ExprIf
63
- | ExprSwitch
64
- | ExprCoalesce
65
- | ExprNullIf
66
- | ExprCast
67
- | ExprToDateOnly
68
- | ExprToDateTime;
69
- ```
70
-
71
- ## `WhereExpr`
72
-
73
- WHERE 절 표현식 AST 유니온 타입.
74
-
75
- ```typescript
76
- export type WhereExpr =
77
- | ExprEq
78
- | ExprGt
79
- | ExprLt
80
- | ExprGte
81
- | ExprLte
82
- | ExprBetween
83
- | ExprIsNull
84
- | ExprLike
85
- | ExprRegexp
86
- | ExprIn
87
- | ExprInQuery
88
- | ExprExists
89
- | ExprNot
90
- | ExprAnd
91
- | ExprOr;
92
- ```
93
-
94
- ## `DateUnit`
95
-
96
- 날짜 연산 단위. `expr.dateDiff()`, `expr.dateAdd()`에서 사용.
97
-
98
- ```typescript
99
- export type DateUnit = "year" | "month" | "day" | "hour" | "minute" | "second";
100
- ```
101
-
102
- ## `WinSpec`
103
-
104
- 윈도우 함수 스펙.
105
-
106
- ```typescript
107
- export interface WinSpec {
108
- partitionBy?: Expr[];
109
- orderBy?: [Expr, ("ASC" | "DESC")?][];
110
- }
111
- ```
112
-
113
- ## 값 표현식 인터페이스
114
-
115
- | 인터페이스 | `type` 값 | 설명 |
116
- |------------|-----------|------|
117
- | `ExprColumn` | `"column"` | 컬럼 참조. `path: string[]` |
118
- | `ExprValue` | `"value"` | 리터럴 값. `value: ColumnPrimitive` |
119
- | `ExprRaw` | `"raw"` | Raw SQL. `sql: string`, `params: Expr[]` |
120
-
121
- ## 비교 표현식 인터페이스 (WhereExpr)
122
-
123
- | 인터페이스 | `type` 값 | 설명 |
124
- |------------|-----------|------|
125
- | `ExprEq` | `"eq"` | `=` (NULL 안전). `source`, `target` |
126
- | `ExprGt` | `"gt"` | `>`. `source`, `target` |
127
- | `ExprLt` | `"lt"` | `<`. `source`, `target` |
128
- | `ExprGte` | `"gte"` | `>=`. `source`, `target` |
129
- | `ExprLte` | `"lte"` | `<=`. `source`, `target` |
130
- | `ExprBetween` | `"between"` | `BETWEEN`. `source`, `from?`, `to?` |
131
- | `ExprIsNull` | `"null"` | `IS NULL`. `arg` |
132
- | `ExprLike` | `"like"` | `LIKE`. `source`, `pattern` |
133
- | `ExprRegexp` | `"regexp"` | 정규식. `source`, `pattern` |
134
- | `ExprIn` | `"in"` | `IN (...)`. `source`, `values: Expr[]` |
135
- | `ExprInQuery` | `"inQuery"` | `IN (SELECT ...)`. `source`, `query: SelectQueryDef` |
136
- | `ExprExists` | `"exists"` | `EXISTS (SELECT ...)`. `query: SelectQueryDef` |
137
- | `ExprNot` | `"not"` | `NOT`. `arg: WhereExpr` |
138
- | `ExprAnd` | `"and"` | `AND`. `conditions: WhereExpr[]` |
139
- | `ExprOr` | `"or"` | `OR`. `conditions: WhereExpr[]` |
140
-
141
- ## 집계/윈도우 함수 인터페이스
142
-
143
- | 인터페이스 | `type` 값 | 설명 |
144
- |------------|-----------|------|
145
- | `ExprCount` | `"count"` | `COUNT(*)` 또는 `COUNT(arg)`. `arg?: Expr` |
146
- | `ExprSum` | `"sum"` | `SUM(arg)`. `arg: Expr` |
147
- | `ExprAvg` | `"avg"` | `AVG(arg)`. `arg: Expr` |
148
- | `ExprMax` | `"max"` | `MAX(arg)`. `arg: Expr` |
149
- | `ExprMin` | `"min"` | `MIN(arg)`. `arg: Expr` |
150
- | `ExprRowNumber` | `"rowNumber"` | `ROW_NUMBER() OVER (...)`. `winSpec: WinSpec` |
151
- | `ExprRank` | `"rank"` | `RANK() OVER (...)`. `winSpec: WinSpec` |
152
- | `ExprDenseRank` | `"denseRank"` | `DENSE_RANK() OVER (...)`. `winSpec: WinSpec` |
153
- | `ExprLag` | `"lag"` | `LAG(...) OVER (...)`. `source`, `offset?`, `default?`, `winSpec?` |
154
- | `ExprLead` | `"lead"` | `LEAD(...) OVER (...)`. `source`, `offset?`, `default?`, `winSpec?` |
155
- | `ExprSumOver` | `"sumOver"` | `SUM(...) OVER (...)` |
156
- | `ExprCountOver` | `"countOver"` | `COUNT(...) OVER (...)` |
157
- | `ExprAvgOver` | `"avgOver"` | `AVG(...) OVER (...)` |
158
- | `ExprMaxOver` | `"maxOver"` | `MAX(...) OVER (...)` |
159
- | `ExprMinOver` | `"minOver"` | `MIN(...) OVER (...)` |
160
- | `ExprFirstValue` | `"firstValue"` | `FIRST_VALUE(...) OVER (...)` |
161
- | `ExprLastValue` | `"lastValue"` | `LAST_VALUE(...) OVER (...)` |
162
- | `ExprNtile` | `"ntile"` | `NTILE(n) OVER (...)` |
163
-
164
- ## 조건부/변환 인터페이스
165
-
166
- | 인터페이스 | `type` 값 | 설명 |
167
- |------------|-----------|------|
168
- | `ExprIf` | `"if"` | `IF(cond, then, else)`. `condition: WhereExpr`, `then: Expr`, `else_: Expr` |
169
- | `ExprSwitch` | `"switch"` | `CASE WHEN`. `cases: { condition, then }[]`, `default?: Expr` |
170
- | `ExprCoalesce` | `"coalesce"` | `COALESCE(...)`. `args: Expr[]` |
171
- | `ExprNullIf` | `"nullIf"` | `NULLIF(source, target)` |
172
- | `ExprCast` | `"cast"` | `CAST(source AS type)`. `source: Expr`, `dataType: DataType` |
173
- | `ExprToDateOnly` | `"toDateOnly"` | DateTime → DateOnly 변환 |
174
- | `ExprToDateTime` | `"toDateTime"` | DateOnly → DateTime 변환 |
175
- | `ExprSubquery` | `"subquery"` | 단일 값 반환 서브쿼리. `dataType: ColumnPrimitiveStr`, `query: SelectQueryDef` |
@@ -1,58 +0,0 @@
1
- # parseQueryResult
2
-
3
- DB 쿼리 원시 결과(`Record<string, unknown>[]`)를 `ResultMeta`를 이용해 타입 변환하고, JOIN 결과를 중첩 TypeScript 객체로 재구성한다. `Queryable.execute()` 내부에서 자동 호출되며, 직접 호출은 커스텀 executor 구현 시에만 필요하다.
4
-
5
- ```typescript
6
- export async function parseQueryResult<TRecord>(
7
- rawResults: Record<string, unknown>[],
8
- meta: ResultMeta,
9
- ): Promise<TRecord[] | undefined>;
10
- ```
11
-
12
- ## Parameters
13
-
14
- | Param | Type | Description |
15
- |-------|------|-------------|
16
- | `rawResults` | `Record<string, unknown>[]` | DB에서 반환된 플랫 원시 결과 배열 |
17
- | `meta` | `ResultMeta` | 컬럼 타입 정보 및 JOIN 구조 정보 |
18
-
19
- ## Returns
20
-
21
- `Promise<TRecord[] | undefined>` — 타입 변환 및 중첩 구조로 재구성된 결과 배열. 입력이 비어 있거나 파싱 후 모든 레코드가 빈 객체이면 `undefined` 반환.
22
-
23
- ## 동작
24
-
25
- 1. **단순 타입 파싱** (JOIN 없는 경우): `meta.columns`에 따라 각 컬럼 값을 TypeScript 타입으로 변환한다. 예를 들어 `"1"` → `1`, `"2026-01-07T10:00:00.000Z"` → `DateTime`.
26
- 2. **JOIN 결과 중첩** (JOIN 있는 경우): `meta.joins`에 따라 `"posts.id"` 등 점 구분 플랫 키를 중첩 객체/배열로 그룹핑한다. `isSingle: false`이면 배열, `isSingle: true`이면 단일 객체로 조합한다.
27
- 3. **비동기 양보**: 100개 레코드마다 이벤트 루프에 양보하여 대규모 결과 처리 시 UI/다른 작업을 차단하지 않는다.
28
-
29
- ## 주의사항
30
-
31
- - `meta` 없이는 이 함수를 호출할 필요가 없다 (입력 = 출력).
32
- - 브라우저/Node.js 양쪽에서 동작한다 (`setImmediate` 또는 `setTimeout` 폴백).
33
- - 타입 파싱 실패(숫자 변환 실패 등) 시 에러를 던진다.
34
-
35
- ## Usage
36
-
37
- ```typescript
38
- // 단순 타입 파싱
39
- const raw = [{ id: "1", createdAt: "2026-01-07T10:00:00.000Z" }];
40
- const meta: ResultMeta = {
41
- columns: { id: "number", createdAt: "DateTime" },
42
- joins: {},
43
- };
44
- const result = await parseQueryResult(raw, meta);
45
- // [{ id: 1, createdAt: DateTime(...) }]
46
-
47
- // JOIN 결과 중첩
48
- const raw = [
49
- { id: 1, name: "User1", "posts.id": 10, "posts.title": "Post1" },
50
- { id: 1, name: "User1", "posts.id": 11, "posts.title": "Post2" },
51
- ];
52
- const meta: ResultMeta = {
53
- columns: { id: "number", name: "string", "posts.id": "number", "posts.title": "string" },
54
- joins: { posts: { isSingle: false } },
55
- };
56
- const result = await parseQueryResult(raw, meta);
57
- // [{ id: 1, name: "User1", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
58
- ```