@simplysm/orm-node 13.0.81 → 13.0.83
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 +60 -0
- package/docs/configuration.md +100 -0
- package/docs/connections.md +158 -0
- package/docs/constants.md +26 -0
- package/docs/context-executor.md +93 -0
- package/docs/create-orm.md +103 -0
- package/docs/pooling.md +67 -0
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @simplysm/orm-node
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @simplysm/orm-node
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install the peer dependency for your target database:
|
|
12
|
+
|
|
13
|
+
| Database | Peer dependency |
|
|
14
|
+
|------------|----------------------------------|
|
|
15
|
+
| MySQL | `mysql2` |
|
|
16
|
+
| MSSQL | `tedious` |
|
|
17
|
+
| PostgreSQL | `pg` + `pg-copy-streams` |
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { defineDbContext, queryable } from "@simplysm/orm-common";
|
|
23
|
+
import { createOrm } from "@simplysm/orm-node";
|
|
24
|
+
|
|
25
|
+
// 1. Define a DbContext
|
|
26
|
+
const MyDb = defineDbContext({
|
|
27
|
+
user: (db) => queryable(db, User),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// 2. Create an ORM instance
|
|
31
|
+
const orm = createOrm(MyDb, {
|
|
32
|
+
dialect: "mysql",
|
|
33
|
+
host: "localhost",
|
|
34
|
+
port: 3306,
|
|
35
|
+
username: "root",
|
|
36
|
+
password: "password",
|
|
37
|
+
database: "mydb",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// 3. Execute queries within a transaction
|
|
41
|
+
const users = await orm.connect(async (db) => {
|
|
42
|
+
return await db.user().execute();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// 4. Execute queries without a transaction
|
|
46
|
+
const users2 = await orm.connectWithoutTransaction(async (db) => {
|
|
47
|
+
return await db.user().execute();
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Documentation
|
|
52
|
+
|
|
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 |
|
|
@@ -0,0 +1,100 @@
|
|
|
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"`)
|
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
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 |
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/orm-node",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.83",
|
|
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/
|
|
25
|
-
"@simplysm/
|
|
24
|
+
"@simplysm/orm-common": "13.0.83",
|
|
25
|
+
"@simplysm/core-common": "13.0.83"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/pg": "^8.18.0",
|