metal-orm 1.1.25 → 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.
@@ -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;
@@ -1,46 +1,75 @@
1
1
  import type { ProcedureCallNode } from '../../ast/procedure.js';
2
2
  import type { JsonPathNode } from '../../ast/expression.js';
3
+ import type {
4
+ DeleteQueryNode,
5
+ InsertQueryNode,
6
+ SelectQueryNode,
7
+ UpdateQueryNode
8
+ } from '../../ast/query.js';
9
+ import type { CompiledQuery, Dialect } from '../abstract.js';
3
10
  import type { CompiledProcedureCall, ProcedureCompiler } from '../capabilities/procedure-compiler.js';
4
- import { SqlDialectBase } from '../base/sql-dialect.js';
11
+ import { composeSqlDialect } from '../base/sql-dialect-composer.js';
5
12
  import { MssqlFunctionStrategy } from './functions.js';
6
13
  import { createMssqlCompilerSet } from './compiler-factory.js';
7
14
  import { MssqlOutputStrategy } from './output.js';
8
15
  import { MssqlProcedureCompiler } from './procedure-compiler.js';
9
16
 
10
- /** Microsoft SQL Server dialect assembled from backend compiler components. */
11
- export class SqlServerDialect extends SqlDialectBase implements ProcedureCompiler {
12
- protected readonly dialect = 'mssql';
13
- private readonly procedureCompiler: MssqlProcedureCompiler;
14
-
15
- public constructor() {
16
- super({
17
- functionStrategy: new MssqlFunctionStrategy(),
18
- returningStrategy: new MssqlOutputStrategy(),
19
- compilerFactory: createMssqlCompilerSet,
20
- supportsDmlReturning: true
21
- });
22
-
23
- this.procedureCompiler = new MssqlProcedureCompiler({
24
- quoteIdentifier: id => this.quoteIdentifier(id),
25
- createCompilerContext: () => this.createCompilerContext(),
26
- compileOperand: (node, ctx) => this.compileOperand(node, ctx)
27
- });
28
- }
17
+ const quoteIdentifier = (id: string): string => `[${id}]`;
18
+
19
+ export type SqlServerDialectImplementation = Dialect & ProcedureCompiler;
20
+
21
+ /** Creates the SQL Server dialect entirely from composable compiler components. */
22
+ export const createSqlServerDialect = (): SqlServerDialectImplementation => {
23
+ const composition = composeSqlDialect({
24
+ name: 'mssql',
25
+ quoteIdentifier,
26
+ formatPlaceholder: index => `@p${index}`,
27
+ functionStrategy: new MssqlFunctionStrategy(),
28
+ returningStrategy: new MssqlOutputStrategy(),
29
+ compilerFactory: createMssqlCompilerSet,
30
+ supportsDmlReturning: true,
31
+ compileJsonPath(node: JsonPathNode): string {
32
+ const column = `${quoteIdentifier(node.column.table)}.${quoteIdentifier(node.column.name)}`;
33
+ return `JSON_VALUE(${column}, '${node.path}')`;
34
+ }
35
+ });
36
+
37
+ const procedures = new MssqlProcedureCompiler(composition.runtime);
38
+ return {
39
+ ...composition.dialect,
40
+ compileProcedureCall: ast => procedures.compileProcedureCall(ast)
41
+ };
42
+ };
43
+
44
+ /** Ergonomic constructor facade over the composed SQL Server dialect. */
45
+ export class SqlServerDialect implements Dialect, ProcedureCompiler {
46
+ private readonly impl: SqlServerDialectImplementation = createSqlServerDialect();
29
47
 
30
48
  quoteIdentifier(id: string): string {
31
- return `[${id}]`;
49
+ return this.impl.quoteIdentifier(id);
50
+ }
51
+
52
+ supportsDmlReturningClause(): boolean {
53
+ return this.impl.supportsDmlReturningClause();
54
+ }
55
+
56
+ compileSelect(ast: SelectQueryNode): CompiledQuery {
57
+ return this.impl.compileSelect(ast);
58
+ }
59
+
60
+ compileInsert(ast: InsertQueryNode): CompiledQuery {
61
+ return this.impl.compileInsert(ast);
32
62
  }
33
63
 
34
- protected compileJsonPath(node: JsonPathNode): string {
35
- const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
36
- return `JSON_VALUE(${column}, '${node.path}')`;
64
+ compileUpdate(ast: UpdateQueryNode): CompiledQuery {
65
+ return this.impl.compileUpdate(ast);
37
66
  }
38
67
 
39
- protected formatPlaceholder(index: number): string {
40
- return `@p${index}`;
68
+ compileDelete(ast: DeleteQueryNode): CompiledQuery {
69
+ return this.impl.compileDelete(ast);
41
70
  }
42
71
 
43
72
  compileProcedureCall(ast: ProcedureCallNode): CompiledProcedureCall {
44
- return this.procedureCompiler.compileProcedureCall(ast);
73
+ return this.impl.compileProcedureCall(ast);
45
74
  }
46
75
  }
@@ -1,51 +1,84 @@
1
1
  import type { ProcedureCallNode } from '../../ast/procedure.js';
2
- import type { JsonPathNode, IsDistinctExpressionNode } from '../../ast/expression.js';
2
+ import type { IsDistinctExpressionNode, JsonPathNode } from '../../ast/expression.js';
3
+ import type {
4
+ DeleteQueryNode,
5
+ InsertQueryNode,
6
+ SelectQueryNode,
7
+ UpdateQueryNode
8
+ } from '../../ast/query.js';
9
+ import type { CompiledQuery, Dialect } from '../abstract.js';
3
10
  import type { CompiledProcedureCall, ProcedureCompiler } from '../capabilities/procedure-compiler.js';
4
- import { SqlDialectBase } from '../base/sql-dialect.js';
11
+ import { composeSqlDialect } from '../base/sql-dialect-composer.js';
5
12
  import { MysqlFunctionStrategy } from './functions.js';
6
13
  import { MySqlProcedureCompiler } from './procedure-compiler.js';
7
14
  import { MySqlUpsertStrategy } from './upsert.js';
8
15
 
9
- /** MySQL dialect assembled from reusable compiler components. */
10
- export class MySqlDialect extends SqlDialectBase implements ProcedureCompiler {
11
- protected readonly dialect = 'mysql';
12
- private readonly procedureCompiler: MySqlProcedureCompiler;
13
-
14
- public constructor() {
15
- super({
16
- functionStrategy: new MysqlFunctionStrategy(),
17
- upsertStrategy: new MySqlUpsertStrategy()
18
- });
19
-
20
- this.procedureCompiler = new MySqlProcedureCompiler({
21
- quoteIdentifier: id => this.quoteIdentifier(id),
22
- createCompilerContext: () => this.createCompilerContext(),
23
- compileOperand: (node, ctx) => this.compileOperand(node, ctx)
24
- });
25
-
26
- this.registerExpressionCompiler(
27
- 'IsDistinctExpression',
28
- (node: IsDistinctExpressionNode, ctx): string => {
29
- const left = this.compileOperand(node.left, ctx);
30
- const right = this.compileOperand(node.right, ctx);
31
- const spaceship = `${left} <=> ${right}`;
32
- return node.operator === 'IS NOT DISTINCT FROM'
33
- ? spaceship
34
- : `NOT (${spaceship})`;
35
- }
36
- );
37
- }
16
+ const quoteIdentifier = (id: string): string => `\`${id}\``;
17
+
18
+ export type MySqlDialectImplementation = Dialect & ProcedureCompiler;
19
+
20
+ /** Creates the MySQL dialect entirely from composable compiler components. */
21
+ export const createMySqlDialect = (): MySqlDialectImplementation => {
22
+ const composition = composeSqlDialect({
23
+ name: 'mysql',
24
+ quoteIdentifier,
25
+ functionStrategy: new MysqlFunctionStrategy(),
26
+ upsertStrategy: new MySqlUpsertStrategy(),
27
+ compileJsonPath(node: JsonPathNode): string {
28
+ const column = `${quoteIdentifier(node.column.table)}.${quoteIdentifier(node.column.name)}`;
29
+ return `${column}->'${node.path}'`;
30
+ },
31
+ configureExpressions(api) {
32
+ api.registerExpressionCompiler(
33
+ 'IsDistinctExpression',
34
+ (node: IsDistinctExpressionNode, ctx): string => {
35
+ const left = api.compileOperand(node.left, ctx);
36
+ const right = api.compileOperand(node.right, ctx);
37
+ const spaceship = `${left} <=> ${right}`;
38
+ return node.operator === 'IS NOT DISTINCT FROM'
39
+ ? spaceship
40
+ : `NOT (${spaceship})`;
41
+ }
42
+ );
43
+ }
44
+ });
45
+
46
+ const procedures = new MySqlProcedureCompiler(composition.runtime);
47
+ return {
48
+ ...composition.dialect,
49
+ compileProcedureCall: ast => procedures.compileProcedureCall(ast)
50
+ };
51
+ };
52
+
53
+ /** Ergonomic constructor facade over the composed MySQL dialect. */
54
+ export class MySqlDialect implements Dialect, ProcedureCompiler {
55
+ private readonly impl: MySqlDialectImplementation = createMySqlDialect();
38
56
 
39
57
  quoteIdentifier(id: string): string {
40
- return `\`${id}\``;
58
+ return this.impl.quoteIdentifier(id);
59
+ }
60
+
61
+ supportsDmlReturningClause(): boolean {
62
+ return this.impl.supportsDmlReturningClause();
63
+ }
64
+
65
+ compileSelect(ast: SelectQueryNode): CompiledQuery {
66
+ return this.impl.compileSelect(ast);
67
+ }
68
+
69
+ compileInsert(ast: InsertQueryNode): CompiledQuery {
70
+ return this.impl.compileInsert(ast);
71
+ }
72
+
73
+ compileUpdate(ast: UpdateQueryNode): CompiledQuery {
74
+ return this.impl.compileUpdate(ast);
41
75
  }
42
76
 
43
- protected compileJsonPath(node: JsonPathNode): string {
44
- const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
45
- return `${column}->'${node.path}'`;
77
+ compileDelete(ast: DeleteQueryNode): CompiledQuery {
78
+ return this.impl.compileDelete(ast);
46
79
  }
47
80
 
48
81
  compileProcedureCall(ast: ProcedureCallNode): CompiledProcedureCall {
49
- return this.procedureCompiler.compileProcedureCall(ast);
82
+ return this.impl.compileProcedureCall(ast);
50
83
  }
51
84
  }
@@ -1,68 +1,96 @@
1
1
  import type { ProcedureCallNode } from '../../ast/procedure.js';
2
2
  import type { BitwiseExpressionNode, ColumnNode, JsonPathNode } from '../../ast/expression.js';
3
- import type { TableNode } from '../../ast/query.js';
3
+ import type {
4
+ DeleteQueryNode,
5
+ InsertQueryNode,
6
+ SelectQueryNode,
7
+ TableNode,
8
+ UpdateQueryNode
9
+ } from '../../ast/query.js';
10
+ import type { CompiledQuery, Dialect } from '../abstract.js';
4
11
  import type { CompiledProcedureCall, ProcedureCompiler } from '../capabilities/procedure-compiler.js';
5
- import { SqlDialectBase } from '../base/sql-dialect.js';
12
+ import { composeSqlDialect } from '../base/sql-dialect-composer.js';
6
13
  import { PostgresFunctionStrategy } from './functions.js';
7
14
  import { PostgresTableFunctionStrategy } from './table-functions.js';
8
15
  import { PostgresProcedureCompiler } from './procedure-compiler.js';
9
16
  import { PostgresReturningStrategy } from './returning.js';
10
17
  import { PostgresUpsertStrategy } from './upsert.js';
11
18
 
12
- /** PostgreSQL dialect assembled from reusable compiler components. */
13
- export class PostgresDialect extends SqlDialectBase implements ProcedureCompiler {
14
- protected readonly dialect = 'postgres';
15
- private readonly procedureCompiler: PostgresProcedureCompiler;
19
+ const quoteIdentifier = (id: string): string => `"${id}"`;
16
20
 
17
- public constructor() {
18
- super({
19
- functionStrategy: new PostgresFunctionStrategy(),
20
- tableFunctionStrategy: new PostgresTableFunctionStrategy(),
21
- returningStrategy: new PostgresReturningStrategy(),
22
- upsertStrategy: new PostgresUpsertStrategy(),
23
- supportsDmlReturning: true
24
- });
21
+ export type PostgresDialectImplementation = Dialect & ProcedureCompiler;
25
22
 
26
- this.procedureCompiler = new PostgresProcedureCompiler({
27
- quoteIdentifier: id => this.quoteIdentifier(id),
28
- createCompilerContext: () => this.createCompilerContext(),
29
- compileOperand: (node, ctx) => this.compileOperand(node, ctx)
30
- });
23
+ /** Creates the PostgreSQL dialect entirely from composable compiler components. */
24
+ export const createPostgresDialect = (): PostgresDialectImplementation => {
25
+ const composition = composeSqlDialect({
26
+ name: 'postgres',
27
+ quoteIdentifier,
28
+ formatPlaceholder: index => `$${index}`,
29
+ functionStrategy: new PostgresFunctionStrategy(),
30
+ tableFunctionStrategy: new PostgresTableFunctionStrategy(),
31
+ returningStrategy: new PostgresReturningStrategy(),
32
+ upsertStrategy: new PostgresUpsertStrategy(),
33
+ supportsDmlReturning: true,
34
+ compileSetTarget: (column: ColumnNode, _table: TableNode) => {
35
+ void _table;
36
+ return quoteIdentifier(column.name);
37
+ },
38
+ compileJsonPath(node: JsonPathNode): string {
39
+ const column = `${quoteIdentifier(node.column.table)}.${quoteIdentifier(node.column.name)}`;
40
+ return `${column}->>'${node.path}'`;
41
+ },
42
+ configureExpressions(api) {
43
+ api.registerExpressionCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
44
+ const left = api.compileOperand(node.left, ctx);
45
+ const right = api.compileOperand(node.right, ctx);
46
+ const operator = node.operator === '^' ? '#' : node.operator;
47
+ return `${left} ${operator} ${right}`;
48
+ });
49
+ api.registerOperandCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
50
+ const left = api.compileOperand(node.left, ctx);
51
+ const right = api.compileOperand(node.right, ctx);
52
+ const operator = node.operator === '^' ? '#' : node.operator;
53
+ return `(${left} ${operator} ${right})`;
54
+ });
55
+ }
56
+ });
31
57
 
32
- this.registerExpressionCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
33
- const left = this.compileOperand(node.left, ctx);
34
- const right = this.compileOperand(node.right, ctx);
35
- const operator = node.operator === '^' ? '#' : node.operator;
36
- return `${left} ${operator} ${right}`;
37
- });
38
- this.registerOperandCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
39
- const left = this.compileOperand(node.left, ctx);
40
- const right = this.compileOperand(node.right, ctx);
41
- const operator = node.operator === '^' ? '#' : node.operator;
42
- return `(${left} ${operator} ${right})`;
43
- });
44
- }
58
+ const procedures = new PostgresProcedureCompiler(composition.runtime);
59
+ return {
60
+ ...composition.dialect,
61
+ compileProcedureCall: ast => procedures.compileProcedureCall(ast)
62
+ };
63
+ };
64
+
65
+ /** Ergonomic constructor facade over the composed PostgreSQL dialect. */
66
+ export class PostgresDialect implements Dialect, ProcedureCompiler {
67
+ private readonly impl: PostgresDialectImplementation = createPostgresDialect();
45
68
 
46
69
  quoteIdentifier(id: string): string {
47
- return `"${id}"`;
70
+ return this.impl.quoteIdentifier(id);
71
+ }
72
+
73
+ supportsDmlReturningClause(): boolean {
74
+ return this.impl.supportsDmlReturningClause();
75
+ }
76
+
77
+ compileSelect(ast: SelectQueryNode): CompiledQuery {
78
+ return this.impl.compileSelect(ast);
48
79
  }
49
80
 
50
- protected formatPlaceholder(index: number): string {
51
- return `$${index}`;
81
+ compileInsert(ast: InsertQueryNode): CompiledQuery {
82
+ return this.impl.compileInsert(ast);
52
83
  }
53
84
 
54
- protected compileJsonPath(node: JsonPathNode): string {
55
- const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
56
- return `${column}->>'${node.path}'`;
85
+ compileUpdate(ast: UpdateQueryNode): CompiledQuery {
86
+ return this.impl.compileUpdate(ast);
57
87
  }
58
88
 
59
- /** PostgreSQL requires unqualified column names in SET clauses. */
60
- protected compileSetTarget(column: ColumnNode, _table: TableNode): string {
61
- void _table;
62
- return this.quoteIdentifier(column.name);
89
+ compileDelete(ast: DeleteQueryNode): CompiledQuery {
90
+ return this.impl.compileDelete(ast);
63
91
  }
64
92
 
65
93
  compileProcedureCall(ast: ProcedureCallNode): CompiledProcedureCall {
66
- return this.procedureCompiler.compileProcedureCall(ast);
94
+ return this.impl.compileProcedureCall(ast);
67
95
  }
68
96
  }
@@ -1,51 +1,81 @@
1
1
  import type { BitwiseExpressionNode, ColumnNode, JsonPathNode } from '../../ast/expression.js';
2
- import type { TableNode } from '../../ast/query.js';
3
- import { SqlDialectBase } from '../base/sql-dialect.js';
2
+ import type {
3
+ DeleteQueryNode,
4
+ InsertQueryNode,
5
+ SelectQueryNode,
6
+ TableNode,
7
+ UpdateQueryNode
8
+ } from '../../ast/query.js';
9
+ import type { CompiledQuery, Dialect } from '../abstract.js';
10
+ import { composeSqlDialect } from '../base/sql-dialect-composer.js';
4
11
  import { SqliteFunctionStrategy } from './functions.js';
5
12
  import { SqliteReturningStrategy } from './returning.js';
6
13
  import { SqliteUpsertStrategy } from './upsert.js';
7
14
 
8
- /** SQLite dialect assembled from reusable compiler components. */
9
- export class SqliteDialect extends SqlDialectBase {
10
- protected readonly dialect = 'sqlite';
11
-
12
- public constructor() {
13
- super({
14
- functionStrategy: new SqliteFunctionStrategy(),
15
- returningStrategy: new SqliteReturningStrategy(),
16
- upsertStrategy: new SqliteUpsertStrategy(),
17
- supportsDmlReturning: true
18
- });
19
-
20
- this.registerExpressionCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
21
- const left = this.compileOperand(node.left, ctx);
22
- const right = this.compileOperand(node.right, ctx);
23
- if (node.operator === '^') {
24
- return `(${left} | ${right}) & ~(${left} & ${right})`;
25
- }
26
- return `${left} ${node.operator} ${right}`;
27
- });
28
- this.registerOperandCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
29
- const left = this.compileOperand(node.left, ctx);
30
- const right = this.compileOperand(node.right, ctx);
31
- if (node.operator === '^') {
32
- return `((${left} | ${right}) & ~(${left} & ${right}))`;
33
- }
34
- return `(${left} ${node.operator} ${right})`;
35
- });
36
- }
15
+ const quoteIdentifier = (id: string): string => `"${id}"`;
16
+
17
+ /** Creates the SQLite dialect entirely from composable compiler components. */
18
+ export const createSqliteDialect = (): Dialect =>
19
+ composeSqlDialect({
20
+ name: 'sqlite',
21
+ quoteIdentifier,
22
+ functionStrategy: new SqliteFunctionStrategy(),
23
+ returningStrategy: new SqliteReturningStrategy(),
24
+ upsertStrategy: new SqliteUpsertStrategy(),
25
+ supportsDmlReturning: true,
26
+ compileSetTarget: (column: ColumnNode, _table: TableNode) => {
27
+ void _table;
28
+ return quoteIdentifier(column.name);
29
+ },
30
+ compileJsonPath(node: JsonPathNode): string {
31
+ const column = `${quoteIdentifier(node.column.table)}.${quoteIdentifier(node.column.name)}`;
32
+ return `json_extract(${column}, '${node.path}')`;
33
+ },
34
+ configureExpressions(api) {
35
+ api.registerExpressionCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
36
+ const left = api.compileOperand(node.left, ctx);
37
+ const right = api.compileOperand(node.right, ctx);
38
+ if (node.operator === '^') {
39
+ return `(${left} | ${right}) & ~(${left} & ${right})`;
40
+ }
41
+ return `${left} ${node.operator} ${right}`;
42
+ });
43
+ api.registerOperandCompiler('BitwiseExpression', (node: BitwiseExpressionNode, ctx) => {
44
+ const left = api.compileOperand(node.left, ctx);
45
+ const right = api.compileOperand(node.right, ctx);
46
+ if (node.operator === '^') {
47
+ return `((${left} | ${right}) & ~(${left} & ${right}))`;
48
+ }
49
+ return `(${left} ${node.operator} ${right})`;
50
+ });
51
+ }
52
+ }).dialect;
53
+
54
+ /** Ergonomic constructor facade over the composed SQLite dialect. */
55
+ export class SqliteDialect implements Dialect {
56
+ private readonly impl: Dialect = createSqliteDialect();
37
57
 
38
58
  quoteIdentifier(id: string): string {
39
- return `"${id}"`;
59
+ return this.impl.quoteIdentifier(id);
60
+ }
61
+
62
+ supportsDmlReturningClause(): boolean {
63
+ return this.impl.supportsDmlReturningClause();
64
+ }
65
+
66
+ compileSelect(ast: SelectQueryNode): CompiledQuery {
67
+ return this.impl.compileSelect(ast);
68
+ }
69
+
70
+ compileInsert(ast: InsertQueryNode): CompiledQuery {
71
+ return this.impl.compileInsert(ast);
40
72
  }
41
73
 
42
- protected compileJsonPath(node: JsonPathNode): string {
43
- const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
44
- return `json_extract(${column}, '${node.path}')`;
74
+ compileUpdate(ast: UpdateQueryNode): CompiledQuery {
75
+ return this.impl.compileUpdate(ast);
45
76
  }
46
77
 
47
- protected compileQualifiedColumn(column: ColumnNode, _table: TableNode): string {
48
- void _table;
49
- return this.quoteIdentifier(column.name);
78
+ compileDelete(ast: DeleteQueryNode): CompiledQuery {
79
+ return this.impl.compileDelete(ast);
50
80
  }
51
81
  }
package/src/index.ts CHANGED
@@ -20,7 +20,7 @@ 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';
23
+ export * from './core/dialect/base/sql-dialect-composer.js';
24
24
  export * from './core/dialect/base/sql-compiler-set.js';
25
25
  export * from './core/dialect/base/upsert-strategy.js';
26
26
  export * from './core/dialect/base/returning-strategy.js';