@simplysm/orm-common 13.0.96 → 13.0.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +209 -54
- package/docs/core.md +225 -0
- package/docs/expression.md +296 -0
- package/docs/query-builder.md +196 -0
- package/docs/queryable.md +578 -0
- package/docs/schema-builders.md +415 -0
- package/docs/types.md +445 -0
- package/docs/utilities.md +122 -0
- package/package.json +2 -2
- package/docs/ddl.md +0 -300
- package/docs/query.md +0 -644
- package/docs/schema.md +0 -325
package/README.md
CHANGED
|
@@ -1,112 +1,267 @@
|
|
|
1
1
|
# @simplysm/orm-common
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ORM Module (common) -- dialect-independent ORM for MySQL, MSSQL, and PostgreSQL.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Provides schema definition, type-safe query building, expression construction, and query rendering without any direct database dependency. Actual database execution is handled by `@simplysm/orm-node`.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install @simplysm/orm-common
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## API Reference
|
|
14
|
+
|
|
15
|
+
### Core
|
|
16
|
+
|
|
17
|
+
Define and create database contexts with connection/transaction management.
|
|
18
|
+
|
|
19
|
+
| Export | Kind | Description |
|
|
20
|
+
|--------|------|-------------|
|
|
21
|
+
| `defineDbContext` | function | Create a DbContext definition (blueprint) from tables, views, procedures, and migrations |
|
|
22
|
+
| `createDbContext` | function | Create a runtime DbContext instance from a definition and executor |
|
|
23
|
+
| `DbContextBase` | interface | Internal interface used by Queryable/Executable (status, database, schema, executeDefs) |
|
|
24
|
+
| `DbContextDef` | interface | DbContext definition holding schema metadata (tables, views, procedures, migrations) |
|
|
25
|
+
| `DbContextInstance` | type | Full runtime instance with queryable accessors, DDL methods, and connection management |
|
|
26
|
+
| `DbContextStatus` | type | `"ready" \| "connect" \| "transact"` |
|
|
27
|
+
| `DbTransactionError` | class | Standardized transaction error with `DbErrorCode` |
|
|
28
|
+
| `DbErrorCode` | enum | `NO_ACTIVE_TRANSACTION`, `TRANSACTION_ALREADY_STARTED`, `DEADLOCK`, `LOCK_TIMEOUT` |
|
|
29
|
+
|
|
30
|
+
[Detailed documentation](docs/core.md)
|
|
31
|
+
|
|
32
|
+
### Queryable / Executable
|
|
33
|
+
|
|
34
|
+
Build and execute SELECT, INSERT, UPDATE, DELETE, and UPSERT queries with full type safety.
|
|
35
|
+
|
|
36
|
+
| Export | Kind | Description |
|
|
37
|
+
|--------|------|-------------|
|
|
38
|
+
| `Queryable` | class | Chaining query builder (select, where, join, include, orderBy, limit, groupBy, etc.) |
|
|
39
|
+
| `queryable` | function | Factory that creates a Queryable getter for a table or view |
|
|
40
|
+
| `getMatchedPrimaryKeys` | function | Match FK columns to target table PK columns |
|
|
41
|
+
| `Executable` | class | Stored procedure execution wrapper |
|
|
42
|
+
| `executable` | function | Factory that creates an Executable getter for a procedure |
|
|
43
|
+
| `parseSearchQuery` | function | Parse search text into LIKE patterns (OR / +must / -not) |
|
|
44
|
+
| `ParsedSearchQuery` | interface | Result of `parseSearchQuery` with `or`, `must`, `not` arrays |
|
|
45
|
+
|
|
46
|
+
[Detailed documentation](docs/queryable.md)
|
|
47
|
+
|
|
48
|
+
### Expression
|
|
49
|
+
|
|
50
|
+
Dialect-independent SQL expression builder producing JSON AST.
|
|
51
|
+
|
|
52
|
+
| Export | Kind | Description |
|
|
53
|
+
|--------|------|-------------|
|
|
54
|
+
| `expr` | const | Expression builder with 70+ methods (comparisons, string, math, date, aggregate, window) |
|
|
55
|
+
| `ExprUnit` | class | Type-safe expression wrapper tracking return type via generics |
|
|
56
|
+
| `WhereExprUnit` | class | WHERE clause expression wrapper |
|
|
57
|
+
| `ExprInput` | type | Accepts `ExprUnit<T>` or literal `T` |
|
|
58
|
+
| `SwitchExprBuilder` | interface | CASE WHEN builder returned by `expr.switch()` |
|
|
59
|
+
|
|
60
|
+
[Detailed documentation](docs/expression.md)
|
|
61
|
+
|
|
62
|
+
### Schema Builders
|
|
63
|
+
|
|
64
|
+
Define tables, views, procedures, columns, indexes, and relations via fluent API.
|
|
65
|
+
|
|
66
|
+
| Export | Kind | Description |
|
|
67
|
+
|--------|------|-------------|
|
|
68
|
+
| `Table` | function | Create a `TableBuilder` for a table |
|
|
69
|
+
| `TableBuilder` | class | Fluent builder: `.database()`, `.columns()`, `.primaryKey()`, `.indexes()`, `.relations()` |
|
|
70
|
+
| `View` | function | Create a `ViewBuilder` for a view |
|
|
71
|
+
| `ViewBuilder` | class | Fluent builder: `.database()`, `.query()`, `.relations()` |
|
|
72
|
+
| `Procedure` | function | Create a `ProcedureBuilder` for a stored procedure |
|
|
73
|
+
| `ProcedureBuilder` | class | Fluent builder: `.database()`, `.params()`, `.returns()`, `.body()` |
|
|
74
|
+
| `ColumnBuilder` | class | Column definition: `.autoIncrement()`, `.nullable()`, `.default()`, `.description()` |
|
|
75
|
+
| `createColumnFactory` | function | Returns column type methods (int, bigint, varchar, text, datetime, etc.) |
|
|
76
|
+
| `IndexBuilder` | class | Index definition: `.name()`, `.unique()`, `.orderBy()`, `.description()` |
|
|
77
|
+
| `createIndexFactory` | function | Returns `{ index(...columns) }` |
|
|
78
|
+
| `ForeignKeyBuilder` | class | N:1 FK relation (creates DB constraint) |
|
|
79
|
+
| `ForeignKeyTargetBuilder` | class | 1:N FK reverse-reference with `.single()` |
|
|
80
|
+
| `RelationKeyBuilder` | class | N:1 logical relation (no DB constraint) |
|
|
81
|
+
| `RelationKeyTargetBuilder` | class | 1:N logical reverse-reference with `.single()` |
|
|
82
|
+
| `createRelationFactory` | function | Returns FK + RelationKey methods (table gets both, view gets RelationKey only) |
|
|
83
|
+
| `_Migration` | const | Built-in system migration table (`_migration` with `code` column) |
|
|
84
|
+
|
|
85
|
+
[Detailed documentation](docs/schema-builders.md)
|
|
86
|
+
|
|
87
|
+
### Query Builder
|
|
88
|
+
|
|
89
|
+
Render `QueryDef` JSON AST to dialect-specific SQL strings.
|
|
90
|
+
|
|
91
|
+
| Export | Kind | Description |
|
|
92
|
+
|--------|------|-------------|
|
|
93
|
+
| `createQueryBuilder` | function | Create a dialect-specific QueryBuilder (`"mysql"`, `"mssql"`, `"postgresql"`) |
|
|
94
|
+
| `QueryBuilderBase` | abstract class | Base class with dispatch and common render methods |
|
|
95
|
+
| `ExprRendererBase` | abstract class | Base class for expression-to-SQL rendering |
|
|
96
|
+
| `MysqlQueryBuilder` | class | MySQL implementation |
|
|
97
|
+
| `MysqlExprRenderer` | class | MySQL expression renderer |
|
|
98
|
+
| `MssqlQueryBuilder` | class | MSSQL implementation |
|
|
99
|
+
| `MssqlExprRenderer` | class | MSSQL expression renderer |
|
|
100
|
+
| `PostgresqlQueryBuilder` | class | PostgreSQL implementation |
|
|
101
|
+
| `PostgresqlExprRenderer` | class | PostgreSQL expression renderer |
|
|
102
|
+
|
|
103
|
+
[Detailed documentation](docs/query-builder.md)
|
|
104
|
+
|
|
105
|
+
### Types
|
|
106
|
+
|
|
107
|
+
TypeScript types for dialects, queries, expressions, columns, and results.
|
|
12
108
|
|
|
13
|
-
|
|
109
|
+
| Export | Kind | Description |
|
|
110
|
+
|--------|------|-------------|
|
|
111
|
+
| `Dialect` | type | `"mysql" \| "mssql" \| "postgresql"` |
|
|
112
|
+
| `dialects` | const | `["mysql", "mssql", "postgresql"]` |
|
|
113
|
+
| `QueryBuildResult` | interface | `{ sql, resultSetIndex?, resultSetStride? }` |
|
|
114
|
+
| `IsolationLevel` | type | `"READ_UNCOMMITTED" \| "READ_COMMITTED" \| "REPEATABLE_READ" \| "SERIALIZABLE"` |
|
|
115
|
+
| `DataRecord` | type | Recursive record type for query results |
|
|
116
|
+
| `DbContextExecutor` | interface | Executor interface (connect, close, beginTransaction, executeDefs, etc.) |
|
|
117
|
+
| `ResultMeta` | interface | Metadata for result type transformation and JOIN nesting |
|
|
118
|
+
| `Migration` | interface | `{ name, up }` migration definition |
|
|
119
|
+
| `DataType` | type | SQL type union (int, bigint, varchar, decimal, datetime, etc.) |
|
|
120
|
+
| `ColumnPrimitive` | type | All column value types (string, number, boolean, DateTime, DateOnly, Time, Uuid, Bytes, undefined) |
|
|
121
|
+
| `ColumnPrimitiveStr` | type | Type name keys: `"string" \| "number" \| "boolean" \| "DateTime" \| ...` |
|
|
122
|
+
| `ColumnMeta` | interface | Column metadata (type, dataType, autoIncrement, nullable, default, description) |
|
|
123
|
+
| `Expr` | type | Discriminated union of 40+ expression AST node types |
|
|
124
|
+
| `WhereExpr` | type | Subset of Expr for WHERE clauses (comparison + logical) |
|
|
125
|
+
| `QueryDef` | type | Union of all query definition types (DML + DDL + Utils + Meta) |
|
|
126
|
+
| `SelectQueryDef` | interface | SELECT query definition |
|
|
127
|
+
| `InsertQueryDef` | interface | INSERT query definition |
|
|
128
|
+
| `UpdateQueryDef` | interface | UPDATE query definition |
|
|
129
|
+
| `DeleteQueryDef` | interface | DELETE query definition |
|
|
130
|
+
| `UpsertQueryDef` | interface | UPSERT query definition |
|
|
131
|
+
| `QueryDefObjectName` | interface | `{ database?, schema?, name }` |
|
|
14
132
|
|
|
15
|
-
|
|
16
|
-
|---------|------|
|
|
17
|
-
| [스키마 정의](docs/schema.md) | Table, View, Procedure, Column, Relation, Index 빌더 |
|
|
18
|
-
| [쿼리 & 표현식](docs/query.md) | Queryable, Executable, expr 표현식 빌더 |
|
|
19
|
-
| [DDL & 초기화](docs/ddl.md) | DDL 메서드, 스키마 초기화, 마이그레이션 |
|
|
133
|
+
[Detailed documentation](docs/types.md)
|
|
20
134
|
|
|
21
|
-
|
|
135
|
+
### Utilities
|
|
22
136
|
|
|
23
|
-
|
|
137
|
+
Result parsing helpers.
|
|
138
|
+
|
|
139
|
+
| Export | Kind | Description |
|
|
140
|
+
|--------|------|-------------|
|
|
141
|
+
| `parseQueryResult` | function | Transform flat DB results to typed nested objects via `ResultMeta` |
|
|
142
|
+
|
|
143
|
+
[Detailed documentation](docs/utilities.md)
|
|
144
|
+
|
|
145
|
+
## Usage Examples
|
|
146
|
+
|
|
147
|
+
### 1. Define Schema and DbContext
|
|
24
148
|
|
|
25
149
|
```typescript
|
|
26
|
-
import { defineDbContext, createDbContext,
|
|
150
|
+
import { Table, defineDbContext, createDbContext, expr } from "@simplysm/orm-common";
|
|
27
151
|
|
|
28
|
-
|
|
29
|
-
|
|
152
|
+
const User = Table("User")
|
|
153
|
+
.database("mydb")
|
|
30
154
|
.columns((c) => ({
|
|
31
|
-
id: c.
|
|
155
|
+
id: c.bigint().autoIncrement(),
|
|
32
156
|
name: c.varchar(100),
|
|
33
157
|
email: c.varchar(200).nullable(),
|
|
158
|
+
status: c.varchar(20).default("active"),
|
|
34
159
|
createdAt: c.datetime(),
|
|
35
160
|
}))
|
|
36
161
|
.primaryKey("id")
|
|
37
162
|
.indexes((i) => [i.index("email").unique()]);
|
|
38
163
|
|
|
39
|
-
const
|
|
164
|
+
const Post = Table("Post")
|
|
165
|
+
.database("mydb")
|
|
40
166
|
.columns((c) => ({
|
|
41
|
-
id: c.
|
|
42
|
-
|
|
43
|
-
|
|
167
|
+
id: c.bigint().autoIncrement(),
|
|
168
|
+
authorId: c.bigint(),
|
|
169
|
+
title: c.varchar(200),
|
|
170
|
+
content: c.text(),
|
|
44
171
|
}))
|
|
45
172
|
.primaryKey("id")
|
|
46
173
|
.relations((r) => ({
|
|
47
|
-
|
|
174
|
+
author: r.foreignKey(["authorId"], () => User),
|
|
48
175
|
}));
|
|
49
176
|
|
|
50
|
-
// DbContext 정의 (스키마 블루프린트)
|
|
51
177
|
const MyDb = defineDbContext({
|
|
52
|
-
tables: { user: User,
|
|
178
|
+
tables: { user: User, post: Post },
|
|
53
179
|
});
|
|
54
180
|
|
|
55
|
-
//
|
|
181
|
+
// createDbContext requires an executor (from @simplysm/orm-node or service-client)
|
|
56
182
|
const db = createDbContext(MyDb, executor, { database: "mydb" });
|
|
57
183
|
```
|
|
58
184
|
|
|
59
|
-
###
|
|
185
|
+
### 2. Query with Filters, Joins, and Aggregation
|
|
60
186
|
|
|
61
187
|
```typescript
|
|
62
188
|
await db.connect(async () => {
|
|
63
|
-
//
|
|
64
|
-
const
|
|
65
|
-
.where((
|
|
66
|
-
.orderBy((
|
|
189
|
+
// Basic query with WHERE
|
|
190
|
+
const activeUsers = await db.user()
|
|
191
|
+
.where((u) => [expr.eq(u.status, "active")])
|
|
192
|
+
.orderBy((u) => u.name)
|
|
67
193
|
.execute();
|
|
68
194
|
|
|
69
|
-
// JOIN
|
|
70
|
-
const
|
|
71
|
-
.include((
|
|
72
|
-
.where((c) => [expr.gt(c.amount, 100)])
|
|
195
|
+
// JOIN with include
|
|
196
|
+
const postsWithAuthor = await db.post()
|
|
197
|
+
.include((p) => p.author)
|
|
73
198
|
.execute();
|
|
74
199
|
|
|
75
|
-
//
|
|
76
|
-
const stats = await db.
|
|
77
|
-
.select((
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
count: expr.count(),
|
|
200
|
+
// Aggregation
|
|
201
|
+
const stats = await db.post()
|
|
202
|
+
.select((p) => ({
|
|
203
|
+
authorId: p.authorId,
|
|
204
|
+
postCount: expr.count(p.id),
|
|
81
205
|
}))
|
|
82
|
-
.groupBy((
|
|
206
|
+
.groupBy((p) => [p.authorId])
|
|
83
207
|
.execute();
|
|
208
|
+
});
|
|
209
|
+
```
|
|
84
210
|
|
|
85
|
-
|
|
86
|
-
await db.user().insert([{ name: "Bob", email: "bob@example.com", createdAt: new DateTime() }]);
|
|
211
|
+
### 3. Insert, Update, Delete
|
|
87
212
|
|
|
88
|
-
|
|
213
|
+
```typescript
|
|
214
|
+
await db.connect(async () => {
|
|
215
|
+
// Insert with output
|
|
89
216
|
const [inserted] = await db.user().insert(
|
|
90
|
-
[{ name: "
|
|
217
|
+
[{ name: "Alice", createdAt: DateTime.now() }],
|
|
91
218
|
["id"],
|
|
92
219
|
);
|
|
93
220
|
|
|
94
|
-
//
|
|
221
|
+
// Update
|
|
95
222
|
await db.user()
|
|
96
|
-
.where((
|
|
97
|
-
.update((
|
|
223
|
+
.where((u) => [expr.eq(u.id, inserted.id)])
|
|
224
|
+
.update((u) => ({
|
|
225
|
+
status: expr.val("string", "verified"),
|
|
226
|
+
}));
|
|
98
227
|
|
|
99
|
-
//
|
|
228
|
+
// Delete
|
|
100
229
|
await db.user()
|
|
101
|
-
.where((
|
|
230
|
+
.where((u) => [expr.eq(u.status, "deleted")])
|
|
102
231
|
.delete();
|
|
232
|
+
|
|
233
|
+
// Upsert
|
|
234
|
+
await db.user()
|
|
235
|
+
.where((u) => [expr.eq(u.email, "alice@test.com")])
|
|
236
|
+
.upsert(() => ({
|
|
237
|
+
name: expr.val("string", "Alice"),
|
|
238
|
+
email: expr.val("string", "alice@test.com"),
|
|
239
|
+
createdAt: expr.val("DateTime", DateTime.now()),
|
|
240
|
+
}));
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### 4. Text Search
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
await db.connect(async () => {
|
|
248
|
+
// Search with OR, +must, -exclude syntax
|
|
249
|
+
const results = await db.user()
|
|
250
|
+
.search((u) => [u.name, u.email], "alice +active -deleted")
|
|
251
|
+
.execute();
|
|
103
252
|
});
|
|
104
253
|
```
|
|
105
254
|
|
|
106
|
-
###
|
|
255
|
+
### 5. Recursive CTE
|
|
107
256
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
257
|
+
```typescript
|
|
258
|
+
await db.connect(async () => {
|
|
259
|
+
const hierarchy = await db.employee()
|
|
260
|
+
.where((e) => [expr.null(e.managerId)])
|
|
261
|
+
.recursive((cte) =>
|
|
262
|
+
cte.from(Employee)
|
|
263
|
+
.where((e) => [expr.eq(e.managerId, e.self![0].id)])
|
|
264
|
+
)
|
|
265
|
+
.execute();
|
|
266
|
+
});
|
|
267
|
+
```
|
package/docs/core.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Core
|
|
2
|
+
|
|
3
|
+
Database context definition, creation, and lifecycle management.
|
|
4
|
+
|
|
5
|
+
Source: `src/define-db-context.ts`, `src/create-db-context.ts`, `src/types/db-context-def.ts`, `src/errors/db-transaction-error.ts`
|
|
6
|
+
|
|
7
|
+
## defineDbContext
|
|
8
|
+
|
|
9
|
+
Create a `DbContextDef` blueprint from tables, views, procedures, and migrations. Automatically includes the `_migration` system table.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
function defineDbContext<
|
|
13
|
+
TTables extends Record<string, TableBuilder<any, any>>,
|
|
14
|
+
TViews extends Record<string, ViewBuilder<any, any, any>>,
|
|
15
|
+
TProcedures extends Record<string, ProcedureBuilder<any, any>>,
|
|
16
|
+
>(config: {
|
|
17
|
+
tables?: TTables;
|
|
18
|
+
views?: TViews;
|
|
19
|
+
procedures?: TProcedures;
|
|
20
|
+
migrations?: Migration[];
|
|
21
|
+
}): DbContextDef<TTables & { _migration: typeof _Migration }, TViews, TProcedures>;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Example:**
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
const MyDb = defineDbContext({
|
|
28
|
+
tables: { user: User, post: Post },
|
|
29
|
+
views: { userSummary: UserSummary },
|
|
30
|
+
procedures: { getUserById: GetUserById },
|
|
31
|
+
migrations: [
|
|
32
|
+
{ name: "20260101_001_init", up: async (db) => { await db.createTable(User); } },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## createDbContext
|
|
38
|
+
|
|
39
|
+
Create a runtime `DbContextInstance` from a definition and executor. This is the main entry point for database operations.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
/**
|
|
43
|
+
* @param def - Definition object created by defineDbContext()
|
|
44
|
+
* @param executor - Query executor (NodeDbContextExecutor, ServiceDbContextExecutor, etc.)
|
|
45
|
+
* @param opt - Database options
|
|
46
|
+
* @param opt.database - Database name
|
|
47
|
+
* @param opt.schema - Schema name (MSSQL: dbo, PostgreSQL: public)
|
|
48
|
+
* @returns A complete DbContext instance
|
|
49
|
+
*/
|
|
50
|
+
function createDbContext<TDef extends DbContextDef<any, any, any>>(
|
|
51
|
+
def: TDef,
|
|
52
|
+
executor: DbContextExecutor,
|
|
53
|
+
opt: { database: string; schema?: string },
|
|
54
|
+
): DbContextInstance<TDef>;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The returned instance provides:
|
|
58
|
+
|
|
59
|
+
- **Queryable accessors** -- one per table/view (e.g., `db.user()` returns a `Queryable`)
|
|
60
|
+
- **Executable accessors** -- one per procedure (e.g., `db.getUserById()` returns an `Executable`)
|
|
61
|
+
- **Connection management** -- `connect()`, `connectWithoutTransaction()`, `transaction()`
|
|
62
|
+
- **DDL methods** -- `createTable()`, `dropTable()`, `addColumn()`, `addIndex()`, etc.
|
|
63
|
+
- **Initialization** -- `initialize()` to run migrations
|
|
64
|
+
|
|
65
|
+
**Example:**
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const db = createDbContext(MyDb, executor, { database: "mydb" });
|
|
69
|
+
|
|
70
|
+
await db.connect(async () => {
|
|
71
|
+
const users = await db.user().execute();
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## DbContextBase
|
|
76
|
+
|
|
77
|
+
Internal interface satisfied by the DbContext instance. Used by `Queryable`, `Executable`, and `ViewBuilder`.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
interface DbContextBase {
|
|
81
|
+
status: DbContextStatus;
|
|
82
|
+
readonly database: string | undefined;
|
|
83
|
+
readonly schema: string | undefined;
|
|
84
|
+
getNextAlias(): string;
|
|
85
|
+
resetAliasCounter(): void;
|
|
86
|
+
executeDefs<T = DataRecord>(
|
|
87
|
+
defs: QueryDef[],
|
|
88
|
+
resultMetas?: (ResultMeta | undefined)[],
|
|
89
|
+
): Promise<T[][]>;
|
|
90
|
+
getQueryDefObjectName(
|
|
91
|
+
tableOrView: TableBuilder<any, any> | ViewBuilder<any, any, any>,
|
|
92
|
+
): QueryDefObjectName;
|
|
93
|
+
switchFk(table: QueryDefObjectName, enabled: boolean): Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## DbContextDef
|
|
98
|
+
|
|
99
|
+
Definition (blueprint) created by `defineDbContext()`. Contains schema metadata but no runtime state.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
interface DbContextDef<
|
|
103
|
+
TTables extends Record<string, TableBuilder<any, any>>,
|
|
104
|
+
TViews extends Record<string, ViewBuilder<any, any, any>>,
|
|
105
|
+
TProcedures extends Record<string, ProcedureBuilder<any, any>>,
|
|
106
|
+
> {
|
|
107
|
+
readonly meta: {
|
|
108
|
+
readonly tables: TTables;
|
|
109
|
+
readonly views: TViews;
|
|
110
|
+
readonly procedures: TProcedures;
|
|
111
|
+
readonly migrations: Migration[];
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## DbContextInstance
|
|
117
|
+
|
|
118
|
+
Full runtime type created by `createDbContext`. Combines `DbContextBase`, connection methods, DDL methods, and auto-mapped queryable/executable accessors.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
type DbContextInstance<TDef extends DbContextDef<any, any, any>> = DbContextBase &
|
|
122
|
+
DbContextConnectionMethods &
|
|
123
|
+
DbContextDdlMethods & {
|
|
124
|
+
[K in keyof TDef["meta"]["tables"]]: () => Queryable<...>;
|
|
125
|
+
} & {
|
|
126
|
+
[K in keyof TDef["meta"]["views"]]: () => Queryable<...>;
|
|
127
|
+
} & {
|
|
128
|
+
[K in keyof TDef["meta"]["procedures"]]: () => Executable<...>;
|
|
129
|
+
} & {
|
|
130
|
+
_migration: () => Queryable<{ code: string }, any>;
|
|
131
|
+
initialize(options?: { dbs?: string[]; force?: boolean }): Promise<void>;
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Connection Methods
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface DbContextConnectionMethods {
|
|
139
|
+
/** Execute within a transaction (auto commit/rollback) */
|
|
140
|
+
connect<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
|
|
141
|
+
|
|
142
|
+
/** Connect without transaction (for DDL or read-only operations) */
|
|
143
|
+
connectWithoutTransaction<TResult>(callback: () => Promise<TResult>): Promise<TResult>;
|
|
144
|
+
|
|
145
|
+
/** Start a transaction within an already-connected state */
|
|
146
|
+
transaction<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### DDL Methods
|
|
151
|
+
|
|
152
|
+
The instance exposes DDL execution methods and their corresponding QueryDef generators:
|
|
153
|
+
|
|
154
|
+
| Method | Description |
|
|
155
|
+
|--------|-------------|
|
|
156
|
+
| `createTable(table)` | CREATE TABLE |
|
|
157
|
+
| `dropTable(table)` | DROP TABLE |
|
|
158
|
+
| `renameTable(table, newName)` | RENAME TABLE |
|
|
159
|
+
| `createView(view)` | CREATE VIEW |
|
|
160
|
+
| `dropView(view)` | DROP VIEW |
|
|
161
|
+
| `createProc(procedure)` | CREATE PROCEDURE |
|
|
162
|
+
| `dropProc(procedure)` | DROP PROCEDURE |
|
|
163
|
+
| `addColumn(table, name, column)` | ADD COLUMN |
|
|
164
|
+
| `dropColumn(table, column)` | DROP COLUMN |
|
|
165
|
+
| `modifyColumn(table, name, column)` | MODIFY COLUMN |
|
|
166
|
+
| `renameColumn(table, column, newName)` | RENAME COLUMN |
|
|
167
|
+
| `addPrimaryKey(table, columns)` | ADD PRIMARY KEY |
|
|
168
|
+
| `dropPrimaryKey(table)` | DROP PRIMARY KEY |
|
|
169
|
+
| `addForeignKey(table, name, def)` | ADD FOREIGN KEY |
|
|
170
|
+
| `dropForeignKey(table, name)` | DROP FOREIGN KEY |
|
|
171
|
+
| `addIndex(table, indexBuilder)` | CREATE INDEX |
|
|
172
|
+
| `dropIndex(table, columns)` | DROP INDEX |
|
|
173
|
+
| `clearSchema(params)` | Clear all objects in schema |
|
|
174
|
+
| `schemaExists(database, schema?)` | Check schema existence |
|
|
175
|
+
| `truncate(table)` | TRUNCATE TABLE |
|
|
176
|
+
| `switchFk(table, enabled)` | Enable/disable FK constraints |
|
|
177
|
+
|
|
178
|
+
## DbContextStatus
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
type DbContextStatus = "ready" | "connect" | "transact";
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Lifecycle: `ready` -> `connect` -> `transact` -> `connect` -> `ready`
|
|
185
|
+
|
|
186
|
+
## DbTransactionError
|
|
187
|
+
|
|
188
|
+
Standardized transaction error wrapping DBMS-specific native errors.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
class DbTransactionError extends Error {
|
|
192
|
+
readonly name = "DbTransactionError";
|
|
193
|
+
constructor(
|
|
194
|
+
public readonly code: DbErrorCode,
|
|
195
|
+
message: string,
|
|
196
|
+
public readonly originalError?: unknown,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## DbErrorCode
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
enum DbErrorCode {
|
|
205
|
+
NO_ACTIVE_TRANSACTION = "NO_ACTIVE_TRANSACTION",
|
|
206
|
+
TRANSACTION_ALREADY_STARTED = "TRANSACTION_ALREADY_STARTED",
|
|
207
|
+
DEADLOCK = "DEADLOCK",
|
|
208
|
+
LOCK_TIMEOUT = "LOCK_TIMEOUT",
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Example:**
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
try {
|
|
216
|
+
await executor.rollbackTransaction();
|
|
217
|
+
} catch (err) {
|
|
218
|
+
if (err instanceof DbTransactionError) {
|
|
219
|
+
if (err.code === DbErrorCode.NO_ACTIVE_TRANSACTION) {
|
|
220
|
+
return; // Already rolled back
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
throw err;
|
|
224
|
+
}
|
|
225
|
+
```
|