metal-orm 1.1.24 → 1.1.26

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 (35) hide show
  1. package/dist/index.cjs +770 -710
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +294 -318
  4. package/dist/index.d.ts +294 -318
  5. package/dist/index.js +745 -709
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/core/dialect/abstract.ts +7 -229
  9. package/src/core/dialect/base/returning-strategy.ts +40 -39
  10. package/src/core/dialect/base/sql-compiler-set.ts +33 -0
  11. package/src/core/dialect/base/sql-dialect-composer.ts +294 -0
  12. package/src/core/dialect/base/standard-sql-services.ts +2 -6
  13. package/src/core/dialect/base/upsert-strategy.ts +44 -0
  14. package/src/core/dialect/capabilities/procedure-compiler.ts +10 -8
  15. package/src/core/dialect/dialect-factory.ts +17 -49
  16. package/src/core/dialect/mssql/compiler-factory.ts +12 -0
  17. package/src/core/dialect/mssql/delete-compiler.ts +40 -0
  18. package/src/core/dialect/mssql/index.ts +52 -370
  19. package/src/core/dialect/mssql/insert-compiler.ts +112 -0
  20. package/src/core/dialect/mssql/output.ts +46 -0
  21. package/src/core/dialect/mssql/procedure-compiler.ts +81 -0
  22. package/src/core/dialect/mssql/select-compiler.ts +116 -0
  23. package/src/core/dialect/mssql/update-compiler.ts +37 -0
  24. package/src/core/dialect/mysql/index.ts +66 -126
  25. package/src/core/dialect/mysql/procedure-compiler.ts +67 -0
  26. package/src/core/dialect/mysql/upsert.ts +42 -0
  27. package/src/core/dialect/postgres/index.ts +75 -114
  28. package/src/core/dialect/postgres/procedure-compiler.ts +41 -0
  29. package/src/core/dialect/postgres/returning.ts +4 -0
  30. package/src/core/dialect/postgres/upsert.ts +43 -0
  31. package/src/core/dialect/sqlite/index.ts +65 -90
  32. package/src/core/dialect/sqlite/returning.ts +30 -0
  33. package/src/core/dialect/sqlite/upsert.ts +43 -0
  34. package/src/index.ts +22 -10
  35. package/src/core/dialect/base/sql-dialect.ts +0 -176
@@ -11,19 +11,15 @@ import type {
11
11
  ExpressionNode,
12
12
  OperandNode
13
13
  } from '../../ast/expression.js';
14
- import type { DialectName } from '../../sql/sql.js';
15
14
  import type { PaginationStrategy } from './pagination-strategy.js';
16
15
  import type { TableFunctionStrategy } from '../../functions/table-types.js';
17
16
 
18
17
  /**
19
18
  * Narrow callback surface consumed by the standard SQL compilers.
20
- *
21
- * The compilers deliberately know nothing about SqlDialectBase or any concrete
22
- * backend class. A dialect can assemble these services through inheritance,
23
- * composition, or a plain object.
19
+ * It deliberately depends on no dialect superclass or built-in dialect union.
24
20
  */
25
21
  export interface StandardSqlCompilerServices {
26
- getDialectName(): DialectName;
22
+ getDialectName(): string;
27
23
  getPaginationStrategy(): PaginationStrategy;
28
24
  getTableFunctionStrategy(): TableFunctionStrategy;
29
25
 
@@ -0,0 +1,44 @@
1
+ import type { CompilerContext } from '../abstract.js';
2
+ import type {
3
+ InsertQueryNode,
4
+ TableNode,
5
+ UpdateAssignmentNode
6
+ } from '../../ast/query.js';
7
+ import type { ExpressionNode, OperandNode } from '../../ast/expression.js';
8
+
9
+ /** Narrow services needed by backend-specific UPSERT implementations. */
10
+ export interface UpsertCompilationServices {
11
+ getDialectName(): string;
12
+ quoteIdentifier(id: string): string;
13
+ compileOperand(node: OperandNode, ctx: CompilerContext): string;
14
+ compileExpression(node: ExpressionNode, ctx: CompilerContext): string;
15
+ compileUpdateAssignments(
16
+ assignments: UpdateAssignmentNode[],
17
+ table: TableNode,
18
+ ctx: CompilerContext
19
+ ): string;
20
+ }
21
+
22
+ /** Backend-specific INSERT conflict/upsert rendering strategy. */
23
+ export interface UpsertStrategy {
24
+ compile(
25
+ ast: InsertQueryNode,
26
+ ctx: CompilerContext,
27
+ services: UpsertCompilationServices
28
+ ): string;
29
+ }
30
+
31
+ /** Default strategy for dialects without UPSERT support. */
32
+ export class NoUpsertStrategy implements UpsertStrategy {
33
+ compile(
34
+ ast: InsertQueryNode,
35
+ _ctx: CompilerContext,
36
+ services: UpsertCompilationServices
37
+ ): string {
38
+ void _ctx;
39
+ if (!ast.onConflict) return '';
40
+ throw new Error(
41
+ `UPSERT/ON CONFLICT is not supported by dialect "${services.getDialectName()}".`
42
+ );
43
+ }
44
+ }
@@ -1,5 +1,6 @@
1
1
  import type { ProcedureCallNode } from '../../ast/procedure.js';
2
- import type { CompiledQuery } from '../abstract.js';
2
+ import type { OperandNode } from '../../ast/expression.js';
3
+ import type { CompiledQuery, CompilerContext } from '../abstract.js';
3
4
 
4
5
  export interface CompiledProcedureCall extends CompiledQuery {
5
6
  outParams: {
@@ -8,13 +9,14 @@ export interface CompiledProcedureCall extends CompiledQuery {
8
9
  };
9
10
  }
10
11
 
11
- /**
12
- * Optional dialect capability for stored-procedure compilation.
13
- *
14
- * Dialects that do not support procedures simply do not implement this
15
- * interface; unsupported behavior is resolved at the capability boundary
16
- * rather than through mandatory methods that only throw.
17
- */
12
+ /** Narrow SQL services consumed by reusable procedure compiler components. */
13
+ export interface ProcedureCompilerServices {
14
+ quoteIdentifier(id: string): string;
15
+ createCompilerContext(): CompilerContext;
16
+ compileOperand(node: OperandNode, ctx: CompilerContext): string;
17
+ }
18
+
19
+ /** Optional dialect capability for stored-procedure compilation. */
18
20
  export interface ProcedureCompiler {
19
21
  compileProcedureCall(ast: ProcedureCallNode): CompiledProcedureCall;
20
22
  }
@@ -1,20 +1,20 @@
1
1
  // Dialect factory for the SQL DSL.
2
- // Centralizes how we go from a symbolic name ("sqlite") to a concrete Dialect instance.
2
+ // Centralizes how we go from a symbolic name ("sqlite") to a structural Dialect.
3
3
 
4
4
  import type { Dialect } from './abstract.js';
5
- import { PostgresDialect } from './postgres/index.js';
6
- import { MySqlDialect } from './mysql/index.js';
7
- import { SqliteDialect } from './sqlite/index.js';
8
- import { SqlServerDialect } from './mssql/index.js';
5
+ import { createPostgresDialect } from './postgres/index.js';
6
+ import { createMySqlDialect } from './mysql/index.js';
7
+ import { createSqliteDialect } from './sqlite/index.js';
8
+ import { createSqlServerDialect } from './mssql/index.js';
9
9
 
10
10
  export type DialectKey =
11
11
  | 'postgres'
12
12
  | 'mysql'
13
13
  | 'sqlite'
14
14
  | 'mssql'
15
- | (string & {}); // allow user-defined keys without constraining too much
15
+ | (string & {});
16
16
 
17
- type DialectFactoryFn = () => Dialect;
17
+ export type DialectFactoryFn = () => Dialect;
18
18
 
19
19
  export class DialectFactory {
20
20
  private static registry = new Map<DialectKey, DialectFactoryFn>();
@@ -24,67 +24,35 @@ export class DialectFactory {
24
24
  if (this.defaultsInitialized) return;
25
25
  this.defaultsInitialized = true;
26
26
 
27
- // Register built-in dialects only if no override exists yet.
28
- if (!this.registry.has('postgres')) {
29
- this.registry.set('postgres', () => new PostgresDialect());
30
- }
31
- if (!this.registry.has('mysql')) {
32
- this.registry.set('mysql', () => new MySqlDialect());
33
- }
34
- if (!this.registry.has('sqlite')) {
35
- this.registry.set('sqlite', () => new SqliteDialect());
36
- }
37
- if (!this.registry.has('mssql')) {
38
- this.registry.set('mssql', () => new SqlServerDialect());
39
- }
27
+ if (!this.registry.has('postgres')) this.registry.set('postgres', createPostgresDialect);
28
+ if (!this.registry.has('mysql')) this.registry.set('mysql', createMySqlDialect);
29
+ if (!this.registry.has('sqlite')) this.registry.set('sqlite', createSqliteDialect);
30
+ if (!this.registry.has('mssql')) this.registry.set('mssql', createSqlServerDialect);
40
31
  }
41
32
 
42
- /**
43
- * Register (or override) a dialect factory for a key.
44
- *
45
- * Implementations are structural: extending DialectBase/SqlDialectBase is
46
- * optional. A composed object satisfying Dialect is a valid registration.
47
- */
33
+ /** Register or replace a structural dialect factory. */
48
34
  public static register(key: DialectKey, factory: DialectFactoryFn): void {
49
35
  this.registry.set(key, factory);
50
36
  }
51
37
 
52
- /**
53
- * Resolve a key into a Dialect instance.
54
- * Throws if the key is not registered.
55
- */
38
+ /** Resolve a key into a new Dialect instance. */
56
39
  public static create(key: DialectKey): Dialect {
57
40
  this.ensureDefaults();
58
41
  const factory = this.registry.get(key);
59
42
  if (!factory) {
60
43
  throw new Error(
61
- `Dialect "${String(
62
- key
63
- )}" is not registered. Use DialectFactory.register(...) to register it.`
44
+ `Dialect "${String(key)}" is not registered. Use DialectFactory.register(...) to register it.`
64
45
  );
65
46
  }
66
47
  return factory();
67
48
  }
68
49
 
69
- /**
70
- * Clear all registrations (mainly for tests).
71
- * Built-ins will be re-registered lazily on the next create().
72
- */
50
+ /** Clear registrations; built-ins are restored lazily on the next create(). */
73
51
  public static clear(): void {
74
52
  this.registry.clear();
75
53
  this.defaultsInitialized = false;
76
54
  }
77
55
  }
78
56
 
79
- /**
80
- * Helper to normalize either a Dialect instance OR a key into a Dialect instance.
81
- * This is what query builders will use.
82
- */
83
- export const resolveDialectInput = (
84
- dialect: Dialect | DialectKey
85
- ): Dialect => {
86
- if (typeof dialect === 'string') {
87
- return DialectFactory.create(dialect);
88
- }
89
- return dialect;
90
- };
57
+ export const resolveDialectInput = (dialect: Dialect | DialectKey): Dialect =>
58
+ typeof dialect === 'string' ? DialectFactory.create(dialect) : dialect;
@@ -0,0 +1,12 @@
1
+ import type { SqlCompilerFactory } from '../base/sql-compiler-set.js';
2
+ import { MssqlDeleteCompiler } from './delete-compiler.js';
3
+ import { MssqlInsertCompiler } from './insert-compiler.js';
4
+ import { MssqlSelectCompiler } from './select-compiler.js';
5
+ import { MssqlUpdateCompiler } from './update-compiler.js';
6
+
7
+ export const createMssqlCompilerSet: SqlCompilerFactory = ({ services, sources }) => ({
8
+ select: new MssqlSelectCompiler(services, sources),
9
+ insert: new MssqlInsertCompiler(services, sources),
10
+ update: new MssqlUpdateCompiler(services, sources),
11
+ delete: new MssqlDeleteCompiler(services, sources)
12
+ });
@@ -0,0 +1,40 @@
1
+ import type { DeleteQueryNode } from '../../ast/query.js';
2
+ import type { CompilerContext } from '../abstract.js';
3
+ import { JoinCompiler } from '../base/join-compiler.js';
4
+ import type { SqlAstCompiler } from '../base/sql-compiler-set.js';
5
+ import type { StandardSqlCompilerServices } from '../base/standard-sql-services.js';
6
+ import type { StandardSqlSourceCompiler } from '../base/standard-sql-source-compiler.js';
7
+ import { MssqlOutputStrategy } from './output.js';
8
+
9
+ export class MssqlDeleteCompiler implements SqlAstCompiler<DeleteQueryNode> {
10
+ private readonly output = new MssqlOutputStrategy();
11
+
12
+ constructor(
13
+ private readonly services: StandardSqlCompilerServices,
14
+ private readonly sources: StandardSqlSourceCompiler
15
+ ) {}
16
+
17
+ compile(ast: DeleteQueryNode, ctx: CompilerContext): string {
18
+ if (ast.using) {
19
+ throw new Error('DELETE ... USING is not supported in the MSSQL dialect; use join() instead.');
20
+ }
21
+
22
+ const alias = ast.from.alias ?? ast.from.name;
23
+ const target = this.sources.compileTableReference(ast.from);
24
+ const joins = JoinCompiler.compileJoins(
25
+ ast.joins,
26
+ ctx,
27
+ (source, compilerContext) => this.sources.compileFrom(source, compilerContext),
28
+ (expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
29
+ );
30
+ const where = ast.where
31
+ ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}`
32
+ : '';
33
+ const returning = this.output.compileOutput(
34
+ ast.returning,
35
+ 'deleted',
36
+ id => this.services.quoteIdentifier(id)
37
+ );
38
+ return `DELETE ${this.services.quoteIdentifier(alias)}${returning} FROM ${target}${joins}${where}`;
39
+ }
40
+ }