metal-orm 1.1.10 → 1.1.16
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 +758 -769
- package/dist/index.cjs +106 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +106 -43
- package/dist/index.js.map +1 -1
- package/package.json +100 -96
- package/scripts/generate-entities/render.mjs +21 -12
- package/scripts/generate-entities/schema.mjs +209 -195
- package/scripts/generate-entities/tree-detection.mjs +159 -153
- package/scripts/inflection/pt-br.mjs +468 -468
- package/scripts/run-eslint.mjs +33 -34
- package/scripts/show-sql-seed.sql +102 -0
- package/scripts/show-sql.mjs +321 -325
- package/src/bulk/bulk-delete-executor.ts +3 -5
- package/src/bulk/bulk-insert-executor.ts +7 -7
- package/src/bulk/bulk-update-executor.ts +2 -2
- package/src/bulk/bulk-upsert-executor.ts +5 -7
- package/src/codegen/naming-strategy.ts +54 -54
- package/src/codegen/typescript.ts +482 -482
- package/src/core/ast/adapters.ts +1 -1
- package/src/core/ast/builders.ts +123 -123
- package/src/core/ast/expression-builders.ts +745 -745
- package/src/core/ast/expression-nodes.ts +304 -304
- package/src/core/ast/expression-visitor.ts +212 -212
- package/src/core/ast/expression.ts +20 -20
- package/src/core/ast/helpers.ts +14 -14
- package/src/core/ast/join.ts +18 -18
- package/src/core/ast/query.ts +200 -200
- package/src/core/ddl/dialects/base-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/render-reference.test.ts +70 -70
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -1
- package/src/core/ddl/introspect/catalogs/index.ts +5 -5
- package/src/core/ddl/introspect/catalogs/postgres.ts +146 -146
- package/src/core/ddl/introspect/context.ts +15 -15
- package/src/core/ddl/introspect/functions/postgres.ts +35 -35
- package/src/core/ddl/introspect/mysql.ts +113 -36
- package/src/core/ddl/introspect/registry.ts +40 -40
- package/src/core/ddl/introspect/run-select.ts +35 -35
- package/src/core/ddl/introspect/utils.ts +56 -56
- package/src/core/ddl/naming-strategy.ts +16 -16
- package/src/core/ddl/schema-dialect.ts +56 -56
- package/src/core/ddl/schema-diff.ts +234 -234
- package/src/core/ddl/schema-generator.ts +1 -1
- package/src/core/ddl/schema-introspect.ts +25 -25
- package/src/core/ddl/sql-writing.ts +171 -171
- package/src/core/dialect/abstract.ts +541 -541
- package/src/core/dialect/base/cte-compiler.ts +33 -33
- package/src/core/dialect/base/function-table-formatter.ts +103 -103
- package/src/core/dialect/base/groupby-compiler.ts +21 -21
- package/src/core/dialect/base/join-compiler.ts +25 -25
- package/src/core/dialect/base/orderby-compiler.ts +35 -35
- package/src/core/dialect/base/pagination-strategy.ts +32 -32
- package/src/core/dialect/base/returning-strategy.ts +57 -57
- package/src/core/dialect/base/sql-dialect.ts +294 -294
- package/src/core/dialect/dialect-factory.ts +91 -91
- package/src/core/dialect/mssql/functions.ts +120 -120
- package/src/core/dialect/mssql/index.ts +317 -317
- package/src/core/dialect/mysql/functions.ts +103 -103
- package/src/core/dialect/mysql/index.ts +105 -105
- package/src/core/dialect/postgres/functions.ts +108 -108
- package/src/core/dialect/postgres/index.ts +91 -91
- package/src/core/dialect/sqlite/functions.ts +129 -129
- package/src/core/dialect/sqlite/index.ts +67 -67
- package/src/core/driver/database-driver.ts +19 -19
- package/src/core/driver/mssql-driver.ts +23 -23
- package/src/core/driver/mysql-driver.ts +23 -23
- package/src/core/driver/postgres-driver.ts +23 -23
- package/src/core/driver/sqlite-driver.ts +23 -23
- package/src/core/execution/db-executor.ts +92 -92
- package/src/core/execution/executors/better-sqlite3-executor.ts +94 -94
- package/src/core/execution/executors/mssql-executor.ts +184 -184
- package/src/core/execution/executors/mysql-executor.ts +88 -88
- package/src/core/execution/executors/postgres-executor.ts +26 -26
- package/src/core/execution/executors/sqlite-executor.ts +42 -42
- package/src/core/execution/pooling/pool-types.ts +30 -30
- package/src/core/execution/pooling/pool.ts +275 -275
- package/src/core/functions/array.ts +35 -35
- package/src/core/functions/control-flow.ts +79 -79
- package/src/core/functions/datetime.ts +237 -237
- package/src/core/functions/json.ts +70 -70
- package/src/core/functions/numeric.ts +297 -297
- package/src/core/functions/text.ts +334 -334
- package/src/core/functions/types.ts +33 -33
- package/src/core/hydration/types.ts +51 -51
- package/src/core/sql/sql-operator-config.ts +39 -39
- package/src/core/sql/sql.ts +152 -152
- package/src/decorators/column-decorator.ts +87 -87
- package/src/decorators/decorator-metadata.ts +143 -143
- package/src/decorators/entity.ts +93 -93
- package/src/decorators/index.ts +39 -39
- package/src/decorators/relations.ts +231 -231
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -231
- package/src/decorators/transformers/transformer-decorators.ts +134 -134
- package/src/decorators/transformers/transformer-executor.ts +171 -171
- package/src/decorators/transformers/transformer-metadata.ts +73 -73
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -55
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -105
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -103
- package/src/decorators/validators/country-validator-registry.ts +64 -64
- package/src/decorators/validators/country-validators-decorators.ts +203 -203
- package/src/decorators/validators/country-validators.ts +105 -105
- package/src/decorators/validators/validator-metadata.ts +59 -59
- package/src/dto/dto-types.ts +226 -226
- package/src/dto/filter-types.ts +141 -141
- package/src/dto/index.ts +95 -95
- package/src/dto/openapi/generators/base.ts +29 -29
- package/src/dto/openapi/generators/column.ts +37 -37
- package/src/dto/openapi/generators/dto.ts +91 -91
- package/src/dto/openapi/generators/filter.ts +75 -75
- package/src/dto/openapi/generators/nested-dto.ts +618 -618
- package/src/dto/openapi/generators/pagination.ts +111 -111
- package/src/dto/openapi/generators/relation-filter.ts +228 -228
- package/src/dto/openapi/index.ts +12 -12
- package/src/dto/openapi/types.ts +101 -101
- package/src/dto/openapi/utilities.ts +95 -95
- package/src/dto/pagination-utils.ts +150 -150
- package/src/dto/transform.ts +197 -197
- package/src/index.ts +86 -86
- package/src/orm/als.ts +58 -58
- package/src/orm/domain-event-bus.ts +119 -119
- package/src/orm/entity-context.ts +86 -86
- package/src/orm/entity-materializer.ts +159 -159
- package/src/orm/entity-meta.ts +97 -97
- package/src/orm/entity-registry.ts +39 -39
- package/src/orm/entity-relation-cache.ts +39 -39
- package/src/orm/execute.ts +194 -194
- package/src/orm/execution-context.ts +18 -18
- package/src/orm/hydration-context.ts +26 -26
- package/src/orm/hydration.ts +112 -112
- package/src/orm/identity-map.ts +61 -61
- package/src/orm/interceptor-pipeline.ts +16 -16
- package/src/orm/lazy-batch/belongs-to-many.ts +119 -119
- package/src/orm/lazy-batch/belongs-to.ts +108 -108
- package/src/orm/lazy-batch/has-many.ts +69 -69
- package/src/orm/lazy-batch/has-one.ts +68 -68
- package/src/orm/lazy-batch/shared.ts +125 -125
- package/src/orm/orm-session.ts +620 -620
- package/src/orm/orm.ts +34 -34
- package/src/orm/pooled-executor-factory.ts +121 -121
- package/src/orm/query-logger.ts +40 -40
- package/src/orm/relation-change-processor.ts +420 -420
- package/src/orm/relations/belongs-to.ts +143 -143
- package/src/orm/relations/has-many.ts +204 -204
- package/src/orm/relations/has-one.ts +174 -174
- package/src/orm/relations/many-to-many.ts +288 -288
- package/src/orm/relations/morph-many.ts +156 -156
- package/src/orm/relations/morph-one.ts +151 -151
- package/src/orm/relations/morph-to.ts +162 -162
- package/src/orm/runtime-types.ts +92 -92
- package/src/orm/save-graph.ts +561 -561
- package/src/orm/transaction-runner.ts +24 -24
- package/src/orm/unit-of-work.ts +426 -426
- package/src/query/index.ts +69 -69
- package/src/query/target.ts +46 -46
- package/src/query-builder/column-selector.ts +81 -81
- package/src/query-builder/delete.ts +141 -141
- package/src/query-builder/insert-query-state.ts +149 -149
- package/src/query-builder/insert.ts +117 -117
- package/src/query-builder/query-ast-service.ts +287 -287
- package/src/query-builder/query-resolution.ts +78 -78
- package/src/query-builder/raw-column-parser.ts +38 -38
- package/src/query-builder/relation-filter-utils.ts +153 -153
- package/src/query-builder/relation-join-planner.ts +10 -10
- package/src/query-builder/relation-manager.ts +87 -87
- package/src/query-builder/relation-projection-helper.ts +102 -102
- package/src/query-builder/relation-types.ts +9 -9
- package/src/query-builder/relation-utils.ts +15 -15
- package/src/query-builder/select/cte-facet.ts +40 -40
- package/src/query-builder/select/from-facet.ts +80 -80
- package/src/query-builder/select/join-facet.ts +62 -62
- package/src/query-builder/select/predicate-facet.ts +104 -104
- package/src/query-builder/select/projection-facet.ts +70 -70
- package/src/query-builder/select/relation-facet.ts +81 -81
- package/src/query-builder/select/setop-facet.ts +36 -36
- package/src/query-builder/select-helpers.ts +1 -1
- package/src/query-builder/select-query-builder-deps.ts +130 -130
- package/src/query-builder/select-query-state.ts +207 -207
- package/src/query-builder/update.ts +151 -151
- package/src/schema/column-types.ts +322 -322
- package/src/schema/table-guards.ts +37 -37
- package/src/schema/table.ts +281 -281
- package/src/tree/index.ts +13 -13
- package/src/tree/nested-set-strategy.ts +545 -545
- package/src/tree/tree-decorator.ts +397 -397
- package/src/tree/tree-manager.ts +754 -754
- package/src/tree/tree-query.ts +427 -427
- package/src/tree/tree-types.ts +299 -299
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
-
import { SqlServerDialect } from '../dialect/mssql/index.js';
|
|
3
|
-
import { MSSqlSchemaDialect } from '../ddl/dialects/mssql-schema-dialect.js';
|
|
4
|
-
import { mssqlIntrospector } from '../ddl/introspect/mssql.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Database driver for Microsoft SQL Server.
|
|
8
|
-
*/
|
|
9
|
-
export class MssqlDriver implements DatabaseDriver {
|
|
10
|
-
readonly name = 'mssql';
|
|
11
|
-
|
|
12
|
-
createDialect() {
|
|
13
|
-
return new SqlServerDialect();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createSchemaDialect() {
|
|
17
|
-
return new MSSqlSchemaDialect();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
createIntrospector() {
|
|
21
|
-
return mssqlIntrospector;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
+
import { SqlServerDialect } from '../dialect/mssql/index.js';
|
|
3
|
+
import { MSSqlSchemaDialect } from '../ddl/dialects/mssql-schema-dialect.js';
|
|
4
|
+
import { mssqlIntrospector } from '../ddl/introspect/mssql.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Database driver for Microsoft SQL Server.
|
|
8
|
+
*/
|
|
9
|
+
export class MssqlDriver implements DatabaseDriver {
|
|
10
|
+
readonly name = 'mssql';
|
|
11
|
+
|
|
12
|
+
createDialect() {
|
|
13
|
+
return new SqlServerDialect();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createSchemaDialect() {
|
|
17
|
+
return new MSSqlSchemaDialect();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
createIntrospector() {
|
|
21
|
+
return mssqlIntrospector;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
-
import { MySqlDialect } from '../dialect/mysql/index.js';
|
|
3
|
-
import { MySqlSchemaDialect } from '../ddl/dialects/mysql-schema-dialect.js';
|
|
4
|
-
import { mysqlIntrospector } from '../ddl/introspect/mysql.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Database driver for MySQL.
|
|
8
|
-
*/
|
|
9
|
-
export class MySqlDriver implements DatabaseDriver {
|
|
10
|
-
readonly name = 'mysql';
|
|
11
|
-
|
|
12
|
-
createDialect() {
|
|
13
|
-
return new MySqlDialect();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createSchemaDialect() {
|
|
17
|
-
return new MySqlSchemaDialect();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
createIntrospector() {
|
|
21
|
-
return mysqlIntrospector;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
+
import { MySqlDialect } from '../dialect/mysql/index.js';
|
|
3
|
+
import { MySqlSchemaDialect } from '../ddl/dialects/mysql-schema-dialect.js';
|
|
4
|
+
import { mysqlIntrospector } from '../ddl/introspect/mysql.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Database driver for MySQL.
|
|
8
|
+
*/
|
|
9
|
+
export class MySqlDriver implements DatabaseDriver {
|
|
10
|
+
readonly name = 'mysql';
|
|
11
|
+
|
|
12
|
+
createDialect() {
|
|
13
|
+
return new MySqlDialect();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createSchemaDialect() {
|
|
17
|
+
return new MySqlSchemaDialect();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
createIntrospector() {
|
|
21
|
+
return mysqlIntrospector;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
-
import { PostgresDialect } from '../dialect/postgres/index.js';
|
|
3
|
-
import { PostgresSchemaDialect } from '../ddl/dialects/postgres-schema-dialect.js';
|
|
4
|
-
import { postgresIntrospector } from '../ddl/introspect/postgres.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Database driver for PostgreSQL.
|
|
8
|
-
*/
|
|
9
|
-
export class PostgresDriver implements DatabaseDriver {
|
|
10
|
-
readonly name = 'postgres';
|
|
11
|
-
|
|
12
|
-
createDialect() {
|
|
13
|
-
return new PostgresDialect();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createSchemaDialect() {
|
|
17
|
-
return new PostgresSchemaDialect();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
createIntrospector() {
|
|
21
|
-
return postgresIntrospector;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
+
import { PostgresDialect } from '../dialect/postgres/index.js';
|
|
3
|
+
import { PostgresSchemaDialect } from '../ddl/dialects/postgres-schema-dialect.js';
|
|
4
|
+
import { postgresIntrospector } from '../ddl/introspect/postgres.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Database driver for PostgreSQL.
|
|
8
|
+
*/
|
|
9
|
+
export class PostgresDriver implements DatabaseDriver {
|
|
10
|
+
readonly name = 'postgres';
|
|
11
|
+
|
|
12
|
+
createDialect() {
|
|
13
|
+
return new PostgresDialect();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createSchemaDialect() {
|
|
17
|
+
return new PostgresSchemaDialect();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
createIntrospector() {
|
|
21
|
+
return postgresIntrospector;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
-
import { SqliteDialect } from '../dialect/sqlite/index.js';
|
|
3
|
-
import { SQLiteSchemaDialect } from '../ddl/dialects/sqlite-schema-dialect.js';
|
|
4
|
-
import { sqliteIntrospector } from '../ddl/introspect/sqlite.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Database driver for SQLite.
|
|
8
|
-
*/
|
|
9
|
-
export class SqliteDriver implements DatabaseDriver {
|
|
10
|
-
readonly name = 'sqlite';
|
|
11
|
-
|
|
12
|
-
createDialect() {
|
|
13
|
-
return new SqliteDialect();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createSchemaDialect() {
|
|
17
|
-
return new SQLiteSchemaDialect();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
createIntrospector() {
|
|
21
|
-
return sqliteIntrospector;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
import { DatabaseDriver } from './database-driver.js';
|
|
2
|
+
import { SqliteDialect } from '../dialect/sqlite/index.js';
|
|
3
|
+
import { SQLiteSchemaDialect } from '../ddl/dialects/sqlite-schema-dialect.js';
|
|
4
|
+
import { sqliteIntrospector } from '../ddl/introspect/sqlite.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Database driver for SQLite.
|
|
8
|
+
*/
|
|
9
|
+
export class SqliteDriver implements DatabaseDriver {
|
|
10
|
+
readonly name = 'sqlite';
|
|
11
|
+
|
|
12
|
+
createDialect() {
|
|
13
|
+
return new SqliteDialect();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createSchemaDialect() {
|
|
17
|
+
return new SQLiteSchemaDialect();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
createIntrospector() {
|
|
21
|
+
return sqliteIntrospector;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
// src/core/execution/db-executor.ts
|
|
2
|
-
|
|
3
|
-
// low-level canonical shape
|
|
4
|
-
export type QueryResult = {
|
|
5
|
-
columns: string[];
|
|
6
|
-
values: unknown[][];
|
|
7
|
-
meta?: {
|
|
8
|
-
insertId?: number | string;
|
|
9
|
-
rowsAffected?: number;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Canonical execution payload.
|
|
15
|
-
* It remains array-compatible for a gradual migration but always exposes
|
|
16
|
-
* `resultSets` for explicit multi-result handling.
|
|
17
|
-
*/
|
|
18
|
-
export type ExecutionPayload = QueryResult[] & {
|
|
19
|
-
resultSets?: QueryResult[];
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const toExecutionPayload = (resultSets: QueryResult[]): ExecutionPayload => {
|
|
23
|
-
const payload = resultSets as ExecutionPayload;
|
|
24
|
-
payload.resultSets = resultSets;
|
|
25
|
-
return payload;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const payloadResultSets = (payload: ExecutionPayload): QueryResult[] =>
|
|
29
|
-
payload.resultSets ?? payload;
|
|
30
|
-
|
|
1
|
+
// src/core/execution/db-executor.ts
|
|
2
|
+
|
|
3
|
+
// low-level canonical shape
|
|
4
|
+
export type QueryResult = {
|
|
5
|
+
columns: string[];
|
|
6
|
+
values: unknown[][];
|
|
7
|
+
meta?: {
|
|
8
|
+
insertId?: number | string;
|
|
9
|
+
rowsAffected?: number;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Canonical execution payload.
|
|
15
|
+
* It remains array-compatible for a gradual migration but always exposes
|
|
16
|
+
* `resultSets` for explicit multi-result handling.
|
|
17
|
+
*/
|
|
18
|
+
export type ExecutionPayload = QueryResult[] & {
|
|
19
|
+
resultSets?: QueryResult[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const toExecutionPayload = (resultSets: QueryResult[]): ExecutionPayload => {
|
|
23
|
+
const payload = resultSets as ExecutionPayload;
|
|
24
|
+
payload.resultSets = resultSets;
|
|
25
|
+
return payload;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const payloadResultSets = (payload: ExecutionPayload): QueryResult[] =>
|
|
29
|
+
payload.resultSets ?? payload;
|
|
30
|
+
|
|
31
31
|
export interface DbExecutor {
|
|
32
32
|
/** Capability flags so the runtime can make correct decisions without relying on optional methods. */
|
|
33
33
|
readonly capabilities: {
|
|
@@ -36,46 +36,46 @@ export interface DbExecutor {
|
|
|
36
36
|
/** True if savepoint/release/rollback-to-savepoint are implemented. */
|
|
37
37
|
savepoints?: boolean;
|
|
38
38
|
};
|
|
39
|
-
|
|
40
|
-
executeSql(sql: string, params?: unknown[]): Promise<ExecutionPayload>;
|
|
41
|
-
|
|
39
|
+
|
|
40
|
+
executeSql(sql: string, params?: unknown[]): Promise<ExecutionPayload>;
|
|
41
|
+
|
|
42
42
|
beginTransaction(): Promise<void>;
|
|
43
43
|
commitTransaction(): Promise<void>;
|
|
44
44
|
rollbackTransaction(): Promise<void>;
|
|
45
45
|
savepoint?(name: string): Promise<void>;
|
|
46
46
|
releaseSavepoint?(name: string): Promise<void>;
|
|
47
47
|
rollbackToSavepoint?(name: string): Promise<void>;
|
|
48
|
-
|
|
49
|
-
/** Release any underlying resources (connections, pool leases, etc). Must be idempotent. */
|
|
50
|
-
dispose(): Promise<void>;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// --- helpers ---
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Convert an array of row objects into a QueryResult.
|
|
57
|
-
*/
|
|
58
|
-
export function rowsToQueryResult(
|
|
59
|
-
rows: Array<Record<string, unknown>>
|
|
60
|
-
): QueryResult {
|
|
61
|
-
if (rows.length === 0) {
|
|
62
|
-
return { columns: [], values: [] };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const columns = Object.keys(rows[0]);
|
|
66
|
-
const values = rows.map(row => columns.map(c => row[c]));
|
|
67
|
-
return { columns, values };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Minimal contract that most SQL clients can implement.
|
|
72
|
-
*/
|
|
73
|
-
export interface SimpleQueryRunner {
|
|
74
|
-
query(
|
|
75
|
-
sql: string,
|
|
76
|
-
params?: unknown[]
|
|
77
|
-
): Promise<Array<Record<string, unknown>>>;
|
|
78
|
-
|
|
48
|
+
|
|
49
|
+
/** Release any underlying resources (connections, pool leases, etc). Must be idempotent. */
|
|
50
|
+
dispose(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// --- helpers ---
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Convert an array of row objects into a QueryResult.
|
|
57
|
+
*/
|
|
58
|
+
export function rowsToQueryResult(
|
|
59
|
+
rows: Array<Record<string, unknown>>
|
|
60
|
+
): QueryResult {
|
|
61
|
+
if (rows.length === 0) {
|
|
62
|
+
return { columns: [], values: [] };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const columns = Object.keys(rows[0]);
|
|
66
|
+
const values = rows.map(row => columns.map(c => row[c]));
|
|
67
|
+
return { columns, values };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Minimal contract that most SQL clients can implement.
|
|
72
|
+
*/
|
|
73
|
+
export interface SimpleQueryRunner {
|
|
74
|
+
query(
|
|
75
|
+
sql: string,
|
|
76
|
+
params?: unknown[]
|
|
77
|
+
): Promise<Array<Record<string, unknown>>>;
|
|
78
|
+
|
|
79
79
|
/** Optional: used to support real transactions. */
|
|
80
80
|
beginTransaction?(): Promise<void>;
|
|
81
81
|
commitTransaction?(): Promise<void>;
|
|
@@ -83,17 +83,17 @@ export interface SimpleQueryRunner {
|
|
|
83
83
|
savepoint?(name: string): Promise<void>;
|
|
84
84
|
releaseSavepoint?(name: string): Promise<void>;
|
|
85
85
|
rollbackToSavepoint?(name: string): Promise<void>;
|
|
86
|
-
|
|
87
|
-
/** Optional: release resources (connection close, pool lease release, etc). */
|
|
88
|
-
dispose?(): Promise<void>;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Generic factory: turn any SimpleQueryRunner into a DbExecutor.
|
|
93
|
-
*/
|
|
94
|
-
export function createExecutorFromQueryRunner(
|
|
95
|
-
runner: SimpleQueryRunner
|
|
96
|
-
): DbExecutor {
|
|
86
|
+
|
|
87
|
+
/** Optional: release resources (connection close, pool lease release, etc). */
|
|
88
|
+
dispose?(): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Generic factory: turn any SimpleQueryRunner into a DbExecutor.
|
|
93
|
+
*/
|
|
94
|
+
export function createExecutorFromQueryRunner(
|
|
95
|
+
runner: SimpleQueryRunner
|
|
96
|
+
): DbExecutor {
|
|
97
97
|
const supportsTransactions =
|
|
98
98
|
typeof runner.beginTransaction === 'function' &&
|
|
99
99
|
typeof runner.commitTransaction === 'function' &&
|
|
@@ -109,23 +109,23 @@ export function createExecutorFromQueryRunner(
|
|
|
109
109
|
transactions: supportsTransactions,
|
|
110
110
|
...(supportsSavepoints ? { savepoints: true } : {}),
|
|
111
111
|
},
|
|
112
|
-
async executeSql(sql, params) {
|
|
113
|
-
const rows = await runner.query(sql, params);
|
|
114
|
-
const result = rowsToQueryResult(rows);
|
|
115
|
-
return toExecutionPayload([result]);
|
|
116
|
-
},
|
|
117
|
-
async beginTransaction() {
|
|
118
|
-
if (!supportsTransactions) {
|
|
119
|
-
throw new Error('Transactions are not supported by this executor');
|
|
120
|
-
}
|
|
121
|
-
await runner.beginTransaction!.call(runner);
|
|
122
|
-
},
|
|
123
|
-
async commitTransaction() {
|
|
124
|
-
if (!supportsTransactions) {
|
|
125
|
-
throw new Error('Transactions are not supported by this executor');
|
|
126
|
-
}
|
|
127
|
-
await runner.commitTransaction!.call(runner);
|
|
128
|
-
},
|
|
112
|
+
async executeSql(sql, params) {
|
|
113
|
+
const rows = await runner.query(sql, params);
|
|
114
|
+
const result = rowsToQueryResult(rows);
|
|
115
|
+
return toExecutionPayload([result]);
|
|
116
|
+
},
|
|
117
|
+
async beginTransaction() {
|
|
118
|
+
if (!supportsTransactions) {
|
|
119
|
+
throw new Error('Transactions are not supported by this executor');
|
|
120
|
+
}
|
|
121
|
+
await runner.beginTransaction!.call(runner);
|
|
122
|
+
},
|
|
123
|
+
async commitTransaction() {
|
|
124
|
+
if (!supportsTransactions) {
|
|
125
|
+
throw new Error('Transactions are not supported by this executor');
|
|
126
|
+
}
|
|
127
|
+
await runner.commitTransaction!.call(runner);
|
|
128
|
+
},
|
|
129
129
|
async rollbackTransaction() {
|
|
130
130
|
if (!supportsTransactions) {
|
|
131
131
|
throw new Error('Transactions are not supported by this executor');
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
// src/core/execution/executors/better-sqlite3-executor.ts
|
|
2
|
-
import {
|
|
3
|
-
DbExecutor,
|
|
4
|
-
toExecutionPayload,
|
|
5
|
-
rowsToQueryResult,
|
|
6
|
-
QueryResult
|
|
7
|
-
} from '../db-executor.js';
|
|
8
|
-
|
|
9
|
-
export interface BetterSqlite3Statement {
|
|
10
|
-
reader: boolean;
|
|
11
|
-
all(...params: unknown[]): unknown[];
|
|
12
|
-
run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface BetterSqlite3ClientLike {
|
|
16
|
-
prepare(sql: string): BetterSqlite3Statement;
|
|
17
|
-
transaction<T extends (...args:
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
21
|
-
|
|
22
|
-
const sanitizeSavepointName = (name: string): string => {
|
|
23
|
-
const trimmed = name.trim();
|
|
24
|
-
if (!SAVEPOINT_NAME_PATTERN.test(trimmed)) {
|
|
25
|
-
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
26
|
-
}
|
|
27
|
-
return trimmed;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Creates a database executor for better-sqlite3.
|
|
32
|
-
* @param client A better-sqlite3 database instance.
|
|
33
|
-
* @returns A DbExecutor implementation for better-sqlite3.
|
|
34
|
-
*/
|
|
35
|
-
export function createBetterSqlite3Executor(
|
|
36
|
-
client: BetterSqlite3ClientLike
|
|
37
|
-
): DbExecutor {
|
|
38
|
-
// better-sqlite3 handles nested transactions using savepoints automatically
|
|
39
|
-
// when using .transaction(), but DbExecutor needs explicit control.
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
capabilities: {
|
|
43
|
-
transactions: true,
|
|
44
|
-
savepoints: true,
|
|
45
|
-
},
|
|
46
|
-
async executeSql(sql, params) {
|
|
47
|
-
const stmt = client.prepare(sql);
|
|
48
|
-
let result: QueryResult;
|
|
49
|
-
|
|
50
|
-
if (stmt.reader) {
|
|
51
|
-
const rows = stmt.all(...(params ?? [])) as Record<string, unknown>[];
|
|
52
|
-
result = rowsToQueryResult(rows);
|
|
53
|
-
} else {
|
|
54
|
-
const info = stmt.run(...(params ?? []));
|
|
55
|
-
result = {
|
|
56
|
-
columns: [],
|
|
57
|
-
values: [],
|
|
58
|
-
meta: {
|
|
59
|
-
rowsAffected: info.changes,
|
|
60
|
-
insertId: typeof info.lastInsertRowid === 'bigint'
|
|
61
|
-
? info.lastInsertRowid.toString()
|
|
62
|
-
: info.lastInsertRowid
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return toExecutionPayload([result]);
|
|
68
|
-
},
|
|
69
|
-
async beginTransaction() {
|
|
70
|
-
client.prepare('BEGIN').run();
|
|
71
|
-
},
|
|
72
|
-
async commitTransaction() {
|
|
73
|
-
client.prepare('COMMIT').run();
|
|
74
|
-
},
|
|
75
|
-
async rollbackTransaction() {
|
|
76
|
-
client.prepare('ROLLBACK').run();
|
|
77
|
-
},
|
|
78
|
-
async savepoint(name: string) {
|
|
79
|
-
const savepoint = sanitizeSavepointName(name);
|
|
80
|
-
client.prepare(`SAVEPOINT ${savepoint}`).run();
|
|
81
|
-
},
|
|
82
|
-
async releaseSavepoint(name: string) {
|
|
83
|
-
const savepoint = sanitizeSavepointName(name);
|
|
84
|
-
client.prepare(`RELEASE SAVEPOINT ${savepoint}`).run();
|
|
85
|
-
},
|
|
86
|
-
async rollbackToSavepoint(name: string) {
|
|
87
|
-
const savepoint = sanitizeSavepointName(name);
|
|
88
|
-
client.prepare(`ROLLBACK TO SAVEPOINT ${savepoint}`).run();
|
|
89
|
-
},
|
|
90
|
-
async dispose() {
|
|
91
|
-
// Connection lifecycle is owned by the caller.
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
}
|
|
1
|
+
// src/core/execution/executors/better-sqlite3-executor.ts
|
|
2
|
+
import {
|
|
3
|
+
DbExecutor,
|
|
4
|
+
toExecutionPayload,
|
|
5
|
+
rowsToQueryResult,
|
|
6
|
+
QueryResult
|
|
7
|
+
} from '../db-executor.js';
|
|
8
|
+
|
|
9
|
+
export interface BetterSqlite3Statement {
|
|
10
|
+
reader: boolean;
|
|
11
|
+
all(...params: unknown[]): unknown[];
|
|
12
|
+
run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BetterSqlite3ClientLike {
|
|
16
|
+
prepare(sql: string): BetterSqlite3Statement;
|
|
17
|
+
transaction<T extends (...args: unknown[]) => unknown>(fn: T): T;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
21
|
+
|
|
22
|
+
const sanitizeSavepointName = (name: string): string => {
|
|
23
|
+
const trimmed = name.trim();
|
|
24
|
+
if (!SAVEPOINT_NAME_PATTERN.test(trimmed)) {
|
|
25
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
26
|
+
}
|
|
27
|
+
return trimmed;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a database executor for better-sqlite3.
|
|
32
|
+
* @param client A better-sqlite3 database instance.
|
|
33
|
+
* @returns A DbExecutor implementation for better-sqlite3.
|
|
34
|
+
*/
|
|
35
|
+
export function createBetterSqlite3Executor(
|
|
36
|
+
client: BetterSqlite3ClientLike
|
|
37
|
+
): DbExecutor {
|
|
38
|
+
// better-sqlite3 handles nested transactions using savepoints automatically
|
|
39
|
+
// when using .transaction(), but DbExecutor needs explicit control.
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
capabilities: {
|
|
43
|
+
transactions: true,
|
|
44
|
+
savepoints: true,
|
|
45
|
+
},
|
|
46
|
+
async executeSql(sql, params) {
|
|
47
|
+
const stmt = client.prepare(sql);
|
|
48
|
+
let result: QueryResult;
|
|
49
|
+
|
|
50
|
+
if (stmt.reader) {
|
|
51
|
+
const rows = stmt.all(...(params ?? [])) as Record<string, unknown>[];
|
|
52
|
+
result = rowsToQueryResult(rows);
|
|
53
|
+
} else {
|
|
54
|
+
const info = stmt.run(...(params ?? []));
|
|
55
|
+
result = {
|
|
56
|
+
columns: [],
|
|
57
|
+
values: [],
|
|
58
|
+
meta: {
|
|
59
|
+
rowsAffected: info.changes,
|
|
60
|
+
insertId: typeof info.lastInsertRowid === 'bigint'
|
|
61
|
+
? info.lastInsertRowid.toString()
|
|
62
|
+
: info.lastInsertRowid
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return toExecutionPayload([result]);
|
|
68
|
+
},
|
|
69
|
+
async beginTransaction() {
|
|
70
|
+
client.prepare('BEGIN').run();
|
|
71
|
+
},
|
|
72
|
+
async commitTransaction() {
|
|
73
|
+
client.prepare('COMMIT').run();
|
|
74
|
+
},
|
|
75
|
+
async rollbackTransaction() {
|
|
76
|
+
client.prepare('ROLLBACK').run();
|
|
77
|
+
},
|
|
78
|
+
async savepoint(name: string) {
|
|
79
|
+
const savepoint = sanitizeSavepointName(name);
|
|
80
|
+
client.prepare(`SAVEPOINT ${savepoint}`).run();
|
|
81
|
+
},
|
|
82
|
+
async releaseSavepoint(name: string) {
|
|
83
|
+
const savepoint = sanitizeSavepointName(name);
|
|
84
|
+
client.prepare(`RELEASE SAVEPOINT ${savepoint}`).run();
|
|
85
|
+
},
|
|
86
|
+
async rollbackToSavepoint(name: string) {
|
|
87
|
+
const savepoint = sanitizeSavepointName(name);
|
|
88
|
+
client.prepare(`ROLLBACK TO SAVEPOINT ${savepoint}`).run();
|
|
89
|
+
},
|
|
90
|
+
async dispose() {
|
|
91
|
+
// Connection lifecycle is owned by the caller.
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|