metal-orm 1.1.24 → 1.1.25

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.
Files changed (31) hide show
  1. package/dist/index.cjs +539 -412
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +225 -176
  4. package/dist/index.d.ts +225 -176
  5. package/dist/index.js +519 -412
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/core/dialect/base/returning-strategy.ts +40 -39
  9. package/src/core/dialect/base/sql-compiler-set.ts +33 -0
  10. package/src/core/dialect/base/sql-dialect.ts +79 -38
  11. package/src/core/dialect/base/upsert-strategy.ts +45 -0
  12. package/src/core/dialect/capabilities/procedure-compiler.ts +10 -8
  13. package/src/core/dialect/mssql/compiler-factory.ts +12 -0
  14. package/src/core/dialect/mssql/delete-compiler.ts +40 -0
  15. package/src/core/dialect/mssql/index.ts +24 -371
  16. package/src/core/dialect/mssql/insert-compiler.ts +112 -0
  17. package/src/core/dialect/mssql/output.ts +46 -0
  18. package/src/core/dialect/mssql/procedure-compiler.ts +81 -0
  19. package/src/core/dialect/mssql/select-compiler.ts +116 -0
  20. package/src/core/dialect/mssql/update-compiler.ts +37 -0
  21. package/src/core/dialect/mysql/index.ts +24 -117
  22. package/src/core/dialect/mysql/procedure-compiler.ts +67 -0
  23. package/src/core/dialect/mysql/upsert.ts +42 -0
  24. package/src/core/dialect/postgres/index.ts +34 -101
  25. package/src/core/dialect/postgres/procedure-compiler.ts +41 -0
  26. package/src/core/dialect/postgres/returning.ts +4 -0
  27. package/src/core/dialect/postgres/upsert.ts +43 -0
  28. package/src/core/dialect/sqlite/index.ts +15 -70
  29. package/src/core/dialect/sqlite/returning.ts +30 -0
  30. package/src/core/dialect/sqlite/upsert.ts +43 -0
  31. package/src/index.ts +22 -10
@@ -0,0 +1,43 @@
1
+ import type { CompilerContext } from '../abstract.js';
2
+ import type { InsertQueryNode } from '../../ast/query.js';
3
+ import type {
4
+ UpsertCompilationServices,
5
+ UpsertStrategy
6
+ } from '../base/upsert-strategy.js';
7
+
8
+ export class PostgresUpsertStrategy implements UpsertStrategy {
9
+ compile(
10
+ ast: InsertQueryNode,
11
+ ctx: CompilerContext,
12
+ services: UpsertCompilationServices
13
+ ): string {
14
+ if (!ast.onConflict) return '';
15
+
16
+ const clause = ast.onConflict;
17
+ const target = clause.target.constraint
18
+ ? ` ON CONFLICT ON CONSTRAINT ${services.quoteIdentifier(clause.target.constraint)}`
19
+ : (() => {
20
+ if (!clause.target.columns.length) {
21
+ throw new Error('PostgreSQL ON CONFLICT requires conflict columns or a constraint name.');
22
+ }
23
+ const columns = clause.target.columns
24
+ .map(column => services.quoteIdentifier(column.name))
25
+ .join(', ');
26
+ return ` ON CONFLICT (${columns})`;
27
+ })();
28
+
29
+ if (clause.action.type === 'DoNothing') {
30
+ return `${target} DO NOTHING`;
31
+ }
32
+
33
+ if (!clause.action.set.length) {
34
+ throw new Error('PostgreSQL ON CONFLICT DO UPDATE requires at least one assignment.');
35
+ }
36
+
37
+ const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
38
+ const where = clause.action.where
39
+ ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}`
40
+ : '';
41
+ return `${target} DO UPDATE SET ${assignments}${where}`;
42
+ }
43
+ }
@@ -1,19 +1,22 @@
1
- import { CompilerContext } from '../abstract.js';
2
- import { JsonPathNode, ColumnNode, BitwiseExpressionNode } from '../../ast/expression.js';
3
- import { InsertQueryNode, TableNode } from '../../ast/query.js';
1
+ import type { BitwiseExpressionNode, ColumnNode, JsonPathNode } from '../../ast/expression.js';
2
+ import type { TableNode } from '../../ast/query.js';
4
3
  import { SqlDialectBase } from '../base/sql-dialect.js';
5
4
  import { SqliteFunctionStrategy } from './functions.js';
5
+ import { SqliteReturningStrategy } from './returning.js';
6
+ import { SqliteUpsertStrategy } from './upsert.js';
6
7
 
7
- /**
8
- * SQLite dialect implementation
9
- */
8
+ /** SQLite dialect assembled from reusable compiler components. */
10
9
  export class SqliteDialect extends SqlDialectBase {
11
10
  protected readonly dialect = 'sqlite';
12
- /**
13
- * Creates a new SqliteDialect instance
14
- */
11
+
15
12
  public constructor() {
16
- super(new SqliteFunctionStrategy());
13
+ super({
14
+ functionStrategy: new SqliteFunctionStrategy(),
15
+ returningStrategy: new SqliteReturningStrategy(),
16
+ upsertStrategy: new SqliteUpsertStrategy(),
17
+ supportsDmlReturning: true
18
+ });
19
+
17
20
  this.registerExpressionCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
18
21
  const left = this.compileOperand(node.left, ctx);
19
22
  const right = this.compileOperand(node.right, ctx);
@@ -32,75 +35,17 @@ export class SqliteDialect extends SqlDialectBase {
32
35
  });
33
36
  }
34
37
 
35
- /**
36
- * Quotes an identifier using SQLite double-quote syntax
37
- * @param id - Identifier to quote
38
- * @returns Quoted identifier
39
- */
40
38
  quoteIdentifier(id: string): string {
41
39
  return `"${id}"`;
42
40
  }
43
41
 
44
- /**
45
- * Compiles JSON path expression using SQLite syntax
46
- * @param node - JSON path node
47
- * @returns SQLite JSON path expression
48
- */
49
42
  protected compileJsonPath(node: JsonPathNode): string {
50
- const col = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
51
- // SQLite uses json_extract(col, '$.path')
52
- return `json_extract(${col}, '${node.path}')`;
43
+ const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
44
+ return `json_extract(${column}, '${node.path}')`;
53
45
  }
54
46
 
55
47
  protected compileQualifiedColumn(column: ColumnNode, _table: TableNode): string {
56
48
  void _table;
57
49
  return this.quoteIdentifier(column.name);
58
50
  }
59
-
60
- protected compileReturning(returning: ColumnNode[] | undefined, ctx: CompilerContext): string {
61
- void ctx;
62
- if (!returning || returning.length === 0) return '';
63
- const columns = this.formatReturningColumns(returning);
64
- return ` RETURNING ${columns}`;
65
- }
66
-
67
- protected formatReturningColumns(returning: ColumnNode[]): string {
68
- return returning
69
- .map(column => {
70
- const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : '';
71
- return `${this.quoteIdentifier(column.name)}${alias}`;
72
- })
73
- .join(', ');
74
- }
75
-
76
- protected compileUpsertClause(ast: InsertQueryNode, ctx: CompilerContext): string {
77
- if (!ast.onConflict) return '';
78
-
79
- const clause = ast.onConflict;
80
- if (clause.target.constraint) {
81
- throw new Error('SQLite ON CONFLICT does not support named constraints.');
82
- }
83
- this.ensureConflictColumns(clause, 'SQLite ON CONFLICT requires conflict columns.');
84
-
85
- const cols = clause.target.columns.map(col => this.quoteIdentifier(col.name)).join(', ');
86
- const target = ` ON CONFLICT (${cols})`;
87
-
88
- if (clause.action.type === 'DoNothing') {
89
- return `${target} DO NOTHING`;
90
- }
91
-
92
- if (!clause.action.set.length) {
93
- throw new Error('SQLite ON CONFLICT DO UPDATE requires at least one assignment.');
94
- }
95
-
96
- const assignments = this.compileUpdateAssignments(clause.action.set, ast.into, ctx);
97
- const where = clause.action.where
98
- ? ` WHERE ${this.compileExpression(clause.action.where, ctx)}`
99
- : '';
100
- return `${target} DO UPDATE SET ${assignments}${where}`;
101
- }
102
-
103
- supportsDmlReturningClause(): boolean {
104
- return true;
105
- }
106
51
  }
@@ -0,0 +1,30 @@
1
+ import type { ColumnNode } from '../../ast/expression.js';
2
+ import type { CompilerContext } from '../abstract.js';
3
+ import type {
4
+ QuoteIdentifier,
5
+ ReturningStrategy
6
+ } from '../base/returning-strategy.js';
7
+
8
+ export class SqliteReturningStrategy implements ReturningStrategy {
9
+ compileReturning(
10
+ returning: ColumnNode[] | undefined,
11
+ _ctx: CompilerContext,
12
+ quoteIdentifier: QuoteIdentifier
13
+ ): string {
14
+ void _ctx;
15
+ if (!returning || returning.length === 0) return '';
16
+ return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
17
+ }
18
+
19
+ formatReturningColumns(
20
+ returning: ColumnNode[],
21
+ quoteIdentifier: QuoteIdentifier
22
+ ): string {
23
+ return returning
24
+ .map(column => {
25
+ const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : '';
26
+ return `${quoteIdentifier(column.name)}${alias}`;
27
+ })
28
+ .join(', ');
29
+ }
30
+ }
@@ -0,0 +1,43 @@
1
+ import type { CompilerContext } from '../abstract.js';
2
+ import type { InsertQueryNode } from '../../ast/query.js';
3
+ import type {
4
+ UpsertCompilationServices,
5
+ UpsertStrategy
6
+ } from '../base/upsert-strategy.js';
7
+
8
+ export class SqliteUpsertStrategy implements UpsertStrategy {
9
+ compile(
10
+ ast: InsertQueryNode,
11
+ ctx: CompilerContext,
12
+ services: UpsertCompilationServices
13
+ ): string {
14
+ if (!ast.onConflict) return '';
15
+
16
+ const clause = ast.onConflict;
17
+ if (clause.target.constraint) {
18
+ throw new Error('SQLite ON CONFLICT does not support named constraints.');
19
+ }
20
+ if (!clause.target.columns.length) {
21
+ throw new Error('SQLite ON CONFLICT requires conflict columns.');
22
+ }
23
+
24
+ const columns = clause.target.columns
25
+ .map(column => services.quoteIdentifier(column.name))
26
+ .join(', ');
27
+ const target = ` ON CONFLICT (${columns})`;
28
+
29
+ if (clause.action.type === 'DoNothing') {
30
+ return `${target} DO NOTHING`;
31
+ }
32
+
33
+ if (!clause.action.set.length) {
34
+ throw new Error('SQLite ON CONFLICT DO UPDATE requires at least one assignment.');
35
+ }
36
+
37
+ const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
38
+ const where = clause.action.where
39
+ ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}`
40
+ : '';
41
+ return `${target} DO UPDATE SET ${assignments}${where}`;
42
+ }
43
+ }
package/src/index.ts CHANGED
@@ -20,16 +20,37 @@ export * from './core/hydration/types.js';
20
20
  export * from './core/dialect/abstract.js';
21
21
  export * from './core/dialect/dialect-factory.js';
22
22
  export * from './core/dialect/capabilities/procedure-compiler.js';
23
+ export * from './core/dialect/base/sql-dialect.js';
24
+ export * from './core/dialect/base/sql-compiler-set.js';
25
+ export * from './core/dialect/base/upsert-strategy.js';
26
+ export * from './core/dialect/base/returning-strategy.js';
27
+ export * from './core/dialect/base/pagination-strategy.js';
23
28
  export * from './core/dialect/base/standard-sql-services.js';
24
29
  export * from './core/dialect/base/standard-sql-source-compiler.js';
25
30
  export * from './core/dialect/base/standard-select-compiler.js';
26
31
  export * from './core/dialect/base/standard-insert-compiler.js';
27
32
  export * from './core/dialect/base/standard-update-compiler.js';
28
33
  export * from './core/dialect/base/standard-delete-compiler.js';
34
+ export * from './core/functions/table-types.js';
35
+ export * from './core/functions/standard-table-strategy.js';
29
36
  export * from './core/dialect/mysql/index.js';
37
+ export * from './core/dialect/mysql/upsert.js';
38
+ export * from './core/dialect/mysql/procedure-compiler.js';
30
39
  export * from './core/dialect/mssql/index.js';
40
+ export * from './core/dialect/mssql/compiler-factory.js';
41
+ export * from './core/dialect/mssql/select-compiler.js';
42
+ export * from './core/dialect/mssql/insert-compiler.js';
43
+ export * from './core/dialect/mssql/update-compiler.js';
44
+ export * from './core/dialect/mssql/delete-compiler.js';
45
+ export * from './core/dialect/mssql/output.js';
46
+ export * from './core/dialect/mssql/procedure-compiler.js';
31
47
  export * from './core/dialect/sqlite/index.js';
48
+ export * from './core/dialect/sqlite/upsert.js';
49
+ export * from './core/dialect/sqlite/returning.js';
32
50
  export * from './core/dialect/postgres/index.js';
51
+ export * from './core/dialect/postgres/upsert.js';
52
+ export * from './core/dialect/postgres/returning.js';
53
+ export * from './core/dialect/postgres/procedure-compiler.js';
33
54
  export * from './core/ddl/schema-generator.js';
34
55
  export * from './core/ddl/schema-types.js';
35
56
  export * from './core/ddl/schema-diff.js';
@@ -71,7 +92,7 @@ export * from './orm/jsonify.js';
71
92
  export * from './orm/save-graph-types.js';
72
93
  export * from './decorators/index.js';
73
94
 
74
- // NEW: execution abstraction + helpers
95
+ // Execution abstraction + helpers
75
96
  export * from './core/execution/db-executor.js';
76
97
  export * from './core/execution/pooling/pool-types.js';
77
98
  export * from './core/execution/pooling/pool.js';
@@ -81,17 +102,8 @@ export * from './core/execution/executors/sqlite-executor.js';
81
102
  export * from './core/execution/executors/better-sqlite3-executor.js';
82
103
  export * from './core/execution/executors/mssql-executor.js';
83
104
 
84
- // NEW: first-class pooling integration
85
105
  export * from './orm/pooled-executor-factory.js';
86
-
87
- // DTO module for REST API integration
88
106
  export * from './dto/index.js';
89
-
90
- // Tree behavior (Nested Set / MPTT)
91
107
  export * from './tree/index.js';
92
-
93
- // Cache module
94
108
  export * from './cache/index.js';
95
-
96
- // Bulk operations module
97
109
  export * from './bulk/index.js';