@simplysm/orm-common 13.0.96 → 13.0.98

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/docs/schema.md DELETED
@@ -1,325 +0,0 @@
1
- # 스키마 정의
2
-
3
- ## Table
4
-
5
- 불변 빌더 패턴으로 테이블을 정의한다. 모든 메서드는 새 인스턴스를 반환한다.
6
-
7
- ```typescript
8
- import { Table } from "@simplysm/orm-common";
9
-
10
- const User = Table("user")
11
- .description("사용자 테이블")
12
- .database("mydb") // 선택
13
- .schema("dbo") // MSSQL/PostgreSQL, 선택
14
- .columns((c) => ({
15
- id: c.int().autoIncrement(),
16
- name: c.varchar(100),
17
- email: c.varchar(200).nullable(),
18
- role: c.varchar(20).default("user"),
19
- bio: c.text().nullable(),
20
- avatar: c.binary().nullable(),
21
- score: c.decimal(10, 2).nullable(),
22
- active: c.boolean().default(true),
23
- birthday: c.date().nullable(),
24
- loginTime: c.time().nullable(),
25
- createdAt: c.datetime(),
26
- externalId: c.uuid().nullable(),
27
- }))
28
- .primaryKey("id") // 복합 PK 지원: .primaryKey("col1", "col2")
29
- .indexes((i) => [
30
- i.index("email").unique(),
31
- i.index("name", "role").orderBy("ASC", "DESC"),
32
- i.index("createdAt").name("ix_created"),
33
- ])
34
- .relations((r) => ({
35
- orders: r.foreignKeyTarget(() => Order, "user"), // 1:N
36
- profile: r.foreignKeyTarget(() => Profile, "user").single(), // 1:1
37
- }));
38
- ```
39
-
40
- ### Table API
41
-
42
- ```
43
- Table(name: string): TableBuilder
44
- ```
45
-
46
- | 메서드 | 시그니처 | 설명 |
47
- |--------|---------|------|
48
- | `description` | `(desc: string) => TableBuilder` | 테이블 설명 (DDL 코멘트) |
49
- | `database` | `(db: string) => TableBuilder` | 데이터베이스 이름 |
50
- | `schema` | `(schema: string) => TableBuilder` | 스키마 이름 (MSSQL: dbo, PostgreSQL: public) |
51
- | `columns` | `(fn: (c) => Record) => TableBuilder` | 컬럼 정의 |
52
- | `primaryKey` | `(...columns: string[]) => TableBuilder` | PK 설정 (복합 PK 지원) |
53
- | `indexes` | `(fn: (i) => IndexBuilder[]) => TableBuilder` | 인덱스 정의 |
54
- | `relations` | `(fn: (r) => Record) => TableBuilder` | 관계 정의 |
55
-
56
- ### 컬럼 타입
57
-
58
- | 메서드 | SQL 타입 | TypeScript 타입 |
59
- |--------|---------|----------------|
60
- | `c.int()` | INT | `number` |
61
- | `c.bigint()` | BIGINT | `number` |
62
- | `c.float()` | FLOAT | `number` |
63
- | `c.double()` | DOUBLE | `number` |
64
- | `c.decimal(p, s?)` | DECIMAL(p,s) | `number` |
65
- | `c.varchar(len)` | VARCHAR(len) | `string` |
66
- | `c.char(len)` | CHAR(len) | `string` |
67
- | `c.text()` | LONGTEXT/TEXT | `string` |
68
- | `c.boolean()` | BIT/TINYINT(1) | `boolean` |
69
- | `c.datetime()` | DATETIME | `DateTime` |
70
- | `c.date()` | DATE | `DateOnly` |
71
- | `c.time()` | TIME | `Time` |
72
- | `c.binary()` | LONGBLOB/VARBINARY/BYTEA | `Bytes` |
73
- | `c.uuid()` | UNIQUEIDENTIFIER/UUID | `Uuid` |
74
-
75
- ### 컬럼 수정자
76
-
77
- ```typescript
78
- c.int().autoIncrement() // 자동 증가 (INSERT 시 선택적)
79
- c.varchar(100).nullable() // NULL 허용 (타입에 undefined 추가)
80
- c.varchar(20).default("x") // 기본값 (INSERT 시 선택적)
81
- c.varchar(100).description("설명")
82
- ```
83
-
84
- ### 타입 추론
85
-
86
- ```typescript
87
- User.$inferSelect // { id: number; name: string; email: string | undefined; ... }
88
- User.$inferInsert // { name: string; createdAt: DateTime; } & { id?: number; email?: string; ... }
89
- User.$inferUpdate // { id?: number; name?: string; ... } (모든 필드 선택적)
90
- User.$inferColumns // { id: number; name: string; email: string | undefined; ... } (관계 제외)
91
- ```
92
-
93
- ---
94
-
95
- ## 관계 (Relation)
96
-
97
- ### foreignKey -- N:1 (DB FK 생성)
98
-
99
- ```typescript
100
- const Order = Table("order")
101
- .columns((c) => ({
102
- id: c.int().autoIncrement(),
103
- userId: c.int(),
104
- }))
105
- .primaryKey("id")
106
- .relations((r) => ({
107
- user: r.foreignKey(["userId"], () => User), // Order.userId -> User.id
108
- }));
109
- ```
110
-
111
- ### foreignKeyTarget -- 1:N / 1:1 (역참조)
112
-
113
- ```typescript
114
- const User = Table("user")
115
- .columns((c) => ({ id: c.int().autoIncrement(), name: c.varchar(100) }))
116
- .primaryKey("id")
117
- .relations((r) => ({
118
- orders: r.foreignKeyTarget(() => Order, "user"), // 1:N (배열)
119
- profile: r.foreignKeyTarget(() => Profile, "user").single(), // 1:1 (단일 객체)
120
- }));
121
- ```
122
-
123
- ### relationKey / relationKeyTarget -- 논리적 관계 (DB FK 없음)
124
-
125
- View에서도 사용 가능. DB에 FK 제약조건을 생성하지 않는다.
126
-
127
- ```typescript
128
- .relations((r) => ({
129
- category: r.relationKey(["categoryId"], () => Category),
130
- items: r.relationKeyTarget(() => Item, "parent"),
131
- }))
132
- ```
133
-
134
- ### 관계 빌더 API
135
-
136
- | 빌더 | 용도 | DB FK 생성 |
137
- |------|------|----------|
138
- | `ForeignKeyBuilder` | N:1 관계 (FK 컬럼 소유) | O |
139
- | `ForeignKeyTargetBuilder` | 1:N / 1:1 역참조 | O (대상 테이블) |
140
- | `RelationKeyBuilder` | N:1 논리적 관계 | X |
141
- | `RelationKeyTargetBuilder` | 1:N / 1:1 논리적 역참조 | X |
142
-
143
- 공통 메서드:
144
-
145
- | 메서드 | 설명 |
146
- |--------|------|
147
- | `.description(desc)` | 관계 설명 |
148
- | `.single()` | 1:1 관계 (ForeignKeyTargetBuilder, RelationKeyTargetBuilder만 해당) |
149
-
150
- ---
151
-
152
- ## View
153
-
154
- ```typescript
155
- import { View, expr } from "@simplysm/orm-common";
156
-
157
- const UserSummary = View("user_summary")
158
- .database("mydb")
159
- .query<typeof MyDb>((db) =>
160
- db.user()
161
- .select((c) => ({
162
- userId: c.id,
163
- userName: c.name,
164
- orderCount: expr.count(),
165
- totalAmount: expr.sum(c.amount),
166
- }))
167
- .groupBy((c) => [c.id, c.name])
168
- )
169
- .relations((r) => ({
170
- user: r.relationKey(["userId"], () => User),
171
- }));
172
- ```
173
-
174
- ### View API
175
-
176
- ```
177
- View(name: string): ViewBuilder
178
- ```
179
-
180
- | 메서드 | 시그니처 | 설명 |
181
- |--------|---------|------|
182
- | `description` | `(desc: string) => ViewBuilder` | 뷰 설명 |
183
- | `database` | `(db: string) => ViewBuilder` | 데이터베이스 이름 |
184
- | `schema` | `(schema: string) => ViewBuilder` | 스키마 이름 |
185
- | `query` | `(viewFn: (db) => Queryable) => ViewBuilder` | 뷰 쿼리 정의 |
186
- | `relations` | `(fn: (r) => Record) => ViewBuilder` | 관계 정의 (relationKey만 가능) |
187
-
188
- **DbContext 등록:**
189
-
190
- ```typescript
191
- const MyDb = defineDbContext({
192
- tables: { user: User },
193
- views: { userSummary: UserSummary },
194
- });
195
- ```
196
-
197
- ---
198
-
199
- ## Procedure
200
-
201
- ```typescript
202
- import { Procedure } from "@simplysm/orm-common";
203
-
204
- const GetUserOrders = Procedure("get_user_orders")
205
- .database("mydb")
206
- .params((c) => ({
207
- userId: c.int(),
208
- fromDate: c.date().nullable(),
209
- }))
210
- .returns((c) => ({
211
- orderId: c.int(),
212
- amount: c.decimal(10, 2),
213
- createdAt: c.datetime(),
214
- }))
215
- .body(`
216
- SELECT id AS orderId, amount, created_at AS createdAt
217
- FROM orders
218
- WHERE user_id = userId AND created_at >= COALESCE(fromDate, '1900-01-01')
219
- `);
220
- ```
221
-
222
- ### Procedure API
223
-
224
- ```
225
- Procedure(name: string): ProcedureBuilder
226
- ```
227
-
228
- | 메서드 | 시그니처 | 설명 |
229
- |--------|---------|------|
230
- | `description` | `(desc: string) => ProcedureBuilder` | 프로시저 설명 |
231
- | `database` | `(db: string) => ProcedureBuilder` | 데이터베이스 이름 |
232
- | `schema` | `(schema: string) => ProcedureBuilder` | 스키마 이름 |
233
- | `params` | `(fn: (c) => Record) => ProcedureBuilder` | 파라미터 정의 |
234
- | `returns` | `(fn: (c) => Record) => ProcedureBuilder` | 반환 타입 정의 |
235
- | `body` | `(sql: string) => ProcedureBuilder` | 프로시저 본문 SQL |
236
-
237
- **DbContext 등록:**
238
-
239
- ```typescript
240
- const MyDb = defineDbContext({
241
- tables: { user: User },
242
- procedures: { getUserOrders: GetUserOrders },
243
- });
244
- ```
245
-
246
- MSSQL은 파라미터에 `@` 접두사 필요: `@userId`, `@fromDate`
247
-
248
- ---
249
-
250
- ## Index
251
-
252
- ```typescript
253
- .indexes((i) => [
254
- i.index("email").unique(), // UNIQUE INDEX
255
- i.index("name", "role").orderBy("ASC", "DESC"), // 정렬 방향 지정
256
- i.index("createdAt").name("ix_custom_name"), // 커스텀 이름
257
- i.index("code").description("코드 인덱스"),
258
- ])
259
- ```
260
-
261
- ### IndexBuilder API
262
-
263
- | 메서드 | 시그니처 | 설명 |
264
- |--------|---------|------|
265
- | `index` | `(...columns: string[]) => IndexBuilder` | 인덱스 생성 (단일/복합) |
266
- | `unique` | `() => IndexBuilder` | 유니크 인덱스 설정 |
267
- | `orderBy` | `(...dirs: ("ASC"\|"DESC")[]) => IndexBuilder` | 컬럼별 정렬 방향 |
268
- | `name` | `(name: string) => IndexBuilder` | 커스텀 인덱스 이름 |
269
- | `description` | `(desc: string) => IndexBuilder` | 인덱스 설명 |
270
-
271
- ---
272
-
273
- ## defineDbContext / createDbContext
274
-
275
- ### defineDbContext -- 스키마 블루프린트
276
-
277
- ```typescript
278
- import { defineDbContext } from "@simplysm/orm-common";
279
-
280
- const MyDb = defineDbContext({
281
- tables: { user: User, order: Order },
282
- views: { userSummary: UserSummary },
283
- procedures: { getUserOrders: GetUserOrders },
284
- migrations: [
285
- {
286
- name: "20260105_001_add_phone",
287
- up: async (db) => {
288
- const c = createColumnFactory();
289
- await db.addColumn({ name: "user" }, "phone", c.varchar(20).nullable());
290
- },
291
- },
292
- ],
293
- });
294
- ```
295
-
296
- `_migration` 테이블이 자동으로 포함된다.
297
-
298
- ### createDbContext -- 런타임 인스턴스 생성
299
-
300
- ```typescript
301
- import { createDbContext } from "@simplysm/orm-common";
302
-
303
- const db = createDbContext(MyDb, executor, {
304
- database: "mydb",
305
- schema: "dbo", // MSSQL/PostgreSQL 선택
306
- });
307
- ```
308
-
309
- ```
310
- createDbContext(
311
- def: DbContextDef,
312
- executor: DbContextExecutor,
313
- opt: { database: string; schema?: string },
314
- ): DbContextInstance
315
- ```
316
-
317
- `executor`는 `DbContextExecutor` 인터페이스를 구현해야 한다 (`@simplysm/orm-node`의 `NodeDbContextExecutor` 등).
318
-
319
- 생성된 인스턴스는 다음을 포함한다:
320
- - 등록된 테이블/뷰에 대한 `Queryable` 접근자 (예: `db.user()`, `db.order()`)
321
- - 등록된 프로시저에 대한 `Executable` 접근자 (예: `db.getUserOrders()`)
322
- - 연결/트랜잭션 관리 메서드
323
- - DDL 실행 메서드
324
- - `initialize()` 메서드
325
- - `_migration()` 시스템 테이블 접근자