@simplysm/orm-node 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/README.md +163 -203
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,182 +1,104 @@
|
|
|
1
1
|
# @simplysm/orm-node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ORM module (node) -- database connections and ORM integration for MySQL, PostgreSQL, and MSSQL on Node.js.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @simplysm/orm-node
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## API Overview
|
|
12
12
|
|
|
13
|
-
|
|
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`, `consola`
|
|
20
|
-
|
|
21
|
-
## 아키텍처 개요
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
createOrm() -- 최상위 팩토리 (ORM 인스턴스)
|
|
25
|
-
└─ NodeDbContextExecutor -- DbContextExecutor 구현체
|
|
26
|
-
└─ createDbConn() -- DB 연결 생성
|
|
27
|
-
└─ MysqlDbConn / PostgresqlDbConn / MssqlDbConn -- 실제 연결
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
- `createOrm` -- `@simplysm/orm-common`의 `DbContext`와 DB 연결을 결합하는 고수준 API
|
|
31
|
-
- `NodeDbContextExecutor` -- `QueryDef` -> SQL 변환 및 실행을 담당하는 어댑터
|
|
32
|
-
- `createDbConn` -- DB 연결 인스턴스를 생성하는 팩토리
|
|
33
|
-
- `MysqlDbConn` / `PostgresqlDbConn` / `MssqlDbConn` -- 각 DBMS별 실제 연결 구현
|
|
34
|
-
|
|
35
|
-
## 주요 사용법
|
|
36
|
-
|
|
37
|
-
### ORM 인스턴스 생성 및 트랜잭션
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { createOrm } from "@simplysm/orm-node";
|
|
41
|
-
import { defineDbContext, Table } from "@simplysm/orm-common";
|
|
42
|
-
|
|
43
|
-
// 1. 테이블 및 DbContext 정의 (orm-common)
|
|
44
|
-
const User = Table("user")
|
|
45
|
-
.columns((c) => ({ id: c.int().autoIncrement(), name: c.varchar(100) }))
|
|
46
|
-
.primaryKey("id");
|
|
47
|
-
|
|
48
|
-
const Order = Table("order")
|
|
49
|
-
.columns((c) => ({ id: c.int().autoIncrement(), userId: c.int(), amount: c.decimal(10, 2) }))
|
|
50
|
-
.primaryKey("id");
|
|
13
|
+
### Types
|
|
51
14
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
15
|
+
| API | Type | Description |
|
|
16
|
+
|-----|------|-------------|
|
|
17
|
+
| `DB_CONN_CONNECT_TIMEOUT` | const | Connection establishment timeout (10 seconds) |
|
|
18
|
+
| `DB_CONN_DEFAULT_TIMEOUT` | const | Query default timeout (10 minutes) |
|
|
19
|
+
| `DB_CONN_ERRORS` | const | Error message constants (`NOT_CONNECTED`, `ALREADY_CONNECTED`) |
|
|
20
|
+
| `DbConn` | interface | Low-level DB connection interface |
|
|
21
|
+
| `DbConnConfig` | type | Union of all DB connection configs |
|
|
22
|
+
| `MysqlDbConnConfig` | interface | MySQL connection configuration |
|
|
23
|
+
| `MssqlDbConnConfig` | interface | MSSQL/Azure SQL connection configuration |
|
|
24
|
+
| `PostgresqlDbConnConfig` | interface | PostgreSQL connection configuration |
|
|
25
|
+
| `getDialectFromConfig` | function | Extract `Dialect` from a `DbConnConfig` |
|
|
55
26
|
|
|
56
|
-
|
|
57
|
-
// database는 필수 -- config 또는 options 중 하나에 반드시 지정해야 한다.
|
|
58
|
-
const orm = createOrm(MyDb, {
|
|
59
|
-
dialect: "mysql",
|
|
60
|
-
host: "localhost",
|
|
61
|
-
port: 3306,
|
|
62
|
-
username: "root",
|
|
63
|
-
password: "password",
|
|
64
|
-
database: "mydb",
|
|
65
|
-
});
|
|
27
|
+
### Connections
|
|
66
28
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
29
|
+
| API | Type | Description |
|
|
30
|
+
|-----|------|-------------|
|
|
31
|
+
| `createDbConn` | function | Factory function to create a DB connection from config |
|
|
32
|
+
| `MysqlDbConn` | class | MySQL connection implementation (mysql2) |
|
|
33
|
+
| `PostgresqlDbConn` | class | PostgreSQL connection implementation (pg) |
|
|
34
|
+
| `MssqlDbConn` | class | MSSQL connection implementation (tedious) |
|
|
73
35
|
|
|
74
|
-
|
|
75
|
-
const users = await orm.connectWithoutTransaction(async (db) => {
|
|
76
|
-
return await db.user().execute();
|
|
77
|
-
});
|
|
36
|
+
### Core
|
|
78
37
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
38
|
+
| API | Type | Description |
|
|
39
|
+
|-----|------|-------------|
|
|
40
|
+
| `OrmOptions` | interface | ORM options (database name, schema override) |
|
|
41
|
+
| `Orm` | interface | ORM instance with `connect` and `connectWithoutTransaction` |
|
|
42
|
+
| `createOrm` | function | Create an ORM instance from a DbContext definition and config |
|
|
43
|
+
| `NodeDbContextExecutor` | class | DbContextExecutor for Node.js environment |
|
|
84
44
|
|
|
85
|
-
|
|
45
|
+
## `DbConnConfig`
|
|
86
46
|
|
|
87
47
|
```typescript
|
|
88
|
-
|
|
89
|
-
database: "other_db", // config.database 대신 사용
|
|
90
|
-
schema: "custom_schema", // config.schema 대신 사용
|
|
91
|
-
});
|
|
48
|
+
type DbConnConfig = MysqlDbConnConfig | MssqlDbConnConfig | PostgresqlDbConnConfig;
|
|
92
49
|
```
|
|
93
50
|
|
|
94
|
-
|
|
51
|
+
## `MysqlDbConnConfig`
|
|
95
52
|
|
|
96
53
|
```typescript
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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();
|
|
54
|
+
interface MysqlDbConnConfig {
|
|
55
|
+
dialect: "mysql";
|
|
56
|
+
host: string;
|
|
57
|
+
port?: number;
|
|
58
|
+
username: string;
|
|
59
|
+
password: string;
|
|
60
|
+
database?: string;
|
|
61
|
+
defaultIsolationLevel?: IsolationLevel;
|
|
110
62
|
}
|
|
111
|
-
|
|
112
|
-
await conn.close();
|
|
113
63
|
```
|
|
114
64
|
|
|
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 정의와 연결 설정을 결합한다.
|
|
65
|
+
## `MssqlDbConnConfig`
|
|
134
66
|
|
|
135
67
|
```typescript
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
68
|
+
interface MssqlDbConnConfig {
|
|
69
|
+
dialect: "mssql" | "mssql-azure";
|
|
70
|
+
host: string;
|
|
71
|
+
port?: number;
|
|
72
|
+
username: string;
|
|
73
|
+
password: string;
|
|
74
|
+
database?: string;
|
|
75
|
+
schema?: string;
|
|
76
|
+
defaultIsolationLevel?: IsolationLevel;
|
|
77
|
+
}
|
|
141
78
|
```
|
|
142
79
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
**`Orm<TDef>` 인터페이스:**
|
|
146
|
-
|
|
147
|
-
| 속성/메서드 | 타입 | 설명 |
|
|
148
|
-
|---|---|---|
|
|
149
|
-
| `dbContextDef` | `TDef` (readonly) | DbContext 정의 |
|
|
150
|
-
| `config` | `DbConnConfig` (readonly) | 연결 설정 |
|
|
151
|
-
| `options` | `OrmOptions` (readonly, optional) | 옵션 |
|
|
152
|
-
| `connect(callback, isolationLevel?)` | `Promise<R>` | 트랜잭션 내에서 콜백 실행 |
|
|
153
|
-
| `connectWithoutTransaction(callback)` | `Promise<R>` | 트랜잭션 없이 콜백 실행 |
|
|
154
|
-
|
|
155
|
-
**`OrmOptions` 인터페이스:**
|
|
156
|
-
|
|
157
|
-
| 필드 | 타입 | 설명 |
|
|
158
|
-
|---|---|---|
|
|
159
|
-
| `database?` | `string` | config.database 대신 사용할 DB 이름 |
|
|
160
|
-
| `schema?` | `string` | config.schema 대신 사용할 스키마 이름 |
|
|
161
|
-
|
|
162
|
-
### `createDbConn(config): Promise<DbConn>`
|
|
163
|
-
|
|
164
|
-
DB 연결 인스턴스를 생성하여 반환한다. 반환된 객체에 `connect()`를 호출해야 실제 연결이 수립된다. 드라이버 모듈은 호출 시 lazy import된다.
|
|
80
|
+
## `PostgresqlDbConnConfig`
|
|
165
81
|
|
|
166
82
|
```typescript
|
|
167
|
-
|
|
83
|
+
interface PostgresqlDbConnConfig {
|
|
84
|
+
dialect: "postgresql";
|
|
85
|
+
host: string;
|
|
86
|
+
port?: number;
|
|
87
|
+
username: string;
|
|
88
|
+
password: string;
|
|
89
|
+
database?: string;
|
|
90
|
+
schema?: string;
|
|
91
|
+
defaultIsolationLevel?: IsolationLevel;
|
|
92
|
+
}
|
|
168
93
|
```
|
|
169
94
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
모든 DB 연결 구현체의 공통 인터페이스. `EventEmitter<{ close: void }>`를 상속한다.
|
|
95
|
+
## `DbConn`
|
|
173
96
|
|
|
174
97
|
```typescript
|
|
175
98
|
interface DbConn extends EventEmitter<{ close: void }> {
|
|
176
99
|
config: DbConnConfig;
|
|
177
100
|
isConnected: boolean;
|
|
178
101
|
isInTransaction: boolean;
|
|
179
|
-
|
|
180
102
|
connect(): Promise<void>;
|
|
181
103
|
close(): Promise<void>;
|
|
182
104
|
beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
|
|
@@ -192,98 +114,136 @@ interface DbConn extends EventEmitter<{ close: void }> {
|
|
|
192
114
|
}
|
|
193
115
|
```
|
|
194
116
|
|
|
195
|
-
|
|
117
|
+
## `getDialectFromConfig`
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
function getDialectFromConfig(config: DbConnConfig): Dialect;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Returns the `Dialect` for a given config. Maps `"mssql-azure"` to `"mssql"`.
|
|
196
124
|
|
|
197
|
-
`
|
|
125
|
+
## `createDbConn`
|
|
198
126
|
|
|
199
127
|
```typescript
|
|
200
|
-
|
|
128
|
+
async function createDbConn(config: DbConnConfig): Promise<DbConn>;
|
|
201
129
|
```
|
|
202
130
|
|
|
203
|
-
|
|
131
|
+
Factory function that creates a DB connection. Driver modules (mysql2, pg, tedious) are lazy-loaded. Returns an unconnected instance -- call `connect()` separately.
|
|
204
132
|
|
|
205
|
-
|
|
206
|
-
|---|---|---|
|
|
207
|
-
| `dialect` | `"mysql"` \| `"mssql"` \| `"mssql-azure"` \| `"postgresql"` | DBMS 종류 |
|
|
208
|
-
| `host` | `string` | 호스트 |
|
|
209
|
-
| `port?` | `number` | 포트 |
|
|
210
|
-
| `username` | `string` | 사용자명 |
|
|
211
|
-
| `password` | `string` | 비밀번호 |
|
|
212
|
-
| `database?` | `string` | 데이터베이스명 |
|
|
213
|
-
| `defaultIsolationLevel?` | `IsolationLevel` | 기본 격리 수준 |
|
|
133
|
+
## `OrmOptions`
|
|
214
134
|
|
|
215
|
-
|
|
135
|
+
```typescript
|
|
136
|
+
interface OrmOptions {
|
|
137
|
+
database?: string;
|
|
138
|
+
schema?: string;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## `Orm`
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
interface Orm<TDef extends DbContextDef<any, any, any>> {
|
|
146
|
+
readonly dbContextDef: TDef;
|
|
147
|
+
readonly config: DbConnConfig;
|
|
148
|
+
readonly options?: OrmOptions;
|
|
149
|
+
connect<R>(
|
|
150
|
+
callback: (conn: DbContextInstance<TDef>) => Promise<R>,
|
|
151
|
+
isolationLevel?: IsolationLevel,
|
|
152
|
+
): Promise<R>;
|
|
153
|
+
connectWithoutTransaction<R>(
|
|
154
|
+
callback: (conn: DbContextInstance<TDef>) => Promise<R>,
|
|
155
|
+
): Promise<R>;
|
|
156
|
+
}
|
|
157
|
+
```
|
|
216
158
|
|
|
217
|
-
|
|
218
|
-
|---|---|---|
|
|
219
|
-
| `schema?` | `string` | 스키마 (MSSQL 기본: `dbo`, PostgreSQL 기본: `public`) |
|
|
159
|
+
## `createOrm`
|
|
220
160
|
|
|
221
|
-
|
|
222
|
-
|
|
161
|
+
```typescript
|
|
162
|
+
function createOrm<TDef extends DbContextDef<any, any, any>>(
|
|
163
|
+
dbContextDef: TDef,
|
|
164
|
+
config: DbConnConfig,
|
|
165
|
+
options?: OrmOptions,
|
|
166
|
+
): Orm<TDef>;
|
|
167
|
+
```
|
|
223
168
|
|
|
224
|
-
|
|
169
|
+
Node.js ORM factory. Creates an instance that manages DbContext and DB connections with automatic transaction handling.
|
|
225
170
|
|
|
226
|
-
|
|
171
|
+
## `NodeDbContextExecutor`
|
|
227
172
|
|
|
228
173
|
```typescript
|
|
229
174
|
class NodeDbContextExecutor implements DbContextExecutor {
|
|
230
175
|
constructor(config: DbConnConfig);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
176
|
+
async connect(): Promise<void>;
|
|
177
|
+
async close(): Promise<void>;
|
|
178
|
+
async beginTransaction(isolationLevel?: IsolationLevel): Promise<void>;
|
|
179
|
+
async commitTransaction(): Promise<void>;
|
|
180
|
+
async rollbackTransaction(): Promise<void>;
|
|
181
|
+
async executeParametrized(query: string, params?: unknown[]): Promise<Record<string, unknown>[][]>;
|
|
182
|
+
async bulkInsert(
|
|
183
|
+
tableName: string,
|
|
184
|
+
columnMetas: Record<string, ColumnMeta>,
|
|
185
|
+
records: DataRecord[],
|
|
186
|
+
): Promise<void>;
|
|
187
|
+
async executeDefs<T = DataRecord>(
|
|
188
|
+
defs: QueryDef[],
|
|
189
|
+
resultMetas?: (ResultMeta | undefined)[],
|
|
190
|
+
): Promise<T[][]>;
|
|
240
191
|
}
|
|
241
192
|
```
|
|
242
193
|
|
|
243
|
-
|
|
244
|
-
- `QueryDef`를 dialect에 맞는 SQL로 변환 (`createQueryBuilder`)
|
|
245
|
-
- `resultMetas`가 모두 `undefined`이면 -> 결과 없는 쿼리로 판단하여 단일 배치 실행
|
|
246
|
-
- `ResultMeta`가 있으면 -> `parseQueryResult`로 타입 변환 적용
|
|
194
|
+
DbContextExecutor for Node.js. Handles actual DB connections and query execution including QueryDef-to-SQL conversion.
|
|
247
195
|
|
|
248
|
-
|
|
196
|
+
## Usage Examples
|
|
249
197
|
|
|
250
|
-
|
|
251
|
-
|---|---|---|
|
|
252
|
-
| `MysqlDbConn` | `mysql2/promise` | `"mysql"` |
|
|
253
|
-
| `PostgresqlDbConn` | `pg` + `pg-copy-streams` | `"postgresql"` |
|
|
254
|
-
| `MssqlDbConn` | `tedious` | `"mssql"`, `"mssql-azure"` |
|
|
198
|
+
### Create ORM and run queries in a transaction
|
|
255
199
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
- MySQL: `username`이 `"root"`인 경우 특정 database에 바인딩하지 않고 연결한다 (관리 작업용).
|
|
260
|
-
- MySQL: `charset`은 `utf8mb4`로 고정, `multipleStatements`가 활성화되어 있다.
|
|
261
|
-
- PostgreSQL: 기본 포트 `5432`가 자동 적용된다.
|
|
262
|
-
- MSSQL: `trustServerCertificate: true`로 설정된다.
|
|
200
|
+
```typescript
|
|
201
|
+
import { createOrm } from "@simplysm/orm-node";
|
|
202
|
+
import { defineDbContext, queryable } from "@simplysm/orm-common";
|
|
263
203
|
|
|
264
|
-
|
|
204
|
+
const MyDb = defineDbContext({
|
|
205
|
+
user: (db) => queryable(db, User),
|
|
206
|
+
});
|
|
265
207
|
|
|
266
|
-
|
|
208
|
+
const orm = createOrm(MyDb, {
|
|
209
|
+
dialect: "mysql",
|
|
210
|
+
host: "localhost",
|
|
211
|
+
port: 3306,
|
|
212
|
+
username: "root",
|
|
213
|
+
password: "password",
|
|
214
|
+
database: "mydb",
|
|
215
|
+
});
|
|
267
216
|
|
|
268
|
-
|
|
269
|
-
|
|
217
|
+
const users = await orm.connect(async (db) => {
|
|
218
|
+
return await db.user().execute();
|
|
219
|
+
});
|
|
270
220
|
```
|
|
271
221
|
|
|
272
|
-
###
|
|
222
|
+
### Use low-level DB connection
|
|
273
223
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
| `DB_CONN_CONNECT_TIMEOUT` | 10초 (10,000ms) | 연결 타임아웃 |
|
|
277
|
-
| `DB_CONN_DEFAULT_TIMEOUT` | 10분 (600,000ms) | 쿼리 기본 타임아웃 |
|
|
278
|
-
| `DB_CONN_ERRORS.NOT_CONNECTED` | `"'Connection' is not connected."` | 미연결 에러 메시지 |
|
|
279
|
-
| `DB_CONN_ERRORS.ALREADY_CONNECTED` | `"'Connection' is already connected."` | 중복 연결 에러 메시지 |
|
|
224
|
+
```typescript
|
|
225
|
+
import { createDbConn } from "@simplysm/orm-node";
|
|
280
226
|
|
|
281
|
-
|
|
227
|
+
const conn = await createDbConn({
|
|
228
|
+
dialect: "postgresql",
|
|
229
|
+
host: "localhost",
|
|
230
|
+
username: "admin",
|
|
231
|
+
password: "secret",
|
|
232
|
+
database: "testdb",
|
|
233
|
+
});
|
|
282
234
|
|
|
283
|
-
|
|
235
|
+
await conn.connect();
|
|
236
|
+
try {
|
|
237
|
+
const results = await conn.execute(["SELECT * FROM users"]);
|
|
238
|
+
} finally {
|
|
239
|
+
await conn.close();
|
|
240
|
+
}
|
|
241
|
+
```
|
|
284
242
|
|
|
285
|
-
|
|
243
|
+
### Run without transaction
|
|
286
244
|
|
|
287
245
|
```typescript
|
|
288
|
-
|
|
246
|
+
const result = await orm.connectWithoutTransaction(async (db) => {
|
|
247
|
+
return await db.user().execute();
|
|
248
|
+
});
|
|
289
249
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/orm-node",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.98",
|
|
4
4
|
"description": "Simplysm package - ORM module (node)",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"consola": "^3.4.2",
|
|
23
|
-
"@simplysm/core-common": "13.0.
|
|
24
|
-
"@simplysm/orm-common": "13.0.
|
|
23
|
+
"@simplysm/core-common": "13.0.98",
|
|
24
|
+
"@simplysm/orm-common": "13.0.98"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@types/pg": "^8.
|
|
27
|
+
"@types/pg": "^8.20.0",
|
|
28
28
|
"@types/pg-copy-streams": "^1.2.5",
|
|
29
|
-
"mysql2": "^3.
|
|
29
|
+
"mysql2": "^3.20.0",
|
|
30
30
|
"pg": "^8.20.0",
|
|
31
31
|
"pg-copy-streams": "^7.0.0",
|
|
32
32
|
"tedious": "^19.2.1"
|