@simplysm/orm-node 13.0.84 → 13.0.86

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
@@ -1,33 +1,61 @@
1
1
  # @simplysm/orm-node
2
2
 
3
- Node.js ORM module supporting MySQL, MSSQL (including Azure SQL), and PostgreSQL. Provides connection pooling, transaction management, bulk insert, and a high-level ORM factory that integrates with `@simplysm/orm-common` DbContext.
3
+ Node.js ORM 모듈. MySQL, PostgreSQL, MSSQL(Azure 포함) 데이터베이스를 지원한다.
4
4
 
5
- ## Installation
5
+ ## 설치
6
6
 
7
7
  ```bash
8
8
  npm install @simplysm/orm-node
9
9
  ```
10
10
 
11
- Install the peer dependency for your target database:
11
+ 사용하는 DB에 따라 드라이버를 추가로 설치한다 (모두 optional peerDependency):
12
12
 
13
- | Database | Peer dependency |
14
- |------------|----------------------------------|
15
- | MySQL | `mysql2` |
16
- | MSSQL | `tedious` |
17
- | PostgreSQL | `pg` + `pg-copy-streams` |
13
+ ```bash
14
+ npm install mysql2 # MySQL
15
+ npm install pg pg-copy-streams # PostgreSQL
16
+ npm install tedious # MSSQL / Azure SQL
17
+ ```
18
+
19
+ **의존성:** `@simplysm/core-common`, `@simplysm/orm-common`, `generic-pool`, `consola`
20
+
21
+ ## 아키텍처 개요
22
+
23
+ ```
24
+ createOrm() -- 최상위 팩토리 (ORM 인스턴스)
25
+ └─ NodeDbContextExecutor -- DbContextExecutor 구현체
26
+ └─ createDbConn() -- 커넥션 풀에서 PooledDbConn 획득
27
+ └─ PooledDbConn -- 풀 래퍼
28
+ └─ MysqlDbConn / PostgresqlDbConn / MssqlDbConn -- 실제 연결
29
+ ```
30
+
31
+ - `createOrm` -- `@simplysm/orm-common`의 `DbContext`와 DB 연결을 결합하는 고수준 API
32
+ - `NodeDbContextExecutor` -- `QueryDef` → SQL 변환 및 실행을 담당하는 어댑터
33
+ - `createDbConn` -- `generic-pool` 기반 커넥션 풀에서 연결을 획득
34
+ - `PooledDbConn` -- 풀에서 빌린 물리 연결을 감싸는 래퍼 (반환 시 자동 롤백)
35
+ - `MysqlDbConn` / `PostgresqlDbConn` / `MssqlDbConn` -- 각 DBMS별 실제 연결 구현
36
+
37
+ ## 주요 사용법
18
38
 
19
- ## Quick Start
39
+ ### ORM 인스턴스 생성 및 트랜잭션
20
40
 
21
41
  ```typescript
22
- import { defineDbContext, queryable } from "@simplysm/orm-common";
23
42
  import { createOrm } from "@simplysm/orm-node";
43
+ import { defineDbContext, Table } from "@simplysm/orm-common";
44
+
45
+ // 1. 테이블 및 DbContext 정의 (orm-common)
46
+ const User = Table("user")
47
+ .columns((c) => ({ id: c.int().autoIncrement(), name: c.varchar(100) }))
48
+ .primaryKey("id");
49
+
50
+ const Order = Table("order")
51
+ .columns((c) => ({ id: c.int().autoIncrement(), userId: c.int(), amount: c.decimal(10, 2) }))
52
+ .primaryKey("id");
24
53
 
25
- // 1. Define a DbContext
26
54
  const MyDb = defineDbContext({
27
- user: (db) => queryable(db, User),
55
+ tables: { user: User, order: Order },
28
56
  });
29
57
 
30
- // 2. Create an ORM instance
58
+ // 2. ORM 인스턴스 생성
31
59
  const orm = createOrm(MyDb, {
32
60
  dialect: "mysql",
33
61
  host: "localhost",
@@ -37,24 +65,242 @@ const orm = createOrm(MyDb, {
37
65
  database: "mydb",
38
66
  });
39
67
 
40
- // 3. Execute queries within a transaction
41
- const users = await orm.connect(async (db) => {
42
- return await db.user().execute();
68
+ // 3-a. 자동 트랜잭션 (commit/rollback 자동 처리)
69
+ const result = await orm.connect(async (db) => {
70
+ const users = await db.user().execute();
71
+ await db.user().insert([{ name: "Alice" }]);
72
+ return users;
43
73
  });
44
74
 
45
- // 4. Execute queries without a transaction
46
- const users2 = await orm.connectWithoutTransaction(async (db) => {
75
+ // 3-b. 트랜잭션 없이 실행
76
+ const users = await orm.connectWithoutTransaction(async (db) => {
47
77
  return await db.user().execute();
48
78
  });
79
+
80
+ // 3-c. 격리 수준 지정
81
+ await orm.connect(async (db) => {
82
+ /* ... */
83
+ }, "SERIALIZABLE");
84
+ ```
85
+
86
+ ### OrmOptions로 database/schema 오버라이드
87
+
88
+ ```typescript
89
+ const orm = createOrm(MyDb, config, {
90
+ database: "other_db", // config.database 대신 사용
91
+ schema: "custom_schema", // config.schema 대신 사용
92
+ });
93
+ ```
94
+
95
+ ### 저수준 DB 연결
96
+
97
+ ```typescript
98
+ import { createDbConn } from "@simplysm/orm-node";
99
+
100
+ const conn = await createDbConn(config);
101
+ await conn.connect();
102
+
103
+ await conn.beginTransaction();
104
+ try {
105
+ const rows = await conn.execute(["SELECT * FROM users"]);
106
+ await conn.executeParametrized("INSERT INTO users (name) VALUES (?)", ["Alice"]);
107
+ await conn.commitTransaction();
108
+ } catch {
109
+ await conn.rollbackTransaction();
110
+ }
111
+
112
+ await conn.close();
113
+ ```
114
+
115
+ ### 벌크 인서트
116
+
117
+ 각 DBMS의 네이티브 벌크 API를 사용하여 최적 성능을 제공한다.
118
+
119
+ ```typescript
120
+ await conn.bulkInsert("users", columnMetas, records);
121
+ ```
122
+
123
+ | DBMS | 방식 |
124
+ |------|------|
125
+ | MySQL | `LOAD DATA LOCAL INFILE` (임시 CSV 파일) |
126
+ | PostgreSQL | `COPY FROM STDIN` (스트림 기반 CSV) |
127
+ | MSSQL | tedious `BulkLoad` API (네이티브) |
128
+
129
+ ## API 레퍼런스
130
+
131
+ ### `createOrm(dbContextDef, config, options?): Orm`
132
+
133
+ ORM 인스턴스 팩토리. `defineDbContext`로 정의한 DbContext 정의와 연결 설정을 결합한다.
134
+
135
+ ```typescript
136
+ function createOrm<TDef extends DbContextDef<any, any, any>>(
137
+ dbContextDef: TDef,
138
+ config: DbConnConfig,
139
+ options?: OrmOptions,
140
+ ): Orm<TDef>;
141
+ ```
142
+
143
+ **`Orm<TDef>` 인터페이스:**
144
+
145
+ | 속성/메서드 | 타입 | 설명 |
146
+ |---|---|---|
147
+ | `dbContextDef` | `TDef` (readonly) | DbContext 정의 |
148
+ | `config` | `DbConnConfig` (readonly) | 연결 설정 |
149
+ | `options` | `OrmOptions` (readonly, optional) | 옵션 |
150
+ | `connect(callback, isolationLevel?)` | `Promise<R>` | 트랜잭션 내에서 콜백 실행 |
151
+ | `connectWithoutTransaction(callback)` | `Promise<R>` | 트랜잭션 없이 콜백 실행 |
152
+
153
+ **`OrmOptions` 인터페이스:**
154
+
155
+ | 필드 | 타입 | 설명 |
156
+ |---|---|---|
157
+ | `database?` | `string` | config.database 대신 사용할 DB 이름 |
158
+ | `schema?` | `string` | config.schema 대신 사용할 스키마 이름 |
159
+
160
+ ### `createDbConn(config): Promise<DbConn>`
161
+
162
+ 커넥션 풀에서 DB 연결을 획득하여 반환한다. 동일 config에 대해 풀이 공유된다.
163
+
164
+ ```typescript
165
+ function createDbConn(config: DbConnConfig): Promise<DbConn>;
49
166
  ```
50
167
 
51
- ## Documentation
168
+ ### `DbConn` 인터페이스
52
169
 
53
- | Category | File | Description |
54
- |----------|------|-------------|
55
- | ORM Factory | [docs/create-orm.md](docs/create-orm.md) | `createOrm` factory function, `Orm` and `OrmOptions` types |
56
- | Connections | [docs/connections.md](docs/connections.md) | `DbConn` interface, `MysqlDbConn`, `MssqlDbConn`, `PostgresqlDbConn` |
57
- | Connection Factory & Pooling | [docs/pooling.md](docs/pooling.md) | `createDbConn`, `PooledDbConn`, connection pool management |
58
- | Configuration | [docs/configuration.md](docs/configuration.md) | `DbConnConfig`, `DbPoolConfig`, dialect-specific config types |
59
- | Context Executor | [docs/context-executor.md](docs/context-executor.md) | `NodeDbContextExecutor` for DbContext integration |
60
- | Constants | [docs/constants.md](docs/constants.md) | Timeout values and error message constants |
170
+ 모든 DB 연결 구현체의 공통 인터페이스. `EventEmitter<{ close: void }>`를 상속한다.
171
+
172
+ ```typescript
173
+ interface DbConn extends EventEmitter<{ close: void }> {
174
+ config: DbConnConfig;
175
+ isConnected: boolean;
176
+ isInTransaction: boolean;
177
+
178
+ connect(): Promise<void>;
179
+ close(): Promise<void>;
180
+ beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
181
+ commitTransaction(): Promise<void>;
182
+ rollbackTransaction(): Promise<void>;
183
+ execute(queries: string[]): Promise<Record<string, unknown>[][]>;
184
+ executeParametrized(query: string, params?: unknown[]): Promise<Record<string, unknown>[][]>;
185
+ bulkInsert(
186
+ tableName: string,
187
+ columnMetas: Record<string, ColumnMeta>,
188
+ records: Record<string, unknown>[],
189
+ ): Promise<void>;
190
+ }
191
+ ```
192
+
193
+ ### `DbConnConfig` 타입
194
+
195
+ `dialect` 필드로 분기되는 유니온 타입이다.
196
+
197
+ ```typescript
198
+ type DbConnConfig = MysqlDbConnConfig | MssqlDbConnConfig | PostgresqlDbConnConfig;
199
+ ```
200
+
201
+ **공통 필드:**
202
+
203
+ | 필드 | 타입 | 설명 |
204
+ |---|---|---|
205
+ | `dialect` | `"mysql"` \| `"mssql"` \| `"mssql-azure"` \| `"postgresql"` | DBMS 종류 |
206
+ | `host` | `string` | 호스트 |
207
+ | `port?` | `number` | 포트 |
208
+ | `username` | `string` | 사용자명 |
209
+ | `password` | `string` | 비밀번호 |
210
+ | `database?` | `string` | 데이터베이스명 |
211
+ | `defaultIsolationLevel?` | `IsolationLevel` | 기본 격리 수준 |
212
+ | `pool?` | `DbPoolConfig` | 커넥션 풀 설정 |
213
+
214
+ **MSSQL/PostgreSQL 전용:**
215
+
216
+ | 필드 | 타입 | 설명 |
217
+ |---|---|---|
218
+ | `schema?` | `string` | 스키마 (MSSQL 기본: `dbo`, PostgreSQL 기본: `public`) |
219
+
220
+ **MSSQL 특수 dialect:**
221
+ - `"mssql-azure"`: Azure SQL용. `encrypt: true`가 자동 적용됨.
222
+
223
+ ### `DbPoolConfig` 인터페이스
224
+
225
+ ```typescript
226
+ interface DbPoolConfig {
227
+ min?: number; // 최소 연결 수 (기본: 1)
228
+ max?: number; // 최대 연결 수 (기본: 10)
229
+ acquireTimeoutMillis?: number; // 획득 타임아웃 (기본: 30초)
230
+ idleTimeoutMillis?: number; // 유휴 타임아웃 (기본: 30초)
231
+ }
232
+ ```
233
+
234
+ ### `NodeDbContextExecutor`
235
+
236
+ `@simplysm/orm-common`의 `DbContextExecutor` 인터페이스 구현체. `DbContext`가 내부적으로 사용한다.
237
+
238
+ ```typescript
239
+ class NodeDbContextExecutor implements DbContextExecutor {
240
+ constructor(config: DbConnConfig);
241
+
242
+ connect(): Promise<void>;
243
+ close(): Promise<void>;
244
+ beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
245
+ commitTransaction(): Promise<void>;
246
+ rollbackTransaction(): Promise<void>;
247
+ executeParametrized(query: string, params?: unknown[]): Promise<Record<string, unknown>[][]>;
248
+ bulkInsert(tableName: string, columnMetas: Record<string, ColumnMeta>, records: DataRecord[]): Promise<void>;
249
+ executeDefs<T = DataRecord>(defs: QueryDef[], resultMetas?: (ResultMeta | undefined)[]): Promise<T[][]>;
250
+ }
251
+ ```
252
+
253
+ **`executeDefs` 동작:**
254
+ - `QueryDef`를 dialect에 맞는 SQL로 변환 (`createQueryBuilder`)
255
+ - `resultMetas`가 모두 `undefined`이면 → 결과 없는 쿼리로 판단하여 단일 배치 실행
256
+ - `ResultMeta`가 있으면 → `parseQueryResult`로 타입 변환 적용
257
+
258
+ ### `PooledDbConn`
259
+
260
+ `generic-pool`의 풀에서 물리 연결을 빌려 사용하는 래퍼 클래스.
261
+
262
+ ```typescript
263
+ class PooledDbConn extends EventEmitter<{ close: void }> implements DbConn {
264
+ constructor(pool: Pool<DbConn>, initialConfig: DbConnConfig, getLastCreateError?: () => Error | undefined);
265
+ }
266
+ ```
267
+
268
+ **특징:**
269
+ - `connect()`: 풀에서 물리 연결 획득
270
+ - `close()`: 트랜잭션 진행 중이면 자동 롤백 후 풀에 반환 (실제 연결은 닫지 않음)
271
+ - 물리 연결이 끊기면 `close` 이벤트 자동 전파
272
+
273
+ ### DB 연결 구현 클래스
274
+
275
+ | 클래스 | 드라이버 | dialect |
276
+ |---|---|---|
277
+ | `MysqlDbConn` | `mysql2/promise` | `"mysql"` |
278
+ | `PostgresqlDbConn` | `pg` + `pg-copy-streams` | `"postgresql"` |
279
+ | `MssqlDbConn` | `tedious` | `"mssql"`, `"mssql-azure"` |
280
+
281
+ 모두 `EventEmitter<{ close: void }>`를 상속하고 `DbConn`을 구현한다. 드라이버 모듈은 `createDbConn` 호출 시 lazy import된다.
282
+
283
+ ### `getDialectFromConfig(config): Dialect`
284
+
285
+ config에서 `Dialect`를 추출한다. `"mssql-azure"` → `"mssql"`로 변환된다.
286
+
287
+ ```typescript
288
+ function getDialectFromConfig(config: DbConnConfig): Dialect;
289
+ ```
290
+
291
+ ### 상수
292
+
293
+ | 상수 | 값 | 설명 |
294
+ |---|---|---|
295
+ | `DB_CONN_CONNECT_TIMEOUT` | 10초 (10,000ms) | 연결 타임아웃 |
296
+ | `DB_CONN_DEFAULT_TIMEOUT` | 10분 (600,000ms) | 쿼리 기본 타임아웃 |
297
+ | `DB_CONN_ERRORS.NOT_CONNECTED` | `"'Connection' is not connected."` | 미연결 에러 메시지 |
298
+ | `DB_CONN_ERRORS.ALREADY_CONNECTED` | `"'Connection' is already connected."` | 중복 연결 에러 메시지 |
299
+
300
+ ### IsolationLevel 타입
301
+
302
+ `@simplysm/orm-common`에서 제공하는 트랜잭션 격리 수준이다.
303
+
304
+ ```typescript
305
+ type IsolationLevel = "READ_UNCOMMITTED" | "READ_COMMITTED" | "REPEATABLE_READ" | "SERIALIZABLE";
306
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/orm-node",
3
- "version": "13.0.84",
3
+ "version": "13.0.86",
4
4
  "description": "Simplysm package - ORM module (node)",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -21,8 +21,8 @@
21
21
  "dependencies": {
22
22
  "consola": "^3.4.2",
23
23
  "generic-pool": "^3.9.0",
24
- "@simplysm/orm-common": "13.0.84",
25
- "@simplysm/core-common": "13.0.84"
24
+ "@simplysm/core-common": "13.0.86",
25
+ "@simplysm/orm-common": "13.0.86"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/pg": "^8.18.0",
@@ -1,100 +0,0 @@
1
- # Configuration
2
-
3
- Connection configuration types used to establish database connections.
4
-
5
- ## `DbConnConfig`
6
-
7
- Union type of all dialect-specific configurations:
8
-
9
- ```typescript
10
- type DbConnConfig = MysqlDbConnConfig | MssqlDbConnConfig | PostgresqlDbConnConfig;
11
- ```
12
-
13
- ---
14
-
15
- ## `MysqlDbConnConfig`
16
-
17
- | Property | Type | Required | Description |
18
- |----------|------|----------|-------------|
19
- | `dialect` | `"mysql"` | Yes | Must be `"mysql"` |
20
- | `host` | `string` | Yes | Server hostname or IP |
21
- | `port` | `number` | No | Server port |
22
- | `username` | `string` | Yes | Login username |
23
- | `password` | `string` | Yes | Login password |
24
- | `database` | `string` | No | Default database name |
25
- | `defaultIsolationLevel` | `IsolationLevel` | No | Default transaction isolation level |
26
- | `pool` | `DbPoolConfig` | No | Connection pool settings |
27
-
28
- ---
29
-
30
- ## `MssqlDbConnConfig`
31
-
32
- | Property | Type | Required | Description |
33
- |----------|------|----------|-------------|
34
- | `dialect` | `"mssql" \| "mssql-azure"` | Yes | Use `"mssql-azure"` for Azure SQL (enables encryption) |
35
- | `host` | `string` | Yes | Server hostname or IP |
36
- | `port` | `number` | No | Server port |
37
- | `username` | `string` | Yes | Login username |
38
- | `password` | `string` | Yes | Login password |
39
- | `database` | `string` | No | Default database name |
40
- | `schema` | `string` | No | Default schema (e.g., `dbo`) |
41
- | `defaultIsolationLevel` | `IsolationLevel` | No | Default transaction isolation level |
42
- | `pool` | `DbPoolConfig` | No | Connection pool settings |
43
-
44
- ---
45
-
46
- ## `PostgresqlDbConnConfig`
47
-
48
- | Property | Type | Required | Description |
49
- |----------|------|----------|-------------|
50
- | `dialect` | `"postgresql"` | Yes | Must be `"postgresql"` |
51
- | `host` | `string` | Yes | Server hostname or IP |
52
- | `port` | `number` | No | Server port (default: 5432) |
53
- | `username` | `string` | Yes | Login username |
54
- | `password` | `string` | Yes | Login password |
55
- | `database` | `string` | No | Default database name |
56
- | `schema` | `string` | No | Default schema (e.g., `public`) |
57
- | `defaultIsolationLevel` | `IsolationLevel` | No | Default transaction isolation level |
58
- | `pool` | `DbPoolConfig` | No | Connection pool settings |
59
-
60
- ---
61
-
62
- ## `DbPoolConfig`
63
-
64
- Connection pool settings (applied via `generic-pool`).
65
-
66
- | Property | Type | Default | Description |
67
- |----------|------|---------|-------------|
68
- | `min` | `number` | `1` | Minimum number of connections in the pool |
69
- | `max` | `number` | `10` | Maximum number of connections in the pool |
70
- | `acquireTimeoutMillis` | `number` | `30000` | Timeout for acquiring a connection (ms) |
71
- | `idleTimeoutMillis` | `number` | `30000` | Timeout before idle connections are destroyed (ms) |
72
-
73
- ---
74
-
75
- ## `IsolationLevel`
76
-
77
- Transaction isolation level (from `@simplysm/orm-common`):
78
-
79
- ```typescript
80
- type IsolationLevel =
81
- | "READ_UNCOMMITTED"
82
- | "READ_COMMITTED"
83
- | "REPEATABLE_READ"
84
- | "SERIALIZABLE";
85
- ```
86
-
87
- ---
88
-
89
- ## `getDialectFromConfig(config)`
90
-
91
- Utility that extracts the `Dialect` from a `DbConnConfig`. Maps `"mssql-azure"` to `"mssql"`.
92
-
93
- ```typescript
94
- import { getDialectFromConfig } from "@simplysm/orm-node";
95
-
96
- getDialectFromConfig({ dialect: "mssql-azure", ... }); // => "mssql"
97
- getDialectFromConfig({ dialect: "mysql", ... }); // => "mysql"
98
- ```
99
-
100
- **Returns:** `Dialect` (`"mysql" | "mssql" | "postgresql"`)
@@ -1,158 +0,0 @@
1
- # Connections
2
-
3
- Low-level database connection classes implementing the `DbConn` interface. Each class wraps a native driver for a specific DBMS.
4
-
5
- ## `DbConn` Interface
6
-
7
- All connection classes implement this interface, which extends `EventEmitter<{ close: void }>`.
8
-
9
- ### Properties
10
-
11
- | Property | Type | Description |
12
- |----------|------|-------------|
13
- | `config` | `DbConnConfig` | Connection configuration |
14
- | `isConnected` | `boolean` | Whether the connection is active |
15
- | `isInTransaction` | `boolean` | Whether a transaction is in progress |
16
-
17
- ### Methods
18
-
19
- #### `connect(): Promise<void>`
20
-
21
- Establishes the database connection.
22
-
23
- #### `close(): Promise<void>`
24
-
25
- Closes the database connection.
26
-
27
- #### `beginTransaction(isolationLevel?): Promise<void>`
28
-
29
- Begins a transaction with an optional isolation level. Defaults to `READ_UNCOMMITTED` if not specified in the method call or in the connection config's `defaultIsolationLevel`.
30
-
31
- #### `commitTransaction(): Promise<void>`
32
-
33
- Commits the current transaction.
34
-
35
- #### `rollbackTransaction(): Promise<void>`
36
-
37
- Rolls back the current transaction.
38
-
39
- #### `execute(queries): Promise<Record<string, unknown>[][]>`
40
-
41
- Executes an array of SQL query strings. Returns an array of result sets (one per query). Empty strings are skipped.
42
-
43
- | Parameter | Type | Description |
44
- |-----------|------|-------------|
45
- | `queries` | `string[]` | SQL query strings |
46
-
47
- #### `executeParametrized(query, params?): Promise<Record<string, unknown>[][]>`
48
-
49
- Executes a single parameterized SQL query.
50
-
51
- | Parameter | Type | Description |
52
- |-----------|------|-------------|
53
- | `query` | `string` | SQL query string |
54
- | `params` | `unknown[]` | Optional binding parameters |
55
-
56
- #### `bulkInsert(tableName, columnMetas, records): Promise<void>`
57
-
58
- Performs a high-performance bulk insert using native DBMS mechanisms.
59
-
60
- | Parameter | Type | Description |
61
- |-----------|------|-------------|
62
- | `tableName` | `string` | Target table (e.g., `database.table` or `database.schema.table`) |
63
- | `columnMetas` | `Record<string, ColumnMeta>` | Column name to metadata mapping |
64
- | `records` | `Record<string, unknown>[]` | Records to insert |
65
-
66
- ### Events
67
-
68
- | Event | Payload | Description |
69
- |-------|---------|-------------|
70
- | `close` | `void` | Emitted when the connection is closed |
71
-
72
- ---
73
-
74
- ## `MysqlDbConn`
75
-
76
- MySQL connection using the `mysql2/promise` library.
77
-
78
- - **Bulk insert** uses `LOAD DATA LOCAL INFILE` with a temporary CSV file.
79
- - UUID and binary columns are stored via `UNHEX()` conversion.
80
- - Root user (`root`) connects without binding to a specific database.
81
- - Connection timeout: 10 minutes (auto-close after 20 minutes idle).
82
-
83
- ```typescript
84
- import { MysqlDbConn } from "@simplysm/orm-node";
85
-
86
- const mysql = await import("mysql2/promise");
87
- const conn = new MysqlDbConn(mysql, {
88
- dialect: "mysql",
89
- host: "localhost",
90
- port: 3306,
91
- username: "root",
92
- password: "password",
93
- database: "mydb",
94
- });
95
-
96
- await conn.connect();
97
- const results = await conn.execute(["SELECT * FROM users"]);
98
- await conn.close();
99
- ```
100
-
101
- ---
102
-
103
- ## `MssqlDbConn`
104
-
105
- MSSQL / Azure SQL connection using the `tedious` library.
106
-
107
- - **Bulk insert** uses tedious `BulkLoad` API.
108
- - Supports `mssql-azure` dialect for Azure SQL with encryption enabled.
109
- - Connection timeout: 10 seconds, query timeout: 10 minutes.
110
- - Auto-close after 20 minutes idle.
111
-
112
- ```typescript
113
- import { MssqlDbConn } from "@simplysm/orm-node";
114
-
115
- const tedious = await import("tedious");
116
- const conn = new MssqlDbConn(tedious, {
117
- dialect: "mssql",
118
- host: "localhost",
119
- port: 1433,
120
- username: "sa",
121
- password: "password",
122
- database: "mydb",
123
- });
124
-
125
- await conn.connect();
126
- const results = await conn.execute(["SELECT * FROM users"]);
127
- await conn.close();
128
- ```
129
-
130
- ---
131
-
132
- ## `PostgresqlDbConn`
133
-
134
- PostgreSQL connection using the `pg` library with `pg-copy-streams` for bulk operations.
135
-
136
- - **Bulk insert** uses `COPY FROM STDIN` with CSV format.
137
- - Binary columns use PostgreSQL `bytea` hex format (`\x...`).
138
- - Default port: 5432.
139
- - Connection timeout: 10 seconds, query timeout: 10 minutes.
140
-
141
- ```typescript
142
- import { PostgresqlDbConn } from "@simplysm/orm-node";
143
-
144
- const pg = await import("pg");
145
- const pgCopyStreams = await import("pg-copy-streams");
146
- const conn = new PostgresqlDbConn(pg, pgCopyStreams, {
147
- dialect: "postgresql",
148
- host: "localhost",
149
- port: 5432,
150
- username: "postgres",
151
- password: "password",
152
- database: "mydb",
153
- });
154
-
155
- await conn.connect();
156
- const results = await conn.execute(["SELECT * FROM users"]);
157
- await conn.close();
158
- ```
package/docs/constants.md DELETED
@@ -1,26 +0,0 @@
1
- # Constants
2
-
3
- Shared constants used across all connection implementations.
4
-
5
- ## `DB_CONN_CONNECT_TIMEOUT`
6
-
7
- Connection establishment timeout.
8
-
9
- - **Value:** `10000` (10 seconds)
10
- - **Used by:** MSSQL (`connectTimeout`) and PostgreSQL (`connectionTimeoutMillis`)
11
-
12
- ## `DB_CONN_DEFAULT_TIMEOUT`
13
-
14
- Default query execution timeout.
15
-
16
- - **Value:** `600000` (10 minutes)
17
- - **Used by:** All connection classes for query timeouts. Connections auto-close after `2x` this value (20 minutes) of inactivity.
18
-
19
- ## `DB_CONN_ERRORS`
20
-
21
- Standard error messages for connection state violations.
22
-
23
- | Key | Value | Description |
24
- |-----|-------|-------------|
25
- | `NOT_CONNECTED` | `"'Connection' is not connected."` | Thrown when operating on a disconnected connection |
26
- | `ALREADY_CONNECTED` | `"'Connection' is already connected."` | Thrown when `connect()` is called on an active connection |
@@ -1,93 +0,0 @@
1
- # Context Executor
2
-
3
- ## `NodeDbContextExecutor`
4
-
5
- A `DbContextExecutor` implementation for Node.js that bridges `@simplysm/orm-common` DbContext with actual database connections. Used internally by `createOrm`, but can also be used directly for lower-level control.
6
-
7
- ### Constructor
8
-
9
- ```typescript
10
- new NodeDbContextExecutor(config: DbConnConfig)
11
- ```
12
-
13
- | Parameter | Type | Description |
14
- |-----------|------|-------------|
15
- | `config` | `DbConnConfig` | Database connection configuration |
16
-
17
- ### Methods
18
-
19
- #### `connect(): Promise<void>`
20
-
21
- Acquires a connection from the pool and activates it.
22
-
23
- #### `close(): Promise<void>`
24
-
25
- Returns the connection to the pool.
26
-
27
- #### `beginTransaction(isolationLevel?): Promise<void>`
28
-
29
- Begins a transaction with an optional isolation level.
30
-
31
- #### `commitTransaction(): Promise<void>`
32
-
33
- Commits the current transaction.
34
-
35
- #### `rollbackTransaction(): Promise<void>`
36
-
37
- Rolls back the current transaction.
38
-
39
- #### `executeParametrized(query, params?): Promise<Record<string, unknown>[][]>`
40
-
41
- Executes a parameterized SQL query string.
42
-
43
- | Parameter | Type | Description |
44
- |-----------|------|-------------|
45
- | `query` | `string` | SQL query string |
46
- | `params` | `unknown[]` | Optional query parameters |
47
-
48
- #### `bulkInsert(tableName, columnMetas, records): Promise<void>`
49
-
50
- Performs bulk insert using the native driver API.
51
-
52
- | Parameter | Type | Description |
53
- |-----------|------|-------------|
54
- | `tableName` | `string` | Target table name |
55
- | `columnMetas` | `Record<string, ColumnMeta>` | Column metadata |
56
- | `records` | `DataRecord[]` | Records to insert |
57
-
58
- #### `executeDefs<T>(defs, resultMetas?): Promise<T[][]>`
59
-
60
- Executes an array of `QueryDef` objects. Converts each `QueryDef` to SQL using the appropriate dialect query builder, executes it, and parses results using optional `ResultMeta`.
61
-
62
- | Parameter | Type | Description |
63
- |-----------|------|-------------|
64
- | `defs` | `QueryDef[]` | Query definitions to execute |
65
- | `resultMetas` | `(ResultMeta \| undefined)[]` | Optional result parsing metadata per query |
66
-
67
- **Optimization:** When all `resultMetas` are `undefined` (no result parsing needed), queries are combined into a single SQL batch for efficiency, returning empty arrays.
68
-
69
- ### Usage
70
-
71
- ```typescript
72
- import { NodeDbContextExecutor } from "@simplysm/orm-node";
73
-
74
- const executor = new NodeDbContextExecutor({
75
- dialect: "postgresql",
76
- host: "localhost",
77
- username: "postgres",
78
- password: "password",
79
- database: "mydb",
80
- });
81
-
82
- await executor.connect();
83
- try {
84
- await executor.beginTransaction();
85
- const results = await executor.executeParametrized(
86
- "SELECT * FROM users WHERE id = $1",
87
- [1],
88
- );
89
- await executor.commitTransaction();
90
- } finally {
91
- await executor.close();
92
- }
93
- ```
@@ -1,103 +0,0 @@
1
- # ORM Factory
2
-
3
- High-level factory for creating ORM instances that manage DbContext lifecycle and transactions.
4
-
5
- ## `createOrm(dbContextDef, config, options?)`
6
-
7
- Creates an `Orm` instance that binds a DbContext definition to a database connection configuration.
8
-
9
- ```typescript
10
- import { defineDbContext, queryable } from "@simplysm/orm-common";
11
- import { createOrm } from "@simplysm/orm-node";
12
-
13
- const MyDb = defineDbContext({
14
- user: (db) => queryable(db, User),
15
- order: (db) => queryable(db, Order),
16
- });
17
-
18
- const orm = createOrm(MyDb, {
19
- dialect: "mysql",
20
- host: "localhost",
21
- port: 3306,
22
- username: "root",
23
- password: "password",
24
- database: "mydb",
25
- });
26
- ```
27
-
28
- **Parameters:**
29
-
30
- | Parameter | Type | Description |
31
- |-----------|------|-------------|
32
- | `dbContextDef` | `DbContextDef` | DbContext definition created with `defineDbContext` |
33
- | `config` | `DbConnConfig` | Database connection configuration |
34
- | `options` | `OrmOptions` | Optional overrides for database/schema |
35
-
36
- **Returns:** `Orm<TDef>`
37
-
38
- ## `Orm<TDef>`
39
-
40
- The object returned by `createOrm`.
41
-
42
- ### Properties
43
-
44
- | Property | Type | Description |
45
- |----------|------|-------------|
46
- | `dbContextDef` | `TDef` | The DbContext definition |
47
- | `config` | `DbConnConfig` | The connection configuration |
48
- | `options` | `OrmOptions \| undefined` | Optional overrides |
49
-
50
- ### `orm.connect(callback, isolationLevel?)`
51
-
52
- Executes a callback within a transaction. The transaction is automatically committed on success and rolled back on error.
53
-
54
- ```typescript
55
- const result = await orm.connect(async (db) => {
56
- const users = await db.user().execute();
57
- return users;
58
- }, "READ_COMMITTED");
59
- ```
60
-
61
- **Parameters:**
62
-
63
- | Parameter | Type | Description |
64
- |-----------|------|-------------|
65
- | `callback` | `(conn: DbContextInstance<TDef>) => Promise<R>` | Callback receiving the DbContext instance |
66
- | `isolationLevel` | `IsolationLevel` | Optional transaction isolation level |
67
-
68
- **Returns:** `Promise<R>` -- the callback's return value.
69
-
70
- ### `orm.connectWithoutTransaction(callback)`
71
-
72
- Executes a callback without wrapping in a transaction.
73
-
74
- ```typescript
75
- const result = await orm.connectWithoutTransaction(async (db) => {
76
- const users = await db.user().execute();
77
- return users;
78
- });
79
- ```
80
-
81
- **Parameters:**
82
-
83
- | Parameter | Type | Description |
84
- |-----------|------|-------------|
85
- | `callback` | `(conn: DbContextInstance<TDef>) => Promise<R>` | Callback receiving the DbContext instance |
86
-
87
- **Returns:** `Promise<R>` -- the callback's return value.
88
-
89
- ## `OrmOptions`
90
-
91
- Options that override values from `DbConnConfig`.
92
-
93
- | Property | Type | Description |
94
- |----------|------|-------------|
95
- | `database` | `string \| undefined` | Database name (overrides config's `database`) |
96
- | `schema` | `string \| undefined` | Schema name (e.g., `dbo` for MSSQL, `public` for PostgreSQL) |
97
-
98
- ```typescript
99
- const orm = createOrm(MyDb, config, {
100
- database: "other_db",
101
- schema: "custom_schema",
102
- });
103
- ```
package/docs/pooling.md DELETED
@@ -1,67 +0,0 @@
1
- # Connection Factory & Pooling
2
-
3
- Connection pool management using the `generic-pool` library. Pools are keyed by configuration and reused automatically.
4
-
5
- ## `createDbConn(config)`
6
-
7
- Factory function that acquires a pooled connection. Creates a new pool if none exists for the given configuration.
8
-
9
- ```typescript
10
- import { createDbConn } from "@simplysm/orm-node";
11
-
12
- const conn = await createDbConn({
13
- dialect: "mysql",
14
- host: "localhost",
15
- port: 3306,
16
- username: "root",
17
- password: "password",
18
- database: "mydb",
19
- pool: {
20
- min: 2,
21
- max: 20,
22
- },
23
- });
24
-
25
- await conn.connect();
26
- // ... use connection ...
27
- await conn.close(); // returns connection to pool
28
- ```
29
-
30
- **Parameters:**
31
-
32
- | Parameter | Type | Description |
33
- |-----------|------|-------------|
34
- | `config` | `DbConnConfig` | Database connection configuration |
35
-
36
- **Returns:** `Promise<DbConn>` -- a `PooledDbConn` wrapper.
37
-
38
- **Pool behavior:**
39
-
40
- - Pools are cached by a JSON-serialized configuration key.
41
- - Each pool validates connections on borrow (`testOnBorrow: true`).
42
- - Failed connection creation errors are tracked per pool.
43
- - Driver modules (`tedious`, `mysql2`, `pg`, `pg-copy-streams`) are lazy-loaded and cached.
44
-
45
- ---
46
-
47
- ## `PooledDbConn`
48
-
49
- A `DbConn` wrapper that manages borrowing from and returning connections to a pool. Implements the full `DbConn` interface via delegation.
50
-
51
- ### Key Behaviors
52
-
53
- - **`connect()`** -- Acquires a physical connection from the pool. Throws if already connected.
54
- - **`close()`** -- Returns the connection to the pool (does **not** terminate the physical connection). If a transaction is in progress, it is rolled back first.
55
- - **Physical connection loss** -- If the underlying connection is lost (timeout, network error), the wrapper emits `close` and clears its reference. The pool's validation will discard the broken connection.
56
-
57
- ### Properties
58
-
59
- | Property | Type | Description |
60
- |----------|------|-------------|
61
- | `config` | `DbConnConfig` | Delegates to underlying connection's config |
62
- | `isConnected` | `boolean` | `true` if a physical connection is acquired and active |
63
- | `isInTransaction` | `boolean` | `true` if the underlying connection has an active transaction |
64
-
65
- ### Methods
66
-
67
- All `DbConn` methods (`beginTransaction`, `commitTransaction`, `rollbackTransaction`, `execute`, `executeParametrized`, `bulkInsert`) are delegated to the underlying physical connection. Throws if no connection is acquired.