@simplysm/orm-node 13.0.0-beta.51 → 13.0.1

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 CHANGED
@@ -28,28 +28,33 @@ npm install pg pg-copy-streams
28
28
  ## Architecture
29
29
 
30
30
  ```
31
- SdOrm (top-level entry point)
31
+ createOrm() (top-level entry point)
32
32
  └── NodeDbContextExecutor (executor between DbContext and actual DB)
33
- └── DbConnFactory (connection creation and pool management)
33
+ └── createDbConn() (connection creation and pool management)
34
34
  └── PooledDbConn (connection pool wrapper)
35
35
  └── MysqlDbConn / MssqlDbConn / PostgresqlDbConn (DBMS-specific low-level connections)
36
36
  ```
37
37
 
38
- - `SdOrm` is the top-level class that takes a `DbContext` type and connection settings to manage transactions.
38
+ - `createOrm()` is the top-level factory function that takes a `DbContext` type and connection settings to manage transactions.
39
39
  - `NodeDbContextExecutor` is the executor used by `DbContext`, converting `QueryDef` to SQL and executing it.
40
- - `DbConnFactory` is a factory that acquires connections from the connection pool.
40
+ - `createDbConn()` is a factory function that acquires connections from the connection pool.
41
41
  - `PooledDbConn` is a connection pool wrapper based on `generic-pool`, returning connections to the pool instead of closing them after use.
42
42
  - Each DBMS-specific connection class (`MysqlDbConn`, `MssqlDbConn`, `PostgresqlDbConn`) directly uses low-level DB drivers.
43
43
 
44
44
  ## Core Modules
45
45
 
46
+ ### Functions
47
+
48
+ | Function | Description |
49
+ |----------|-------------|
50
+ | `createOrm()` | ORM factory function. Takes `DbContext` type and connection settings to manage transaction-based connections. |
51
+ | `createDbConn()` | Connection factory function. Caches connection pools by configuration and returns `PooledDbConn`. |
52
+
46
53
  ### Classes
47
54
 
48
55
  | Class | Description |
49
56
  |--------|------|
50
- | `SdOrm` | ORM top-level class. Takes `DbContext` type and connection settings to manage transaction-based connections. |
51
57
  | `NodeDbContextExecutor` | `DbContextExecutor` implementation. Converts `QueryDef` to SQL, executes it, and parses results. |
52
- | `DbConnFactory` | Connection factory. Caches connection pools by configuration and returns `PooledDbConn`. |
53
58
  | `PooledDbConn` | Connection pool wrapper. Acquires/returns physical connections from `generic-pool`, implements `DbConn` interface. |
54
59
  | `MysqlDbConn` | MySQL connection class. Uses `mysql2/promise` driver. |
55
60
  | `MssqlDbConn` | MSSQL/Azure SQL connection class. Uses `tedious` driver. |
@@ -65,7 +70,7 @@ SdOrm (top-level entry point)
65
70
  | `MssqlDbConnConfig` | MSSQL connection config. `dialect: "mssql" \| "mssql-azure"`. |
66
71
  | `PostgresqlDbConnConfig` | PostgreSQL connection config. `dialect: "postgresql"`. |
67
72
  | `DbPoolConfig` | Connection pool config (`min`, `max`, `acquireTimeoutMillis`, `idleTimeoutMillis`). |
68
- | `SdOrmOptions` | `SdOrm` options. `database`, `schema` settings that override `DbConnConfig`. |
73
+ | `OrmOptions` | `createOrm()` options. `database`, `schema` settings that override `DbConnConfig`. |
69
74
 
70
75
  ### Constants and Utility Functions
71
76
 
@@ -77,12 +82,12 @@ SdOrm (top-level entry point)
77
82
 
78
83
  ## Usage
79
84
 
80
- ### Basic Usage with SdOrm
85
+ ### Basic Usage with createOrm
81
86
 
82
- `SdOrm` is the top-level entry point used with `DbContext`. It automatically handles transaction management.
87
+ `createOrm()` is the top-level factory function used with `DbContext`. It automatically handles transaction management.
83
88
 
84
89
  ```typescript
85
- import { SdOrm } from "@simplysm/orm-node";
90
+ import { createOrm } from "@simplysm/orm-node";
86
91
  import { DbContext, queryable, Table } from "@simplysm/orm-common";
87
92
 
88
93
  // 1. Define table
@@ -100,8 +105,8 @@ class MyDb extends DbContext {
100
105
  readonly user = queryable(this, User);
101
106
  }
102
107
 
103
- // 3. Create SdOrm instance
104
- const orm = new SdOrm(MyDb, {
108
+ // 3. Create ORM instance
109
+ const orm = createOrm(MyDb, {
105
110
  dialect: "mysql",
106
111
  host: "localhost",
107
112
  port: 3306,
@@ -148,12 +153,12 @@ Supported isolation levels (`IsolationLevel`):
148
153
  - `"REPEATABLE_READ"`
149
154
  - `"SERIALIZABLE"`
150
155
 
151
- ### Overriding database/schema via SdOrmOptions
156
+ ### Overriding database/schema via OrmOptions
152
157
 
153
- Using `SdOrmOptions`, you can use different values instead of the `database`/`schema` set in `DbConnConfig`.
158
+ Using `OrmOptions`, you can use different values instead of the `database`/`schema` set in `DbConnConfig`.
154
159
 
155
160
  ```typescript
156
- const orm = new SdOrm(MyDb, {
161
+ const orm = createOrm(MyDb, {
157
162
  dialect: "postgresql",
158
163
  host: "localhost",
159
164
  port: 5432,
@@ -172,7 +177,7 @@ const orm = new SdOrm(MyDb, {
172
177
  Configure connection pool via the `pool` field in `DbConnConfig`. The pool is based on the `generic-pool` library, and pools are automatically cached for identical configurations.
173
178
 
174
179
  ```typescript
175
- const orm = new SdOrm(MyDb, {
180
+ const orm = createOrm(MyDb, {
176
181
  dialect: "mssql",
177
182
  host: "localhost",
178
183
  port: 1433,
@@ -188,15 +193,15 @@ const orm = new SdOrm(MyDb, {
188
193
  });
189
194
  ```
190
195
 
191
- ### Low-Level Connection with DbConnFactory
196
+ ### Low-Level Connection with createDbConn
192
197
 
193
- You can connect directly to the DB and execute SQL without `SdOrm`/`DbContext`. `DbConnFactory.create()` returns `PooledDbConn` from the connection pool.
198
+ You can connect directly to the DB and execute SQL without `createOrm`/`DbContext`. `createDbConn()` returns `PooledDbConn` from the connection pool.
194
199
 
195
200
  ```typescript
196
- import { DbConnFactory } from "@simplysm/orm-node";
201
+ import { createDbConn } from "@simplysm/orm-node";
197
202
 
198
203
  // Create connection (acquire from pool)
199
- const conn = await DbConnFactory.create({
204
+ const conn = await createDbConn({
200
205
  dialect: "mysql",
201
206
  host: "localhost",
202
207
  port: 3306,
@@ -233,7 +238,7 @@ try {
233
238
  Each connection class supports parameter binding via the `executeParametrized()` method.
234
239
 
235
240
  ```typescript
236
- const conn = await DbConnFactory.create({
241
+ const conn = await createDbConn({
237
242
  dialect: "postgresql",
238
243
  host: "localhost",
239
244
  port: 5432,
@@ -266,7 +271,7 @@ Supports bulk data insertion using native bulk APIs for each DBMS.
266
271
  ```typescript
267
272
  import type { ColumnMeta } from "@simplysm/orm-common";
268
273
 
269
- const conn = await DbConnFactory.create({
274
+ const conn = await createDbConn({
270
275
  dialect: "mysql",
271
276
  host: "localhost",
272
277
  port: 3306,
@@ -398,7 +403,7 @@ The common interface implemented by all DBMS-specific connection classes (`Mysql
398
403
 
399
404
  ### Driver Lazy Loading
400
405
 
401
- DBMS-specific drivers (`mysql2`, `tedious`, `pg`) are lazy-loaded within `DbConnFactory`. Therefore, import errors won't occur even if unused drivers are not installed.
406
+ DBMS-specific drivers (`mysql2`, `tedious`, `pg`) are lazy-loaded within `createDbConn()`. Therefore, import errors won't occur even if unused drivers are not installed.
402
407
 
403
408
  ### PooledDbConn close Behavior
404
409
 
@@ -0,0 +1,12 @@
1
+ import type { DbConn, DbConnConfig } from "./types/db-conn";
2
+ /**
3
+ * DB 연결 생성
4
+ *
5
+ * 커넥션 풀에서 연결을 획득하여 반환한다.
6
+ * 풀이 없는 경우 새로 생성한다.
7
+ *
8
+ * @param config - 데이터베이스 연결 설정
9
+ * @returns 풀링된 DB 연결 객체
10
+ */
11
+ export declare function createDbConn(config: DbConnConfig): Promise<DbConn>;
12
+ //# sourceMappingURL=create-db-conn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-db-conn.d.ts","sourceRoot":"","sources":["../src/create-db-conn.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwB5D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlE"}
@@ -0,0 +1,75 @@
1
+ import { createPool } from "generic-pool";
2
+ import { PooledDbConn } from "./pooled-db-conn.js";
3
+ import { MysqlDbConn } from "./connections/mysql-db-conn.js";
4
+ import { MssqlDbConn } from "./connections/mssql-db-conn.js";
5
+ import { PostgresqlDbConn } from "./connections/postgresql-db-conn.js";
6
+ const poolMap = /* @__PURE__ */ new Map();
7
+ const modules = {};
8
+ function createDbConn(config) {
9
+ const pool = getOrCreatePool(config);
10
+ return Promise.resolve(new PooledDbConn(pool, config));
11
+ }
12
+ function getOrCreatePool(config) {
13
+ const configKey = JSON.stringify(
14
+ config,
15
+ (_, value) => value != null && typeof value === "object" && !Array.isArray(value) ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b))) : value
16
+ );
17
+ if (!poolMap.has(configKey)) {
18
+ const pool = createPool(
19
+ {
20
+ create: async () => {
21
+ const conn = await createRawConnection(config);
22
+ await conn.connect();
23
+ return conn;
24
+ },
25
+ destroy: async (conn) => {
26
+ await conn.close();
27
+ },
28
+ validate: (conn) => {
29
+ return Promise.resolve(conn.isConnected);
30
+ }
31
+ },
32
+ {
33
+ min: config.pool?.min ?? 1,
34
+ max: config.pool?.max ?? 10,
35
+ acquireTimeoutMillis: config.pool?.acquireTimeoutMillis ?? 3e4,
36
+ idleTimeoutMillis: config.pool?.idleTimeoutMillis ?? 3e4,
37
+ testOnBorrow: true
38
+ // [중요] 빌려줄 때 validate 실행 여부
39
+ }
40
+ );
41
+ poolMap.set(configKey, pool);
42
+ }
43
+ return poolMap.get(configKey);
44
+ }
45
+ async function createRawConnection(config) {
46
+ if (config.dialect === "mysql") {
47
+ const mysql = await ensureModule("mysql");
48
+ return new MysqlDbConn(mysql, config);
49
+ } else if (config.dialect === "postgresql") {
50
+ const pg = await ensureModule("pg");
51
+ const pgCopyStreams = await ensureModule("pgCopyStreams");
52
+ return new PostgresqlDbConn(pg, pgCopyStreams.from, config);
53
+ } else {
54
+ const tedious = await ensureModule("tedious");
55
+ return new MssqlDbConn(tedious, config);
56
+ }
57
+ }
58
+ async function ensureModule(name) {
59
+ if (modules[name] == null) {
60
+ if (name === "mysql") {
61
+ modules.mysql = await import("mysql2/promise");
62
+ } else if (name === "pg") {
63
+ modules.pg = await import("pg");
64
+ } else if (name === "pgCopyStreams") {
65
+ modules.pgCopyStreams = await import("pg-copy-streams");
66
+ } else {
67
+ modules.tedious = await import("tedious");
68
+ }
69
+ }
70
+ return modules[name];
71
+ }
72
+ export {
73
+ createDbConn
74
+ };
75
+ //# sourceMappingURL=create-db-conn.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/create-db-conn.ts"],
4
+ "mappings": "AACA,SAAS,kBAAkB;AAE3B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AAUjC,MAAM,UAAU,oBAAI,IAA0B;AAG9C,MAAM,UAKF,CAAC;AAWE,SAAS,aAAa,QAAuC;AAElE,QAAM,OAAO,gBAAgB,MAAM;AAGnC,SAAO,QAAQ,QAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AACvD;AAEA,SAAS,gBAAgB,QAAoC;AAE3D,QAAM,YAAY,KAAK;AAAA,IAAU;AAAA,IAAQ,CAAC,GAAG,UAC3C,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC9D,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,IAC/E;AAAA,EACN;AAEA,MAAI,CAAC,QAAQ,IAAI,SAAS,GAAG;AAC3B,UAAM,OAAO;AAAA,MACX;AAAA,QACE,QAAQ,YAAY;AAClB,gBAAM,OAAO,MAAM,oBAAoB,MAAM;AAC7C,gBAAM,KAAK,QAAQ;AACnB,iBAAO;AAAA,QACT;AAAA,QACA,SAAS,OAAO,SAAS;AACvB,gBAAM,KAAK,MAAM;AAAA,QACnB;AAAA,QACA,UAAU,CAAC,SAAS;AAElB,iBAAO,QAAQ,QAAQ,KAAK,WAAW;AAAA,QACzC;AAAA,MACF;AAAA,MACA;AAAA,QACE,KAAK,OAAO,MAAM,OAAO;AAAA,QACzB,KAAK,OAAO,MAAM,OAAO;AAAA,QACzB,sBAAsB,OAAO,MAAM,wBAAwB;AAAA,QAC3D,mBAAmB,OAAO,MAAM,qBAAqB;AAAA,QACrD,cAAc;AAAA;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,IAAI,WAAW,IAAI;AAAA,EAC7B;AAEA,SAAO,QAAQ,IAAI,SAAS;AAC9B;AAEA,eAAe,oBAAoB,QAAuC;AACxE,MAAI,OAAO,YAAY,SAAS;AAC9B,UAAM,QAAQ,MAAM,aAAa,OAAO;AACxC,WAAO,IAAI,YAAY,OAAO,MAAM;AAAA,EACtC,WAAW,OAAO,YAAY,cAAc;AAC1C,UAAM,KAAK,MAAM,aAAa,IAAI;AAClC,UAAM,gBAAgB,MAAM,aAAa,eAAe;AACxD,WAAO,IAAI,iBAAiB,IAAI,cAAc,MAAM,MAAM;AAAA,EAC5D,OAAO;AAEL,UAAM,UAAU,MAAM,aAAa,SAAS;AAC5C,WAAO,IAAI,YAAY,SAAS,MAAM;AAAA,EACxC;AACF;AAEA,eAAe,aAA6C,MAAoD;AAC9G,MAAI,QAAQ,IAAI,KAAK,MAAM;AACzB,QAAI,SAAS,SAAS;AACpB,cAAQ,QAAQ,MAAM,OAAO,gBAAgB;AAAA,IAC/C,WAAW,SAAS,MAAM;AACxB,cAAQ,KAAK,MAAM,OAAO,IAAI;AAAA,IAChC,WAAW,SAAS,iBAAiB;AACnC,cAAQ,gBAAgB,MAAM,OAAO,iBAAiB;AAAA,IACxD,OAAO;AACL,cAAQ,UAAU,MAAM,OAAO,SAAS;AAAA,IAC1C;AAAA,EACF;AACA,SAAO,QAAQ,IAAI;AACrB;",
5
+ "names": []
6
+ }
@@ -1,12 +1,11 @@
1
- import type { DbContext, IsolationLevel } from "@simplysm/orm-common";
2
- import type { Type } from "@simplysm/core-common";
1
+ import { type DbContextDef, type DbContextInstance, type IsolationLevel } from "@simplysm/orm-common";
3
2
  import type { DbConnConfig } from "./types/db-conn";
4
3
  /**
5
- * SdOrm 옵션
4
+ * Orm 옵션
6
5
  *
7
6
  * DbConnConfig보다 우선 적용되는 DbContext 옵션
8
7
  */
9
- export interface SdOrmOptions {
8
+ export interface OrmOptions {
10
9
  /**
11
10
  * 데이터베이스 이름 (DbConnConfig의 database 대신 사용)
12
11
  */
@@ -17,18 +16,43 @@ export interface SdOrmOptions {
17
16
  schema?: string;
18
17
  }
19
18
  /**
20
- * Node.js ORM 클래스
19
+ * Orm 인스턴스 타입
21
20
  *
22
- * DbContext와 DB 연결을 관리하는 최상위 클래스입니다.
23
- * DbContext 타입과 연결 설정을 받아 트랜잭션을 관리합니다.
21
+ * createOrm에서 반환되는 객체의 타입
22
+ */
23
+ export interface Orm<TDef extends DbContextDef<any, any, any>> {
24
+ readonly dbContextDef: TDef;
25
+ readonly config: DbConnConfig;
26
+ readonly options?: OrmOptions;
27
+ /**
28
+ * 트랜잭션 내에서 콜백 실행
29
+ *
30
+ * @param callback - DB 연결 후 실행할 콜백
31
+ * @param isolationLevel - 트랜잭션 격리 수준
32
+ * @returns 콜백 결과
33
+ */
34
+ connect<R>(callback: (conn: DbContextInstance<TDef>) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>;
35
+ /**
36
+ * 트랜잭션 없이 콜백 실행
37
+ *
38
+ * @param callback - DB 연결 후 실행할 콜백
39
+ * @returns 콜백 결과
40
+ */
41
+ connectWithoutTransaction<R>(callback: (conn: DbContextInstance<TDef>) => Promise<R>): Promise<R>;
42
+ }
43
+ /**
44
+ * Node.js ORM 팩토리 함수
45
+ *
46
+ * DbContext와 DB 연결을 관리하는 인스턴스를 생성합니다.
47
+ * DbContext 정의와 연결 설정을 받아 트랜잭션을 관리합니다.
24
48
  *
25
49
  * @example
26
50
  * ```typescript
27
- * class MyDb extends DbContext {
28
- * readonly user = queryable(this, User);
29
- * }
51
+ * const MyDb = defineDbContext({
52
+ * user: (db) => queryable(db, User),
53
+ * });
30
54
  *
31
- * const orm = new SdOrm(MyDb, {
55
+ * const orm = createOrm(MyDb, {
32
56
  * dialect: "mysql",
33
57
  * host: "localhost",
34
58
  * port: 3306,
@@ -50,29 +74,5 @@ export interface SdOrmOptions {
50
74
  * });
51
75
  * ```
52
76
  */
53
- export declare class SdOrm<T extends DbContext> {
54
- readonly dbContextType: Type<T>;
55
- readonly config: DbConnConfig;
56
- readonly options?: SdOrmOptions | undefined;
57
- constructor(dbContextType: Type<T>, config: DbConnConfig, options?: SdOrmOptions | undefined);
58
- /**
59
- * 트랜잭션 내에서 콜백 실행
60
- *
61
- * @param callback - DB 연결 후 실행할 콜백
62
- * @param isolationLevel - 트랜잭션 격리 수준
63
- * @returns 콜백 결과
64
- */
65
- connect<R>(callback: (conn: T) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>;
66
- /**
67
- * 트랜잭션 없이 콜백 실행
68
- *
69
- * @param callback - DB 연결 후 실행할 콜백
70
- * @returns 콜백 결과
71
- */
72
- connectWithoutTransaction<R>(callback: (conn: T) => Promise<R>): Promise<R>;
73
- /**
74
- * DbContext 인스턴스 생성
75
- */
76
- private _createDbContext;
77
- }
78
- //# sourceMappingURL=sd-orm.d.ts.map
77
+ export declare function createOrm<TDef extends DbContextDef<any, any, any>>(dbContextDef: TDef, config: DbConnConfig, options?: OrmOptions): Orm<TDef>;
78
+ //# sourceMappingURL=create-orm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-orm.d.ts","sourceRoot":"","sources":["../src/create-orm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,GAAG,CAAC,IAAI,SAAS,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;IAE9B;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEjH;;;;;OAKG;IACH,yBAAyB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,SAAS,CAAC,IAAI,SAAS,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAChE,YAAY,EAAE,IAAI,EAClB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,UAAU,GACnB,GAAG,CAAC,IAAI,CAAC,CA8BX"}
@@ -0,0 +1,32 @@
1
+ import { createDbContext } from "@simplysm/orm-common";
2
+ import { NodeDbContextExecutor } from "./node-db-context-executor.js";
3
+ function createOrm(dbContextDef, config, options) {
4
+ function _createDbContext() {
5
+ const database = options?.database ?? ("database" in config ? config.database : void 0);
6
+ if (database == null || database === "") {
7
+ throw new Error("database is required");
8
+ }
9
+ const schema = options?.schema ?? ("schema" in config ? config.schema : void 0);
10
+ return createDbContext(dbContextDef, new NodeDbContextExecutor(config), {
11
+ database,
12
+ schema
13
+ });
14
+ }
15
+ return {
16
+ dbContextDef,
17
+ config,
18
+ options,
19
+ async connect(callback, isolationLevel) {
20
+ const db = _createDbContext();
21
+ return db.connect(async () => callback(db), isolationLevel);
22
+ },
23
+ async connectWithoutTransaction(callback) {
24
+ const db = _createDbContext();
25
+ return db.connectWithoutTransaction(async () => callback(db));
26
+ }
27
+ };
28
+ }
29
+ export {
30
+ createOrm
31
+ };
32
+ //# sourceMappingURL=create-orm.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/create-orm.ts"],
4
+ "mappings": "AAAA,SAAS,uBAAuF;AAEhG,SAAS,6BAA6B;AAiF/B,SAAS,UACd,cACA,QACA,SACW;AACX,WAAS,mBAA4C;AAEnD,UAAM,WAAW,SAAS,aAAa,cAAc,SAAS,OAAO,WAAW;AAChF,QAAI,YAAY,QAAQ,aAAa,IAAI;AACvC,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAGA,UAAM,SAAS,SAAS,WAAW,YAAY,SAAS,OAAO,SAAS;AAExE,WAAO,gBAAgB,cAAc,IAAI,sBAAsB,MAAM,GAAG;AAAA,MACtE;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,UAAU,gBAAiB;AACvC,YAAM,KAAK,iBAAiB;AAC5B,aAAO,GAAG,QAAQ,YAAY,SAAS,EAAE,GAAG,cAAc;AAAA,IAC5D;AAAA,IACA,MAAM,0BAA0B,UAAU;AACxC,YAAM,KAAK,iBAAiB;AAC5B,aAAO,GAAG,0BAA0B,YAAY,SAAS,EAAE,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;",
5
+ "names": []
6
+ }
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ export * from "./types/db-conn";
2
2
  export * from "./connections/mssql-db-conn";
3
3
  export * from "./connections/mysql-db-conn";
4
4
  export * from "./connections/postgresql-db-conn";
5
- export * from "./db-conn-factory";
5
+ export * from "./create-db-conn";
6
6
  export * from "./node-db-context-executor";
7
7
  export * from "./pooled-db-conn";
8
- export * from "./sd-orm";
8
+ export * from "./create-orm";
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;AAGhC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AAGjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;AAGhC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AAGjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ export * from "./types/db-conn.js";
2
2
  export * from "./connections/mssql-db-conn.js";
3
3
  export * from "./connections/mysql-db-conn.js";
4
4
  export * from "./connections/postgresql-db-conn.js";
5
- export * from "./db-conn-factory.js";
5
+ export * from "./create-db-conn.js";
6
6
  export * from "./node-db-context-executor.js";
7
7
  export * from "./pooled-db-conn.js";
8
- export * from "./sd-orm.js";
8
+ export * from "./create-orm.js";
9
9
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  import { SdError } from "@simplysm/core-common";
2
2
  import { createQueryBuilder, parseQueryResult } from "@simplysm/orm-common";
3
3
  import { DB_CONN_ERRORS, getDialectFromConfig } from "./types/db-conn.js";
4
- import { DbConnFactory } from "./db-conn-factory.js";
4
+ import { createDbConn } from "./create-db-conn.js";
5
5
  class NodeDbContextExecutor {
6
6
  constructor(_config) {
7
7
  this._config = _config;
@@ -15,7 +15,7 @@ class NodeDbContextExecutor {
15
15
  * 커넥션 풀에서 연결을 획득하고 연결 상태를 활성화한다.
16
16
  */
17
17
  async connect() {
18
- this._conn = await DbConnFactory.create(this._config);
18
+ this._conn = await createDbConn(this._config);
19
19
  await this._conn.connect();
20
20
  }
21
21
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/node-db-context-executor.ts"],
4
- "mappings": "AAAA,SAAS,eAAe;AAUxB,SAAS,oBAAoB,wBAAwB;AAErD,SAAS,gBAAgB,4BAA4B;AACrD,SAAS,qBAAqB;AAOvB,MAAM,sBAAmD;AAAA,EAI9D,YAA6B,SAAuB;AAAvB;AAC3B,SAAK,WAAW,qBAAqB,OAAO;AAAA,EAC9C;AAAA,EALQ;AAAA,EACS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWjB,MAAM,UAAyB;AAC7B,SAAK,QAAQ,MAAM,cAAc,OAAO,KAAK,OAAO;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAuB;AAC3B,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,MAAM;AACjB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,gBAAgD;AACrE,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,iBAAiB,cAAc;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAmC;AACvC,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,kBAAkB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAqC;AACzC,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,oBAAoB;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAoB,OAAe,QAA0C;AACjF,UAAM,OAAO,KAAK,aAAa;AAC/B,WAAO,KAAK,oBAAoB,OAAO,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,WAAmB,aAAyC,SAAsC;AACjH,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,WAAW,WAAW,aAAa,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YAA4B,MAAkB,aAA0D;AAC5G,UAAM,OAAO,KAAK,aAAa;AAE/B,UAAM,UAAU,mBAAmB,KAAK,QAAQ;AAIhD,QAAI,eAAe,QAAQ,YAAY,MAAM,CAAC,SAAS,QAAQ,IAAI,GAAG;AACpE,YAAM,cAAc,KAAK,IAAI,CAAC,QAAQ,QAAQ,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI;AACvE,YAAM,KAAK,QAAQ,CAAC,WAAW,CAAC;AAChC,aAAO,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,IAC1B;AAGA,UAAM,UAAiB,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,OAAO,cAAc,CAAC;AAC5B,YAAM,cAAc,QAAQ,MAAM,GAAG;AAErC,YAAM,aAAa,MAAM,KAAK,QAAQ,CAAC,YAAY,GAAG,CAAC;AAGvD,YAAM,kBACJ,YAAY,kBAAkB,OAAO,WAAW,YAAY,cAAc,IAAI,WAAW,CAAC;AAE5F,UAAI,QAAQ,MAAM;AAChB,cAAM,SAAS,MAAM,iBAAoB,iBAA8C,IAAI;AAC3F,gBAAQ,KAAK,UAAU,CAAC,CAAC;AAAA,MAC3B,OAAO;AACL,gBAAQ,KAAK,eAAsB;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAuB;AAC7B,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,QAAQ,eAAe,aAAa;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AACF;",
4
+ "mappings": "AAAA,SAAS,eAAe;AAUxB,SAAS,oBAAoB,wBAAwB;AAErD,SAAS,gBAAgB,4BAA4B;AACrD,SAAS,oBAAoB;AAOtB,MAAM,sBAAmD;AAAA,EAI9D,YAA6B,SAAuB;AAAvB;AAC3B,SAAK,WAAW,qBAAqB,OAAO;AAAA,EAC9C;AAAA,EALQ;AAAA,EACS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWjB,MAAM,UAAyB;AAC7B,SAAK,QAAQ,MAAM,aAAa,KAAK,OAAO;AAC5C,UAAM,KAAK,MAAM,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAuB;AAC3B,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,MAAM;AACjB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,gBAAgD;AACrE,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,iBAAiB,cAAc;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAmC;AACvC,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,kBAAkB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAqC;AACzC,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,oBAAoB;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAoB,OAAe,QAA0C;AACjF,UAAM,OAAO,KAAK,aAAa;AAC/B,WAAO,KAAK,oBAAoB,OAAO,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,WAAmB,aAAyC,SAAsC;AACjH,UAAM,OAAO,KAAK,aAAa;AAC/B,UAAM,KAAK,WAAW,WAAW,aAAa,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YAA4B,MAAkB,aAA0D;AAC5G,UAAM,OAAO,KAAK,aAAa;AAE/B,UAAM,UAAU,mBAAmB,KAAK,QAAQ;AAIhD,QAAI,eAAe,QAAQ,YAAY,MAAM,CAAC,SAAS,QAAQ,IAAI,GAAG;AACpE,YAAM,cAAc,KAAK,IAAI,CAAC,QAAQ,QAAQ,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI;AACvE,YAAM,KAAK,QAAQ,CAAC,WAAW,CAAC;AAChC,aAAO,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,IAC1B;AAGA,UAAM,UAAiB,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,OAAO,cAAc,CAAC;AAC5B,YAAM,cAAc,QAAQ,MAAM,GAAG;AAErC,YAAM,aAAa,MAAM,KAAK,QAAQ,CAAC,YAAY,GAAG,CAAC;AAGvD,YAAM,kBACJ,YAAY,kBAAkB,OAAO,WAAW,YAAY,cAAc,IAAI,WAAW,CAAC;AAE5F,UAAI,QAAQ,MAAM;AAChB,cAAM,SAAS,MAAM,iBAAoB,iBAA8C,IAAI;AAC3F,gBAAQ,KAAK,UAAU,CAAC,CAAC;AAAA,MAC3B,OAAO;AACL,gBAAQ,KAAK,eAAsB;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAuB;AAC7B,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,QAAQ,eAAe,aAAa;AAAA,IAChD;AACA,WAAO,KAAK;AAAA,EACd;AACF;",
5
5
  "names": []
6
6
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplysm/orm-node",
3
3
  "sideEffects": false,
4
- "version": "13.0.0-beta.51",
4
+ "version": "13.0.1",
5
5
  "description": "심플리즘 패키지 - ORM 모듈 (node)",
6
6
  "author": "김석래",
7
7
  "repository": {
@@ -20,8 +20,8 @@
20
20
  "dependencies": {
21
21
  "consola": "^3.4.2",
22
22
  "generic-pool": "^3.9.0",
23
- "@simplysm/core-common": "13.0.0-beta.51",
24
- "@simplysm/orm-common": "13.0.0-beta.51"
23
+ "@simplysm/core-common": "13.0.1",
24
+ "@simplysm/orm-common": "13.0.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/pg": "^8.16.0",
@@ -0,0 +1,111 @@
1
+ import type { Pool } from "generic-pool";
2
+ import { createPool } from "generic-pool";
3
+ import type { DbConn, DbConnConfig } from "./types/db-conn";
4
+ import { PooledDbConn } from "./pooled-db-conn";
5
+ import { MysqlDbConn } from "./connections/mysql-db-conn";
6
+ import { MssqlDbConn } from "./connections/mssql-db-conn";
7
+ import { PostgresqlDbConn } from "./connections/postgresql-db-conn";
8
+
9
+ /**
10
+ * DB 연결 팩토리
11
+ *
12
+ * 데이터베이스 연결 인스턴스를 생성하고 풀링을 관리한다.
13
+ * MSSQL, MySQL, PostgreSQL을 지원한다.
14
+ */
15
+
16
+ // 설정별 커넥션 풀 캐싱
17
+ const poolMap = new Map<string, Pool<DbConn>>();
18
+
19
+ // 지연 로딩 모듈 캐시
20
+ const modules: {
21
+ tedious?: typeof import("tedious");
22
+ mysql?: typeof import("mysql2/promise");
23
+ pg?: typeof import("pg");
24
+ pgCopyStreams?: typeof import("pg-copy-streams");
25
+ } = {};
26
+
27
+ /**
28
+ * DB 연결 생성
29
+ *
30
+ * 커넥션 풀에서 연결을 획득하여 반환한다.
31
+ * 풀이 없는 경우 새로 생성한다.
32
+ *
33
+ * @param config - 데이터베이스 연결 설정
34
+ * @returns 풀링된 DB 연결 객체
35
+ */
36
+ export function createDbConn(config: DbConnConfig): Promise<DbConn> {
37
+ // 1. 풀 가져오기 (없으면 생성)
38
+ const pool = getOrCreatePool(config);
39
+
40
+ // 2. 래퍼 객체 반환
41
+ return Promise.resolve(new PooledDbConn(pool, config));
42
+ }
43
+
44
+ function getOrCreatePool(config: DbConnConfig): Pool<DbConn> {
45
+ // 객체를 키로 쓰기 위해 문자열 변환 (중첩 객체도 정렬하여 동일 설정의 일관된 키 보장)
46
+ const configKey = JSON.stringify(config, (_, value: unknown) =>
47
+ value != null && typeof value === "object" && !Array.isArray(value)
48
+ ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)))
49
+ : value,
50
+ );
51
+
52
+ if (!poolMap.has(configKey)) {
53
+ const pool = createPool<DbConn>(
54
+ {
55
+ create: async () => {
56
+ const conn = await createRawConnection(config);
57
+ await conn.connect();
58
+ return conn;
59
+ },
60
+ destroy: async (conn) => {
61
+ await conn.close(); // 풀에서 제거될 때 실제 연결 종료
62
+ },
63
+ validate: (conn) => {
64
+ // 획득 시 연결 상태 확인 (끊겨있으면 Pool이 폐기하고 새로 만듦)
65
+ return Promise.resolve(conn.isConnected);
66
+ },
67
+ },
68
+ {
69
+ min: config.pool?.min ?? 1,
70
+ max: config.pool?.max ?? 10,
71
+ acquireTimeoutMillis: config.pool?.acquireTimeoutMillis ?? 30000,
72
+ idleTimeoutMillis: config.pool?.idleTimeoutMillis ?? 30000,
73
+ testOnBorrow: true, // [중요] 빌려줄 때 validate 실행 여부
74
+ },
75
+ );
76
+
77
+ poolMap.set(configKey, pool);
78
+ }
79
+
80
+ return poolMap.get(configKey)!;
81
+ }
82
+
83
+ async function createRawConnection(config: DbConnConfig): Promise<DbConn> {
84
+ if (config.dialect === "mysql") {
85
+ const mysql = await ensureModule("mysql");
86
+ return new MysqlDbConn(mysql, config);
87
+ } else if (config.dialect === "postgresql") {
88
+ const pg = await ensureModule("pg");
89
+ const pgCopyStreams = await ensureModule("pgCopyStreams");
90
+ return new PostgresqlDbConn(pg, pgCopyStreams.from, config);
91
+ } else {
92
+ // mssql, mssql-azure
93
+ const tedious = await ensureModule("tedious");
94
+ return new MssqlDbConn(tedious, config);
95
+ }
96
+ }
97
+
98
+ async function ensureModule<K extends keyof typeof modules>(name: K): Promise<NonNullable<(typeof modules)[K]>> {
99
+ if (modules[name] == null) {
100
+ if (name === "mysql") {
101
+ modules.mysql = await import("mysql2/promise");
102
+ } else if (name === "pg") {
103
+ modules.pg = await import("pg");
104
+ } else if (name === "pgCopyStreams") {
105
+ modules.pgCopyStreams = await import("pg-copy-streams");
106
+ } else {
107
+ modules.tedious = await import("tedious");
108
+ }
109
+ }
110
+ return modules[name]!;
111
+ }
@@ -0,0 +1,118 @@
1
+ import { createDbContext, type DbContextDef, type DbContextInstance, type IsolationLevel } from "@simplysm/orm-common";
2
+ import type { DbConnConfig } from "./types/db-conn";
3
+ import { NodeDbContextExecutor } from "./node-db-context-executor";
4
+
5
+ /**
6
+ * Orm 옵션
7
+ *
8
+ * DbConnConfig보다 우선 적용되는 DbContext 옵션
9
+ */
10
+ export interface OrmOptions {
11
+ /**
12
+ * 데이터베이스 이름 (DbConnConfig의 database 대신 사용)
13
+ */
14
+ database?: string;
15
+
16
+ /**
17
+ * 스키마 이름 (MSSQL: dbo, PostgreSQL: public)
18
+ */
19
+ schema?: string;
20
+ }
21
+
22
+ /**
23
+ * Orm 인스턴스 타입
24
+ *
25
+ * createOrm에서 반환되는 객체의 타입
26
+ */
27
+ export interface Orm<TDef extends DbContextDef<any, any, any>> {
28
+ readonly dbContextDef: TDef;
29
+ readonly config: DbConnConfig;
30
+ readonly options?: OrmOptions;
31
+
32
+ /**
33
+ * 트랜잭션 내에서 콜백 실행
34
+ *
35
+ * @param callback - DB 연결 후 실행할 콜백
36
+ * @param isolationLevel - 트랜잭션 격리 수준
37
+ * @returns 콜백 결과
38
+ */
39
+ connect<R>(callback: (conn: DbContextInstance<TDef>) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>;
40
+
41
+ /**
42
+ * 트랜잭션 없이 콜백 실행
43
+ *
44
+ * @param callback - DB 연결 후 실행할 콜백
45
+ * @returns 콜백 결과
46
+ */
47
+ connectWithoutTransaction<R>(callback: (conn: DbContextInstance<TDef>) => Promise<R>): Promise<R>;
48
+ }
49
+
50
+ /**
51
+ * Node.js ORM 팩토리 함수
52
+ *
53
+ * DbContext와 DB 연결을 관리하는 인스턴스를 생성합니다.
54
+ * DbContext 정의와 연결 설정을 받아 트랜잭션을 관리합니다.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const MyDb = defineDbContext({
59
+ * user: (db) => queryable(db, User),
60
+ * });
61
+ *
62
+ * const orm = createOrm(MyDb, {
63
+ * dialect: "mysql",
64
+ * host: "localhost",
65
+ * port: 3306,
66
+ * username: "root",
67
+ * password: "password",
68
+ * database: "mydb",
69
+ * });
70
+ *
71
+ * // 트랜잭션 내에서 실행
72
+ * await orm.connect(async (db) => {
73
+ * const users = await db.user().result();
74
+ * return users;
75
+ * });
76
+ *
77
+ * // 트랜잭션 없이 실행
78
+ * await orm.connectWithoutTransaction(async (db) => {
79
+ * const users = await db.user().result();
80
+ * return users;
81
+ * });
82
+ * ```
83
+ */
84
+ export function createOrm<TDef extends DbContextDef<any, any, any>>(
85
+ dbContextDef: TDef,
86
+ config: DbConnConfig,
87
+ options?: OrmOptions,
88
+ ): Orm<TDef> {
89
+ function _createDbContext(): DbContextInstance<TDef> {
90
+ // database는 options에서 우선, 없으면 config에서
91
+ const database = options?.database ?? ("database" in config ? config.database : undefined);
92
+ if (database == null || database === "") {
93
+ throw new Error("database is required");
94
+ }
95
+
96
+ // schema는 options에서 우선, 없으면 config에서
97
+ const schema = options?.schema ?? ("schema" in config ? config.schema : undefined);
98
+
99
+ return createDbContext(dbContextDef, new NodeDbContextExecutor(config), {
100
+ database,
101
+ schema,
102
+ });
103
+ }
104
+
105
+ return {
106
+ dbContextDef,
107
+ config,
108
+ options,
109
+ async connect(callback, isolationLevel?) {
110
+ const db = _createDbContext();
111
+ return db.connect(async () => callback(db), isolationLevel);
112
+ },
113
+ async connectWithoutTransaction(callback) {
114
+ const db = _createDbContext();
115
+ return db.connectWithoutTransaction(async () => callback(db));
116
+ },
117
+ };
118
+ }
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ export * from "./connections/mysql-db-conn";
7
7
  export * from "./connections/postgresql-db-conn";
8
8
 
9
9
  // Core
10
- export * from "./db-conn-factory";
10
+ export * from "./create-db-conn";
11
11
  export * from "./node-db-context-executor";
12
12
  export * from "./pooled-db-conn";
13
- export * from "./sd-orm";
13
+ export * from "./create-orm";
@@ -11,7 +11,7 @@ import type {
11
11
  import { createQueryBuilder, parseQueryResult } from "@simplysm/orm-common";
12
12
  import type { DbConn, DbConnConfig } from "./types/db-conn";
13
13
  import { DB_CONN_ERRORS, getDialectFromConfig } from "./types/db-conn";
14
- import { DbConnFactory } from "./db-conn-factory";
14
+ import { createDbConn } from "./create-db-conn";
15
15
 
16
16
  /**
17
17
  * Node.js 환경용 DbContextExecutor
@@ -32,7 +32,7 @@ export class NodeDbContextExecutor implements DbContextExecutor {
32
32
  * 커넥션 풀에서 연결을 획득하고 연결 상태를 활성화한다.
33
33
  */
34
34
  async connect(): Promise<void> {
35
- this._conn = await DbConnFactory.create(this._config);
35
+ this._conn = await createDbConn(this._config);
36
36
  await this._conn.connect();
37
37
  }
38
38
 
@@ -1,25 +0,0 @@
1
- import type { DbConn, DbConnConfig } from "./types/db-conn";
2
- /**
3
- * DB 연결 팩토리
4
- *
5
- * 데이터베이스 연결 인스턴스를 생성하고 풀링을 관리한다.
6
- * MSSQL, MySQL, PostgreSQL을 지원한다.
7
- */
8
- export declare class DbConnFactory {
9
- private static readonly _poolMap;
10
- /**
11
- * DB 연결 생성
12
- *
13
- * 커넥션 풀에서 연결을 획득하여 반환한다.
14
- * 풀이 없는 경우 새로 생성한다.
15
- *
16
- * @param config - 데이터베이스 연결 설정
17
- * @returns 풀링된 DB 연결 객체
18
- */
19
- static create(config: DbConnConfig): Promise<DbConn>;
20
- private static _getOrCreatePool;
21
- private static _createRawConnection;
22
- private static readonly _modules;
23
- private static _ensureModule;
24
- }
25
- //# sourceMappingURL=db-conn-factory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"db-conn-factory.d.ts","sourceRoot":"","sources":["../src/db-conn-factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM5D;;;;;GAKG;AACH,qBAAa,aAAa;IAExB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAEnE;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQpD,OAAO,CAAC,MAAM,CAAC,gBAAgB;mBAuCV,oBAAoB;IAgBzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAKzB;mBAEc,aAAa;CAgBnC"}
@@ -1,88 +0,0 @@
1
- import { createPool } from "generic-pool";
2
- import { PooledDbConn } from "./pooled-db-conn.js";
3
- import { MysqlDbConn } from "./connections/mysql-db-conn.js";
4
- import { MssqlDbConn } from "./connections/mssql-db-conn.js";
5
- import { PostgresqlDbConn } from "./connections/postgresql-db-conn.js";
6
- class DbConnFactory {
7
- // 설정별 커넥션 풀 캐싱
8
- static _poolMap = /* @__PURE__ */ new Map();
9
- /**
10
- * DB 연결 생성
11
- *
12
- * 커넥션 풀에서 연결을 획득하여 반환한다.
13
- * 풀이 없는 경우 새로 생성한다.
14
- *
15
- * @param config - 데이터베이스 연결 설정
16
- * @returns 풀링된 DB 연결 객체
17
- */
18
- static create(config) {
19
- const pool = this._getOrCreatePool(config);
20
- return Promise.resolve(new PooledDbConn(pool, config));
21
- }
22
- static _getOrCreatePool(config) {
23
- const configKey = JSON.stringify(
24
- config,
25
- (_, value) => value != null && typeof value === "object" && !Array.isArray(value) ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b))) : value
26
- );
27
- if (!this._poolMap.has(configKey)) {
28
- const pool = createPool(
29
- {
30
- create: async () => {
31
- const conn = await this._createRawConnection(config);
32
- await conn.connect();
33
- return conn;
34
- },
35
- destroy: async (conn) => {
36
- await conn.close();
37
- },
38
- validate: (conn) => {
39
- return Promise.resolve(conn.isConnected);
40
- }
41
- },
42
- {
43
- min: config.pool?.min ?? 1,
44
- max: config.pool?.max ?? 10,
45
- acquireTimeoutMillis: config.pool?.acquireTimeoutMillis ?? 3e4,
46
- idleTimeoutMillis: config.pool?.idleTimeoutMillis ?? 3e4,
47
- testOnBorrow: true
48
- // [중요] 빌려줄 때 validate 실행 여부
49
- }
50
- );
51
- this._poolMap.set(configKey, pool);
52
- }
53
- return this._poolMap.get(configKey);
54
- }
55
- static async _createRawConnection(config) {
56
- if (config.dialect === "mysql") {
57
- const mysql = await this._ensureModule("mysql");
58
- return new MysqlDbConn(mysql, config);
59
- } else if (config.dialect === "postgresql") {
60
- const pg = await this._ensureModule("pg");
61
- const pgCopyStreams = await this._ensureModule("pgCopyStreams");
62
- return new PostgresqlDbConn(pg, pgCopyStreams.from, config);
63
- } else {
64
- const tedious = await this._ensureModule("tedious");
65
- return new MssqlDbConn(tedious, config);
66
- }
67
- }
68
- // 지연 로딩 모듈 캐시
69
- static _modules = {};
70
- static async _ensureModule(name) {
71
- if (this._modules[name] == null) {
72
- if (name === "mysql") {
73
- this._modules.mysql = await import("mysql2/promise");
74
- } else if (name === "pg") {
75
- this._modules.pg = await import("pg");
76
- } else if (name === "pgCopyStreams") {
77
- this._modules.pgCopyStreams = await import("pg-copy-streams");
78
- } else {
79
- this._modules.tedious = await import("tedious");
80
- }
81
- }
82
- return this._modules[name];
83
- }
84
- }
85
- export {
86
- DbConnFactory
87
- };
88
- //# sourceMappingURL=db-conn-factory.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/db-conn-factory.ts"],
4
- "mappings": "AACA,SAAS,kBAAkB;AAE3B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AAQ1B,MAAM,cAAc;AAAA;AAAA,EAEzB,OAAwB,WAAW,oBAAI,IAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWjE,OAAO,OAAO,QAAuC;AAEnD,UAAM,OAAO,KAAK,iBAAiB,MAAM;AAGzC,WAAO,QAAQ,QAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,EACvD;AAAA,EAEA,OAAe,iBAAiB,QAAoC;AAElE,UAAM,YAAY,KAAK;AAAA,MAAU;AAAA,MAAQ,CAAC,GAAG,UAC3C,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC9D,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,IAC/E;AAAA,IACN;AAEA,QAAI,CAAC,KAAK,SAAS,IAAI,SAAS,GAAG;AACjC,YAAM,OAAO;AAAA,QACX;AAAA,UACE,QAAQ,YAAY;AAClB,kBAAM,OAAO,MAAM,KAAK,qBAAqB,MAAM;AACnD,kBAAM,KAAK,QAAQ;AACnB,mBAAO;AAAA,UACT;AAAA,UACA,SAAS,OAAO,SAAS;AACvB,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,UACA,UAAU,CAAC,SAAS;AAElB,mBAAO,QAAQ,QAAQ,KAAK,WAAW;AAAA,UACzC;AAAA,QACF;AAAA,QACA;AAAA,UACE,KAAK,OAAO,MAAM,OAAO;AAAA,UACzB,KAAK,OAAO,MAAM,OAAO;AAAA,UACzB,sBAAsB,OAAO,MAAM,wBAAwB;AAAA,UAC3D,mBAAmB,OAAO,MAAM,qBAAqB;AAAA,UACrD,cAAc;AAAA;AAAA,QAChB;AAAA,MACF;AAEA,WAAK,SAAS,IAAI,WAAW,IAAI;AAAA,IACnC;AAEA,WAAO,KAAK,SAAS,IAAI,SAAS;AAAA,EACpC;AAAA,EAEA,aAAqB,qBAAqB,QAAuC;AAC/E,QAAI,OAAO,YAAY,SAAS;AAC9B,YAAM,QAAQ,MAAM,KAAK,cAAc,OAAO;AAC9C,aAAO,IAAI,YAAY,OAAO,MAAM;AAAA,IACtC,WAAW,OAAO,YAAY,cAAc;AAC1C,YAAM,KAAK,MAAM,KAAK,cAAc,IAAI;AACxC,YAAM,gBAAgB,MAAM,KAAK,cAAc,eAAe;AAC9D,aAAO,IAAI,iBAAiB,IAAI,cAAc,MAAM,MAAM;AAAA,IAC5D,OAAO;AAEL,YAAM,UAAU,MAAM,KAAK,cAAc,SAAS;AAClD,aAAO,IAAI,YAAY,SAAS,MAAM;AAAA,IACxC;AAAA,EACF;AAAA;AAAA,EAGA,OAAwB,WAKpB,CAAC;AAAA,EAEL,aAAqB,cACnB,MACiD;AACjD,QAAI,KAAK,SAAS,IAAI,KAAK,MAAM;AAC/B,UAAI,SAAS,SAAS;AACpB,aAAK,SAAS,QAAQ,MAAM,OAAO,gBAAgB;AAAA,MACrD,WAAW,SAAS,MAAM;AACxB,aAAK,SAAS,KAAK,MAAM,OAAO,IAAI;AAAA,MACtC,WAAW,SAAS,iBAAiB;AACnC,aAAK,SAAS,gBAAgB,MAAM,OAAO,iBAAiB;AAAA,MAC9D,OAAO;AACL,aAAK,SAAS,UAAU,MAAM,OAAO,SAAS;AAAA,MAChD;AAAA,IACF;AACA,WAAO,KAAK,SAAS,IAAI;AAAA,EAC3B;AACF;",
5
- "names": []
6
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"sd-orm.d.ts","sourceRoot":"","sources":["../src/sd-orm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,KAAK,CAAC,CAAC,SAAS,SAAS;IAElC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,YAAY;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY;gBAFtB,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,EACtB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,YAAY,YAAA;IAGjC;;;;;;OAMG;IACG,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAKhG;;;;;OAKG;IACG,yBAAyB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAKjF;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAYzB"}
package/dist/sd-orm.js DELETED
@@ -1,44 +0,0 @@
1
- import { NodeDbContextExecutor } from "./node-db-context-executor.js";
2
- class SdOrm {
3
- constructor(dbContextType, config, options) {
4
- this.dbContextType = dbContextType;
5
- this.config = config;
6
- this.options = options;
7
- }
8
- /**
9
- * 트랜잭션 내에서 콜백 실행
10
- *
11
- * @param callback - DB 연결 후 실행할 콜백
12
- * @param isolationLevel - 트랜잭션 격리 수준
13
- * @returns 콜백 결과
14
- */
15
- async connect(callback, isolationLevel) {
16
- const db = this._createDbContext();
17
- return db.connect(async () => callback(db), isolationLevel);
18
- }
19
- /**
20
- * 트랜잭션 없이 콜백 실행
21
- *
22
- * @param callback - DB 연결 후 실행할 콜백
23
- * @returns 콜백 결과
24
- */
25
- async connectWithoutTransaction(callback) {
26
- const db = this._createDbContext();
27
- return db.connectWithoutTransaction(async () => callback(db));
28
- }
29
- /**
30
- * DbContext 인스턴스 생성
31
- */
32
- _createDbContext() {
33
- const database = this.options?.database ?? ("database" in this.config ? this.config.database : void 0);
34
- const schema = this.options?.schema ?? ("schema" in this.config ? this.config.schema : void 0);
35
- return new this.dbContextType(new NodeDbContextExecutor(this.config), {
36
- database,
37
- schema
38
- });
39
- }
40
- }
41
- export {
42
- SdOrm
43
- };
44
- //# sourceMappingURL=sd-orm.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/sd-orm.ts"],
4
- "mappings": "AAGA,SAAS,6BAA6B;AAqD/B,MAAM,MAA2B;AAAA,EACtC,YACW,eACA,QACA,SACT;AAHS;AACA;AACA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASH,MAAM,QAAW,UAAmC,gBAA6C;AAC/F,UAAM,KAAK,KAAK,iBAAiB;AACjC,WAAO,GAAG,QAAQ,YAAY,SAAS,EAAE,GAAG,cAAc;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,0BAA6B,UAA+C;AAChF,UAAM,KAAK,KAAK,iBAAiB;AACjC,WAAO,GAAG,0BAA0B,YAAY,SAAS,EAAE,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAsB;AAE5B,UAAM,WAAW,KAAK,SAAS,aAAa,cAAc,KAAK,SAAS,KAAK,OAAO,WAAW;AAG/F,UAAM,SAAS,KAAK,SAAS,WAAW,YAAY,KAAK,SAAS,KAAK,OAAO,SAAS;AAEvF,WAAO,IAAI,KAAK,cAAc,IAAI,sBAAsB,KAAK,MAAM,GAAG;AAAA,MACpE;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
5
- "names": []
6
- }
@@ -1,114 +0,0 @@
1
- import type { Pool } from "generic-pool";
2
- import { createPool } from "generic-pool";
3
- import type { DbConn, DbConnConfig } from "./types/db-conn";
4
- import { PooledDbConn } from "./pooled-db-conn";
5
- import { MysqlDbConn } from "./connections/mysql-db-conn";
6
- import { MssqlDbConn } from "./connections/mssql-db-conn";
7
- import { PostgresqlDbConn } from "./connections/postgresql-db-conn";
8
-
9
- /**
10
- * DB 연결 팩토리
11
- *
12
- * 데이터베이스 연결 인스턴스를 생성하고 풀링을 관리한다.
13
- * MSSQL, MySQL, PostgreSQL을 지원한다.
14
- */
15
- export class DbConnFactory {
16
- // 설정별 커넥션 풀 캐싱
17
- private static readonly _poolMap = new Map<string, Pool<DbConn>>();
18
-
19
- /**
20
- * DB 연결 생성
21
- *
22
- * 커넥션 풀에서 연결을 획득하여 반환한다.
23
- * 풀이 없는 경우 새로 생성한다.
24
- *
25
- * @param config - 데이터베이스 연결 설정
26
- * @returns 풀링된 DB 연결 객체
27
- */
28
- static create(config: DbConnConfig): Promise<DbConn> {
29
- // 1. 풀 가져오기 (없으면 생성)
30
- const pool = this._getOrCreatePool(config);
31
-
32
- // 2. 래퍼 객체 반환
33
- return Promise.resolve(new PooledDbConn(pool, config));
34
- }
35
-
36
- private static _getOrCreatePool(config: DbConnConfig): Pool<DbConn> {
37
- // 객체를 키로 쓰기 위해 문자열 변환 (중첩 객체도 정렬하여 동일 설정의 일관된 키 보장)
38
- const configKey = JSON.stringify(config, (_, value: unknown) =>
39
- value != null && typeof value === "object" && !Array.isArray(value)
40
- ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)))
41
- : value,
42
- );
43
-
44
- if (!this._poolMap.has(configKey)) {
45
- const pool = createPool<DbConn>(
46
- {
47
- create: async () => {
48
- const conn = await this._createRawConnection(config);
49
- await conn.connect();
50
- return conn;
51
- },
52
- destroy: async (conn) => {
53
- await conn.close(); // 풀에서 제거될 때 실제 연결 종료
54
- },
55
- validate: (conn) => {
56
- // 획득 시 연결 상태 확인 (끊겨있으면 Pool이 폐기하고 새로 만듦)
57
- return Promise.resolve(conn.isConnected);
58
- },
59
- },
60
- {
61
- min: config.pool?.min ?? 1,
62
- max: config.pool?.max ?? 10,
63
- acquireTimeoutMillis: config.pool?.acquireTimeoutMillis ?? 30000,
64
- idleTimeoutMillis: config.pool?.idleTimeoutMillis ?? 30000,
65
- testOnBorrow: true, // [중요] 빌려줄 때 validate 실행 여부
66
- },
67
- );
68
-
69
- this._poolMap.set(configKey, pool);
70
- }
71
-
72
- return this._poolMap.get(configKey)!;
73
- }
74
-
75
- private static async _createRawConnection(config: DbConnConfig): Promise<DbConn> {
76
- if (config.dialect === "mysql") {
77
- const mysql = await this._ensureModule("mysql");
78
- return new MysqlDbConn(mysql, config);
79
- } else if (config.dialect === "postgresql") {
80
- const pg = await this._ensureModule("pg");
81
- const pgCopyStreams = await this._ensureModule("pgCopyStreams");
82
- return new PostgresqlDbConn(pg, pgCopyStreams.from, config);
83
- } else {
84
- // mssql, mssql-azure
85
- const tedious = await this._ensureModule("tedious");
86
- return new MssqlDbConn(tedious, config);
87
- }
88
- }
89
-
90
- // 지연 로딩 모듈 캐시
91
- private static readonly _modules: {
92
- tedious?: typeof import("tedious");
93
- mysql?: typeof import("mysql2/promise");
94
- pg?: typeof import("pg");
95
- pgCopyStreams?: typeof import("pg-copy-streams");
96
- } = {};
97
-
98
- private static async _ensureModule<K extends keyof typeof this._modules>(
99
- name: K,
100
- ): Promise<NonNullable<(typeof this._modules)[K]>> {
101
- if (this._modules[name] == null) {
102
- if (name === "mysql") {
103
- this._modules.mysql = await import("mysql2/promise");
104
- } else if (name === "pg") {
105
- this._modules.pg = await import("pg");
106
- } else if (name === "pgCopyStreams") {
107
- this._modules.pgCopyStreams = await import("pg-copy-streams");
108
- } else {
109
- this._modules.tedious = await import("tedious");
110
- }
111
- }
112
- return this._modules[name]!;
113
- }
114
- }
package/src/sd-orm.ts DELETED
@@ -1,102 +0,0 @@
1
- import type { DbContext, IsolationLevel } from "@simplysm/orm-common";
2
- import type { Type } from "@simplysm/core-common";
3
- import type { DbConnConfig } from "./types/db-conn";
4
- import { NodeDbContextExecutor } from "./node-db-context-executor";
5
-
6
- /**
7
- * SdOrm 옵션
8
- *
9
- * DbConnConfig보다 우선 적용되는 DbContext 옵션
10
- */
11
- export interface SdOrmOptions {
12
- /**
13
- * 데이터베이스 이름 (DbConnConfig의 database 대신 사용)
14
- */
15
- database?: string;
16
-
17
- /**
18
- * 스키마 이름 (MSSQL: dbo, PostgreSQL: public)
19
- */
20
- schema?: string;
21
- }
22
-
23
- /**
24
- * Node.js ORM 클래스
25
- *
26
- * DbContext와 DB 연결을 관리하는 최상위 클래스입니다.
27
- * DbContext 타입과 연결 설정을 받아 트랜잭션을 관리합니다.
28
- *
29
- * @example
30
- * ```typescript
31
- * class MyDb extends DbContext {
32
- * readonly user = queryable(this, User);
33
- * }
34
- *
35
- * const orm = new SdOrm(MyDb, {
36
- * dialect: "mysql",
37
- * host: "localhost",
38
- * port: 3306,
39
- * username: "root",
40
- * password: "password",
41
- * database: "mydb",
42
- * });
43
- *
44
- * // 트랜잭션 내에서 실행
45
- * await orm.connect(async (db) => {
46
- * const users = await db.user().result();
47
- * return users;
48
- * });
49
- *
50
- * // 트랜잭션 없이 실행
51
- * await orm.connectWithoutTransaction(async (db) => {
52
- * const users = await db.user().result();
53
- * return users;
54
- * });
55
- * ```
56
- */
57
- export class SdOrm<T extends DbContext> {
58
- constructor(
59
- readonly dbContextType: Type<T>,
60
- readonly config: DbConnConfig,
61
- readonly options?: SdOrmOptions,
62
- ) {}
63
-
64
- /**
65
- * 트랜잭션 내에서 콜백 실행
66
- *
67
- * @param callback - DB 연결 후 실행할 콜백
68
- * @param isolationLevel - 트랜잭션 격리 수준
69
- * @returns 콜백 결과
70
- */
71
- async connect<R>(callback: (conn: T) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R> {
72
- const db = this._createDbContext();
73
- return db.connect(async () => callback(db), isolationLevel);
74
- }
75
-
76
- /**
77
- * 트랜잭션 없이 콜백 실행
78
- *
79
- * @param callback - DB 연결 후 실행할 콜백
80
- * @returns 콜백 결과
81
- */
82
- async connectWithoutTransaction<R>(callback: (conn: T) => Promise<R>): Promise<R> {
83
- const db = this._createDbContext();
84
- return db.connectWithoutTransaction(async () => callback(db));
85
- }
86
-
87
- /**
88
- * DbContext 인스턴스 생성
89
- */
90
- private _createDbContext(): T {
91
- // database는 options에서 우선, 없으면 config에서
92
- const database = this.options?.database ?? ("database" in this.config ? this.config.database : undefined);
93
-
94
- // schema는 options에서 우선, 없으면 config에서
95
- const schema = this.options?.schema ?? ("schema" in this.config ? this.config.schema : undefined);
96
-
97
- return new this.dbContextType(new NodeDbContextExecutor(this.config), {
98
- database,
99
- schema,
100
- });
101
- }
102
- }