@zmdb/mssql 1.0.0-beta.1

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.
@@ -0,0 +1,296 @@
1
+ import { quoteIdentifier, quoteTable, UnsupportedFeatureError, } from '@zmdb/sql';
2
+ import {} from '@zmdb/sql/schema-objects';
3
+ import { mssqlDdlType } from './types.js';
4
+ function identifier(name) {
5
+ return `[${name.replaceAll(']', ']]')}]`;
6
+ }
7
+ function table(name) {
8
+ return name
9
+ .split('.')
10
+ .map(part => identifier(part))
11
+ .join('.');
12
+ }
13
+ function safeVersion(value, row) {
14
+ if (typeof value !== 'number' && typeof value !== 'bigint' && typeof value !== 'string') {
15
+ throw new TypeError(`SQL Server migration ledger row ${String(row)} has an invalid version`);
16
+ }
17
+ const version = Number(value);
18
+ if (!Number.isSafeInteger(version)) {
19
+ throw new TypeError(`SQL Server migration ledger row ${String(row)} version is not a safe integer`);
20
+ }
21
+ return version;
22
+ }
23
+ function appliedMigration(row, index) {
24
+ const name = Reflect.get(row, 'name');
25
+ const migrationChecksum = Reflect.get(row, 'checksum');
26
+ if (typeof name !== 'string' || (migrationChecksum !== null && typeof migrationChecksum !== 'string')) {
27
+ throw new TypeError(`SQL Server migration ledger row ${String(index)} has an invalid name or checksum`);
28
+ }
29
+ return {
30
+ version: safeVersion(Reflect.get(row, 'version'), index),
31
+ name,
32
+ checksum: migrationChecksum,
33
+ };
34
+ }
35
+ async function checksum(sql) {
36
+ const bytes = new TextEncoder().encode(sql);
37
+ const digest = new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', bytes));
38
+ return `sha256:${Array.from(digest, byte => byte.toString(16).padStart(2, '0')).join('')}`;
39
+ }
40
+ function migrationConnection(driver, options = {}) {
41
+ const dialect = driver.dialect;
42
+ const tableName = options.table ?? '_zmdb_migrations';
43
+ const qualifiedTable = options.schema === undefined ? tableName : `${options.schema}.${tableName}`;
44
+ const ledgerTable = quoteTable(dialect, qualifiedTable);
45
+ async function execute(text, parameters = []) {
46
+ return driver.execute({ text, parameters });
47
+ }
48
+ async function appliedMigrations() {
49
+ const rows = await execute(`SELECT version, name, checksum FROM ${ledgerTable} ORDER BY version`);
50
+ return rows.map(appliedMigration);
51
+ }
52
+ return {
53
+ name: 'mssql',
54
+ transactionalDdl: true,
55
+ async exec(sql) {
56
+ await execute(sql);
57
+ },
58
+ async appliedVersions() {
59
+ return (await appliedMigrations()).map(migration => migration.version);
60
+ },
61
+ appliedMigrations,
62
+ async recordApplied(version, name, migrationChecksum = '') {
63
+ await execute(`INSERT INTO ${ledgerTable} (` +
64
+ `${quoteIdentifier(dialect, 'version')}, ${quoteIdentifier(dialect, 'name')}, ` +
65
+ `${quoteIdentifier(dialect, 'applied_at')}, ${quoteIdentifier(dialect, 'checksum')}) ` +
66
+ 'VALUES (@p1, @p2, @p3, @p4)', [version, name, Date.now(), migrationChecksum]);
67
+ },
68
+ async recordReverted(version) {
69
+ await execute(`DELETE FROM ${ledgerTable} WHERE ${quoteIdentifier(dialect, 'version')} = @p1`, [version]);
70
+ },
71
+ async ensureVersionTable() {
72
+ const objectName = qualifiedTable.replaceAll("'", "''");
73
+ await execute(`IF OBJECT_ID(N'${objectName}', N'U') IS NULL ` +
74
+ `CREATE TABLE ${ledgerTable} (` +
75
+ `${quoteIdentifier(dialect, 'version')} BIGINT PRIMARY KEY, ` +
76
+ `${quoteIdentifier(dialect, 'name')} NVARCHAR(MAX) NOT NULL, ` +
77
+ `${quoteIdentifier(dialect, 'applied_at')} BIGINT NOT NULL, ` +
78
+ `${quoteIdentifier(dialect, 'checksum')} NVARCHAR(MAX))`);
79
+ try {
80
+ await execute(`SELECT ${quoteIdentifier(dialect, 'checksum')} FROM ${ledgerTable} WHERE 1 = 0`);
81
+ }
82
+ catch {
83
+ await execute(`ALTER TABLE ${ledgerTable} ADD ${quoteIdentifier(dialect, 'checksum')} NVARCHAR(MAX)`);
84
+ }
85
+ },
86
+ checksum,
87
+ async transaction(run) {
88
+ if (driver.transaction === undefined) {
89
+ throw new Error('mssql migrations require a transactional driver; every callback request must come from one node-mssql transaction');
90
+ }
91
+ return driver.transaction(transactionDriver => run(migrationConnection(transactionDriver, options)));
92
+ },
93
+ };
94
+ }
95
+ function columnDdl(column, options) {
96
+ const primaryKey = options.inlinePrimaryKey ? ' PRIMARY KEY' : '';
97
+ const notNull = !options.inlinePrimaryKey && (!column.nullable || options.tablePrimaryKey) ? ' NOT NULL' : '';
98
+ return `${identifier(column.name)} ${mssqlDdlType(column)}${primaryKey}${notNull}`;
99
+ }
100
+ function action(actionName) {
101
+ return actionName === 'restrict' || actionName === 'no action' ? 'NO ACTION' : actionName.toUpperCase();
102
+ }
103
+ function foreignKeyDdl(foreignKey) {
104
+ const columns = foreignKey.columns.map(identifier).join(', ');
105
+ const targetColumns = foreignKey.targetColumns.map(identifier).join(', ');
106
+ return (`FOREIGN KEY (${columns}) REFERENCES ${table(foreignKey.targetTable)} (${targetColumns}) ` +
107
+ `ON DELETE ${action(foreignKey.onDelete)} ON UPDATE ${action(foreignKey.onUpdate)}`);
108
+ }
109
+ function createTable(operation) {
110
+ const inline = operation.primaryKey.length === 1 ? operation.primaryKey[0] : undefined;
111
+ const composite = operation.primaryKey.length > 1 ? new Set(operation.primaryKey) : undefined;
112
+ const definitions = operation.columns.map(column => columnDdl(column, {
113
+ inlinePrimaryKey: column.name === inline,
114
+ tablePrimaryKey: composite?.has(column.name) === true,
115
+ }));
116
+ if (composite !== undefined) {
117
+ definitions.push(`PRIMARY KEY (${operation.primaryKey.map(identifier).join(', ')})`);
118
+ }
119
+ return `CREATE TABLE ${table(operation.table)} (${definitions.join(', ')})`;
120
+ }
121
+ function alterNullability(operation, direction) {
122
+ const nullable = direction === 'up' ? operation.toNullable : operation.fromNullable;
123
+ if (nullable === undefined) {
124
+ throw new UnsupportedFeatureError(`altering the type of "${operation.table}"."${operation.column}" without nullability metadata`, 'mssql', 'mssql ALTER COLUMN must restate NULL or NOT NULL; generate this operation from snapshots or provide ' +
125
+ `${direction === 'up' ? 'toNullable' : 'fromNullable'} explicitly`);
126
+ }
127
+ return nullable ? ' NULL' : ' NOT NULL';
128
+ }
129
+ function alteredType(operation, direction) {
130
+ return mssqlDdlType({
131
+ name: operation.column,
132
+ type: direction === 'up' ? operation.to : operation.from,
133
+ nullable: direction === 'up' ? (operation.toNullable ?? true) : (operation.fromNullable ?? true),
134
+ primaryKey: false,
135
+ });
136
+ }
137
+ function primaryKeyRefusal(operation) {
138
+ throw new UnsupportedFeatureError(`altering the primary key of "${operation.table}"`, 'mssql', `mssql cannot safely alter the primary key of "${operation.table}" ` +
139
+ `(${operation.from.join(', ')} → ${operation.to.join(', ')}) because the snapshot does not carry the ` +
140
+ 'existing SQL Server constraint name; use a hand-written migration');
141
+ }
142
+ function emitUp(operation) {
143
+ switch (operation.kind) {
144
+ case 'create_extension':
145
+ throw new UnsupportedFeatureError(`extension "${operation.name}"`, 'mssql', `mssql does not support database extensions ("${operation.name}")`);
146
+ case 'create_table':
147
+ return createTable(operation);
148
+ case 'drop_table':
149
+ return `DROP TABLE ${table(operation.table)}`;
150
+ case 'add_column':
151
+ return `ALTER TABLE ${table(operation.table)} ADD ${columnDdl(operation.column, {
152
+ inlinePrimaryKey: operation.column.primaryKey,
153
+ tablePrimaryKey: false,
154
+ })}`;
155
+ case 'drop_column':
156
+ return `ALTER TABLE ${table(operation.table)} DROP COLUMN ${identifier(operation.column)}`;
157
+ case 'alter_column_type':
158
+ return (`ALTER TABLE ${table(operation.table)} ALTER COLUMN ${identifier(operation.column)} ` +
159
+ `${alteredType(operation, 'up')}${alterNullability(operation, 'up')}`);
160
+ case 'alter_primary_key':
161
+ return primaryKeyRefusal(operation);
162
+ case 'add_foreign_key':
163
+ return (`ALTER TABLE ${table(operation.table)} ADD CONSTRAINT ${identifier(operation.fk.name)} ` +
164
+ foreignKeyDdl(operation.fk));
165
+ case 'drop_foreign_key':
166
+ return `ALTER TABLE ${table(operation.table)} DROP CONSTRAINT ${identifier(operation.name)}`;
167
+ }
168
+ }
169
+ function emitDown(operation) {
170
+ switch (operation.kind) {
171
+ case 'create_extension':
172
+ throw new UnsupportedFeatureError(`reverting extension "${operation.name}"`, 'mssql');
173
+ case 'create_table':
174
+ return `DROP TABLE ${table(operation.table)}`;
175
+ case 'drop_table':
176
+ throw new UnsupportedFeatureError(`recreating dropped table "${operation.table}"`, 'mssql', `mssql cannot recreate dropped table "${operation.table}" because the drop operation carries no columns; ` +
177
+ 'write the down migration by hand');
178
+ case 'add_column':
179
+ return `ALTER TABLE ${table(operation.table)} DROP COLUMN ${identifier(operation.column.name)}`;
180
+ case 'drop_column':
181
+ throw new UnsupportedFeatureError(`recreating dropped column "${operation.table}"."${operation.column}"`, 'mssql', 'the drop operation carries no SQL type or nullability; write the down migration by hand');
182
+ case 'alter_column_type':
183
+ return (`ALTER TABLE ${table(operation.table)} ALTER COLUMN ${identifier(operation.column)} ` +
184
+ `${alteredType(operation, 'down')}${alterNullability(operation, 'down')}`);
185
+ case 'alter_primary_key':
186
+ return primaryKeyRefusal({
187
+ ...operation,
188
+ from: operation.to,
189
+ to: operation.from,
190
+ });
191
+ case 'add_foreign_key':
192
+ return `ALTER TABLE ${table(operation.table)} DROP CONSTRAINT ${identifier(operation.fk.name)}`;
193
+ case 'drop_foreign_key':
194
+ throw new UnsupportedFeatureError(`recreating foreign key "${operation.name}" on "${operation.table}"`, 'mssql', 'the drop operation carries no columns, target or referential actions; write the down migration by hand');
195
+ }
196
+ }
197
+ function indexColumn(column, definition) {
198
+ if (typeof column === 'string')
199
+ return identifier(column);
200
+ if ('expr' in column) {
201
+ throw new UnsupportedFeatureError(`expression index "${definition.name}"`, 'mssql', `mssql does not support an expression index ("${definition.name}" on "${definition.table}" uses ` +
202
+ `${column.expr}); add a computed column and index that instead`);
203
+ }
204
+ if (column.opclass !== undefined) {
205
+ throw new UnsupportedFeatureError(`index operator class ${column.opclass}`, 'mssql');
206
+ }
207
+ return identifier(column.column);
208
+ }
209
+ function createIndex(definition) {
210
+ if (definition.method !== undefined && definition.method !== 'btree') {
211
+ throw new UnsupportedFeatureError(`index method ${definition.method}`, 'mssql', `mssql does not support the index method ${definition.method} ("${definition.name}" on "${definition.table}")`);
212
+ }
213
+ if (definition.with !== undefined && Object.keys(definition.with).length > 0) {
214
+ throw new UnsupportedFeatureError(`index options on "${definition.name}"`, 'mssql', 'the current SQL Server index contract does not model WITH options');
215
+ }
216
+ const unique = definition.unique === true ? 'UNIQUE ' : '';
217
+ const columns = definition.columns.map(column => indexColumn(column, definition)).join(', ');
218
+ const predicate = definition.where === undefined ? '' : ` WHERE ${definition.where}`;
219
+ return `CREATE ${unique}INDEX ${identifier(definition.name)} ON ${table(definition.table)} (${columns})${predicate}`;
220
+ }
221
+ function sequence(definition) {
222
+ let sql = `CREATE SEQUENCE ${table(definition.name)}`;
223
+ if (definition.start !== undefined)
224
+ sql += ` START WITH ${String(definition.start)}`;
225
+ if (definition.increment !== undefined)
226
+ sql += ` INCREMENT BY ${String(definition.increment)}`;
227
+ return sql;
228
+ }
229
+ function generatedColumn(definition) {
230
+ return `${identifier(definition.name)} AS (${definition.expression})${definition.stored === true ? ' PERSISTED' : ''}`;
231
+ }
232
+ function unsupportedSchemaObject(feature, detail) {
233
+ throw new UnsupportedFeatureError(feature, 'mssql', detail);
234
+ }
235
+ function emitSchemaObject(operation) {
236
+ switch (operation.kind) {
237
+ case 'create_index':
238
+ return [createIndex(operation.definition)];
239
+ case 'check_constraint':
240
+ return [
241
+ `ALTER TABLE ${table(operation.table)} ADD CONSTRAINT ${identifier(operation.name)} ` +
242
+ `CHECK (${operation.expression})`,
243
+ ];
244
+ case 'create_view':
245
+ if (operation.definition.materialized === true) {
246
+ return unsupportedSchemaObject('materialized views', 'SQL Server indexed views require schema binding and index declarations that the current view contract does not carry');
247
+ }
248
+ return [`CREATE VIEW ${table(operation.definition.name)} AS ${operation.definition.select}`];
249
+ case 'drop_view':
250
+ if (operation.materialized === true)
251
+ return unsupportedSchemaObject('materialized views');
252
+ return [`DROP VIEW IF EXISTS ${table(operation.name)}`];
253
+ case 'create_sequence':
254
+ return [sequence(operation.definition)];
255
+ case 'generated_column':
256
+ return [generatedColumn(operation.definition)];
257
+ case 'create_schema':
258
+ return [`CREATE SCHEMA ${identifier(operation.name)}`];
259
+ case 'enable_rls':
260
+ return unsupportedSchemaObject('row-level security');
261
+ case 'create_policy':
262
+ return unsupportedSchemaObject('row-level security policy');
263
+ case 'create_extension':
264
+ return unsupportedSchemaObject(`extension "${operation.definition.name}"`, `mssql does not support database extensions ("${operation.definition.name}")`);
265
+ case 'create_routine':
266
+ case 'drop_routine':
267
+ case 'replace_routine':
268
+ return unsupportedSchemaObject('stored routines', 'SQL Server CREATE/ALTER and EXEC grammar is not represented by the current routine contract; ' +
269
+ 'use a hand-written migration and driver call');
270
+ }
271
+ }
272
+ function validateSnapshot(snapshot) {
273
+ for (const currentTable of snapshot.tables) {
274
+ for (const column of currentTable.columns)
275
+ mssqlDdlType(column);
276
+ }
277
+ }
278
+ function validatePlan(plan) {
279
+ validateSnapshot(plan.before);
280
+ validateSnapshot(plan.after);
281
+ for (const operation of plan.operations)
282
+ emitUp(operation);
283
+ }
284
+ export const mssqlMigrations = Object.freeze({
285
+ name: 'mssql',
286
+ foreignKeyMode: 'deferred',
287
+ embedded: false,
288
+ validateSnapshot,
289
+ validatePlan,
290
+ ddlType: mssqlDdlType,
291
+ emitUp,
292
+ emitDown,
293
+ emitSchemaObject,
294
+ connection: migrationConnection,
295
+ });
296
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ColumnSnapshot } from '@zmdb/migrations';
2
+ export declare const MSSQL_TYPES: Readonly<{
3
+ serial: string;
4
+ integer: string;
5
+ bigint: string;
6
+ numeric: string;
7
+ text: string;
8
+ varchar: string;
9
+ boolean: string;
10
+ timestamp: string;
11
+ json: string;
12
+ jsonEnum: string;
13
+ }>;
14
+ export declare function mssqlDdlType(column: ColumnSnapshot): string;
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,eAAO,MAAM,WAAW;;;;;;;;;;;EAWG,CAAC;AAE5B,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAiB3D"}
package/dist/types.js ADDED
@@ -0,0 +1,27 @@
1
+ import { UnsupportedFeatureError } from '@zmdb/sql';
2
+ export const MSSQL_TYPES = Object.freeze({
3
+ serial: 'INT IDENTITY(1,1)',
4
+ integer: 'INT',
5
+ bigint: 'BIGINT',
6
+ numeric: 'DECIMAL',
7
+ text: 'NVARCHAR(MAX)',
8
+ varchar: 'NVARCHAR',
9
+ boolean: 'BIT',
10
+ timestamp: 'DATETIMEOFFSET(3)',
11
+ json: 'NVARCHAR(MAX)',
12
+ jsonEnum: 'NVARCHAR(MAX)',
13
+ });
14
+ export function mssqlDdlType(column) {
15
+ if (typeof column.type !== 'string') {
16
+ const args = column.type.args ?? [];
17
+ const rendered = `${column.type.name}${args.length === 0 ? '' : `(${args.map(String).join(',')})`}`;
18
+ throw new UnsupportedFeatureError(`extension type ${rendered}`, 'mssql', `mssql does not support the extension type ${rendered} on column "${column.name}" ` +
19
+ `(extension \`${column.type.extension}\`); use a native SQL Server type in a hand-written migration`);
20
+ }
21
+ const mapped = Reflect.get(MSSQL_TYPES, column.type) ?? column.type;
22
+ if (column.type === 'varchar') {
23
+ return column.length === undefined ? 'NVARCHAR(MAX)' : `NVARCHAR(${String(column.length)})`;
24
+ }
25
+ return mapped;
26
+ }
27
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAuB,MAAM,WAAW,CAAC;AAEzE,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACvC,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,UAAU;IACnB,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,mBAAmB;IAC9B,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,eAAe;CACD,CAAC,CAAC;AAE5B,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACpG,MAAM,IAAI,uBAAuB,CAC/B,kBAAkB,QAAQ,EAAE,EAC5B,OAAO,EACP,6CAA6C,QAAQ,eAAe,MAAM,CAAC,IAAI,IAAI;YACjF,gBAAgB,MAAM,CAAC,IAAI,CAAC,SAAS,+DAA+D,CACvG,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAW,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;IAC5E,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAC9F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@zmdb/mssql",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Complete SQL Server vertical for zmdb: T-SQL compilation, migrations, structural node-mssql execution, catalog introspection, and capability metadata.",
5
+ "keywords": [
6
+ "database",
7
+ "mssql",
8
+ "orm",
9
+ "sql-server",
10
+ "typescript",
11
+ "zmdb"
12
+ ],
13
+ "homepage": "https://github.com/ambasta/zmdb#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/ambasta/zmdb/issues"
16
+ },
17
+ "license": "GPL-3.0-or-later",
18
+ "author": "zmdb contributors",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ambasta/zmdb.git",
22
+ "directory": "packages/mssql"
23
+ },
24
+ "type": "module",
25
+ "sideEffects": false,
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ }
31
+ },
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "tag": "beta"
35
+ },
36
+ "scripts": {
37
+ "build": "node ../../scripts/build-package.mjs",
38
+ "test": "vitest run"
39
+ },
40
+ "dependencies": {
41
+ "@zmdb/migrations": "1.0.0-beta.1"
42
+ },
43
+ "peerDependencies": {
44
+ "@zmdb/orm": "1.0.0-beta.1",
45
+ "@zmdb/sql": "1.0.0-beta.1",
46
+ "mssql": "^12.7.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "mssql": {
50
+ "optional": true
51
+ }
52
+ },
53
+ "engines": {
54
+ "node": ">=26"
55
+ },
56
+ "main": "./dist/index.js",
57
+ "types": "./dist/index.d.ts"
58
+ }
@@ -0,0 +1,109 @@
1
+ import {
2
+ quoteColumn,
3
+ quoteIdentifier,
4
+ quoteTable,
5
+ UnsupportedFeatureError,
6
+ type DialectCompiler,
7
+ type DialectReturningColumn,
8
+ type DialectReturningContext,
9
+ type DialectUpsertContext,
10
+ } from '@zmdb/sql';
11
+
12
+ function outputColumn(
13
+ context: DialectReturningContext,
14
+ pseudoTable: 'INSERTED' | 'DELETED',
15
+ column: DialectReturningColumn,
16
+ ): string {
17
+ if (typeof column === 'string') {
18
+ return column === '*' ? `${pseudoTable}.*` : `${pseudoTable}.${quoteColumn(context.dialect, column)}`;
19
+ }
20
+ return (
21
+ `${pseudoTable}.${quoteColumn(context.dialect, column.column)} AS ` + quoteIdentifier(context.dialect, column.alias)
22
+ );
23
+ }
24
+
25
+ function returning(context: DialectReturningContext) {
26
+ const pseudoTable = context.row === 'old' ? 'DELETED' : 'INSERTED';
27
+ // SQL Server rejects OUTPUT without INTO when the target has an enabled
28
+ // trigger for the statement's DML action. OUTPUT INTO would require a table
29
+ // variable plus a second statement, outside the one-statement compiler contract.
30
+ return Object.freeze({
31
+ inline: ` OUTPUT ${context.columns.map(column => outputColumn(context, pseudoTable, column)).join(', ')}`,
32
+ suffix: '',
33
+ });
34
+ }
35
+
36
+ function upsert(context: DialectUpsertContext): string {
37
+ const target = context.conflict.target;
38
+ if (target === undefined || target.length === 0) {
39
+ throw new UnsupportedFeatureError(
40
+ 'upsert without a conflict target',
41
+ context.dialect.name,
42
+ 'MERGE needs an explicit join predicate; pass the conflicting column(s) to onConflict(...).',
43
+ );
44
+ }
45
+
46
+ const keySet = new Set(context.columns);
47
+ for (const column of target) {
48
+ if (!keySet.has(column)) {
49
+ throw new TypeError(`MERGE conflict target ${JSON.stringify(column)} is not present in values()`);
50
+ }
51
+ }
52
+
53
+ const quoted = (column: string) => quoteIdentifier(context.dialect, column);
54
+ const source = (column: string) => `src.${quoted(column)}`;
55
+ const current = (column: string) => `tgt.${quoted(column)}`;
56
+ const sourceColumns = context.columns.map(quoted).join(', ');
57
+ const predicate = target.map(column => `${current(column)} = ${source(column)}`).join(' AND ');
58
+ let matched = '';
59
+
60
+ if (context.conflict.action === 'update') {
61
+ let setSql: string;
62
+ if (Array.isArray(context.conflict.updateFields)) {
63
+ for (const column of context.conflict.updateFields) {
64
+ if (!keySet.has(column)) {
65
+ throw new TypeError(`MERGE update field ${JSON.stringify(column)} is not present in values()`);
66
+ }
67
+ }
68
+ setSql = context.conflict.updateFields.map(column => `${quoted(column)} = ${source(column)}`).join(', ');
69
+ } else if (context.conflict.updateFields !== undefined) {
70
+ const entries = Object.entries(context.conflict.updateFields);
71
+ if (entries.length === 0) throw new TypeError('MERGE doUpdate() requires at least one update field');
72
+ setSql = entries
73
+ .map(([column, value]) => {
74
+ if (context.isProposedValue(value) && !keySet.has(column)) {
75
+ throw new TypeError(`MERGE proposed field ${JSON.stringify(column)} is not present in values()`);
76
+ }
77
+ return (
78
+ `${quoted(column)} = ` +
79
+ context.renderUpdateValue(column, value, {
80
+ current: current(column),
81
+ proposed: source(column),
82
+ })
83
+ );
84
+ })
85
+ .join(', ');
86
+ } else {
87
+ const targetSet = new Set(target);
88
+ const nonTarget = context.columns.filter(column => !targetSet.has(column));
89
+ const updateColumns = nonTarget.length > 0 ? nonTarget : context.columns;
90
+ setSql = updateColumns.map(column => `${quoted(column)} = ${source(column)}`).join(', ');
91
+ }
92
+ matched = ` WHEN MATCHED THEN UPDATE SET ${setSql}`;
93
+ }
94
+
95
+ // HOLDLOCK supplies the serializable range lock that prevents concurrent
96
+ // upserts from both observing an absent key and racing into INSERT.
97
+ return (
98
+ `MERGE ${quoteTable(context.dialect, context.table)} WITH (HOLDLOCK) AS tgt ` +
99
+ `USING (VALUES (${context.placeholders.join(', ')})) AS src (${sourceColumns}) ON ${predicate}` +
100
+ matched +
101
+ ` WHEN NOT MATCHED THEN INSERT (${sourceColumns}) VALUES (${context.columns.map(source).join(', ')})` +
102
+ `${context.returning.inline};`
103
+ );
104
+ }
105
+
106
+ export const mssqlCompiler: DialectCompiler = Object.freeze({
107
+ returning,
108
+ upsert,
109
+ });
package/src/driver.ts ADDED
@@ -0,0 +1,87 @@
1
+ import { type SelectedDriver, type TransactionalDriver } from '@zmdb/orm';
2
+ import { type CompiledQuery, type SqlDialect } from '@zmdb/sql';
3
+
4
+ /** The node-mssql Request surface used by the adapter. */
5
+ export interface MssqlRequest {
6
+ input(name: string, value: unknown): MssqlRequest;
7
+ query(text: string): Promise<{
8
+ readonly recordset?: readonly Record<string, unknown>[];
9
+ }>;
10
+ }
11
+
12
+ /** The node-mssql Transaction surface used by the adapter. */
13
+ export interface MssqlTransaction {
14
+ begin(): Promise<unknown>;
15
+ commit(): Promise<unknown>;
16
+ rollback(): Promise<unknown>;
17
+ request(): MssqlRequest;
18
+ }
19
+
20
+ /** A connected node-mssql ConnectionPool, expressed structurally. */
21
+ export interface MssqlPool {
22
+ request(): MssqlRequest;
23
+ transaction(): MssqlTransaction;
24
+ }
25
+
26
+ /** Per-request customization without importing the node-mssql runtime. */
27
+ export interface MssqlOptions {
28
+ readonly queryTelemetry?: true;
29
+ readonly configureRequest?: (request: MssqlRequest, query: CompiledQuery) => void;
30
+ }
31
+
32
+ interface MssqlRequestSource {
33
+ request(): MssqlRequest;
34
+ }
35
+
36
+ function bindValue(value: unknown): unknown {
37
+ return value instanceof Date ? value.toISOString() : value;
38
+ }
39
+
40
+ function requestDriver(
41
+ dialect: SqlDialect<'mssql'>,
42
+ source: MssqlRequestSource,
43
+ options: MssqlOptions,
44
+ ): SelectedDriver<'mssql'> {
45
+ return {
46
+ dialect,
47
+ ...(options.queryTelemetry === true ? { queryTelemetry: true as const } : {}),
48
+ async execute(query, executeOptions) {
49
+ executeOptions?.signal?.throwIfAborted();
50
+ const request = source.request();
51
+ options.configureRequest?.(request, query);
52
+ query.parameters.forEach((value, index) => {
53
+ request.input(`p${String(index + 1)}`, bindValue(value));
54
+ });
55
+ const result = await request.query(query.text);
56
+ return result.recordset ?? [];
57
+ },
58
+ };
59
+ }
60
+
61
+ export function createMssqlDriver(
62
+ dialect: SqlDialect<'mssql'>,
63
+ pool: MssqlPool,
64
+ options: MssqlOptions = {},
65
+ ): TransactionalDriver<'mssql'> {
66
+ const driver = requestDriver(dialect, pool, options);
67
+ return {
68
+ ...driver,
69
+ dialect,
70
+ async transaction<Result>(run: (driver: SelectedDriver<'mssql'>) => Promise<Result>): Promise<Result> {
71
+ const transaction = pool.transaction();
72
+ await transaction.begin();
73
+ try {
74
+ const result = await run(requestDriver(dialect, transaction, options));
75
+ await transaction.commit();
76
+ return result;
77
+ } catch (error) {
78
+ try {
79
+ await transaction.rollback();
80
+ } catch {
81
+ // Preserve the query or callback error: rollback failure is secondary.
82
+ }
83
+ throw error;
84
+ }
85
+ },
86
+ };
87
+ }