@deterministic-code/datasources-sqlserver 0.0.0-stage → 0.1.2

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,5 @@
1
+ import { AlterTableStatementTextRenderer, type AlterAction, type AlterTableStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerAlterTableStatementRenderer extends AlterTableStatementTextRenderer {
3
+ renderAlter(statement: AlterTableStatement): string;
4
+ protected actionSql(action: AlterAction): string;
5
+ }
@@ -0,0 +1,15 @@
1
+ import { AlterTableStatementTextRenderer, } from "@deterministic-code/datasources";
2
+ export class SqlServerAlterTableStatementRenderer extends AlterTableStatementTextRenderer {
3
+ renderAlter(statement) {
4
+ return statement.action.kind === "renameColumn"
5
+ ? `EXEC sp_rename '${statement.table}.${statement.action.from}', '${statement.action.to}', 'COLUMN'`
6
+ : statement.action.kind === "renameTable"
7
+ ? `EXEC sp_rename '${statement.table}', '${statement.action.to}'`
8
+ : super.renderAlter(statement);
9
+ }
10
+ actionSql(action) {
11
+ return action.kind === "alterColumn"
12
+ ? `ALTER COLUMN ${this.quote(action.column.name)} ${this.typeName(action.column)}${this.notNullClause(action.column)}`
13
+ : super.actionSql(action);
14
+ }
15
+ }
@@ -0,0 +1,4 @@
1
+ import { CreateTableStatementTextRenderer, type Column } from "@deterministic-code/datasources";
2
+ export declare class SqlServerCreateTableStatementRenderer extends CreateTableStatementTextRenderer {
3
+ protected identity(column: Column): string;
4
+ }
@@ -0,0 +1,6 @@
1
+ import { CreateTableStatementTextRenderer } from "@deterministic-code/datasources";
2
+ export class SqlServerCreateTableStatementRenderer extends CreateTableStatementTextRenderer {
3
+ identity(column) {
4
+ return column.identity ? " IDENTITY(1,1)" : "";
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ import { CreateTriggerStatementTextRenderer, type CreateTriggerStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerCreateTriggerStatementRenderer extends CreateTriggerStatementTextRenderer {
3
+ render(statement: CreateTriggerStatement): string;
4
+ }
@@ -0,0 +1,12 @@
1
+ import { CreateTriggerStatementTextRenderer } from "@deterministic-code/datasources";
2
+ export class SqlServerCreateTriggerStatementRenderer extends CreateTriggerStatementTextRenderer {
3
+ render(statement) {
4
+ return `CREATE TRIGGER ${statement.name} ON ${statement.table}
5
+ AFTER UPDATE AS
6
+ BEGIN
7
+ SET NOCOUNT ON;
8
+ UPDATE ${statement.table} SET ${statement.updatedColumn} = ${statement.utcNow}
9
+ FROM ${statement.table} t INNER JOIN inserted i ON t.${statement.keyColumn} = i.${statement.keyColumn};
10
+ END`;
11
+ }
12
+ }
@@ -0,0 +1,14 @@
1
+ import { DefaultValueConverter, DeterministicTypeConverter, StatementTextRenderer, type Cell, type DatasourceOptions, type ICommand, type IConnection, type IDriver, type Information, type ITransaction, type IsolationLevel, type TypeConverter } from "@deterministic-code/datasources";
2
+ export declare class SqlServerDriver implements IDriver {
3
+ readonly statementRenderer: StatementTextRenderer;
4
+ readonly information: Information;
5
+ rowTypeConverters: Record<string, TypeConverter<Cell, Cell>>;
6
+ readonly quoteLeft = "[";
7
+ readonly quoteRight = "]";
8
+ readonly typeConverter: DeterministicTypeConverter;
9
+ readonly defaultValueConverter: DefaultValueConverter;
10
+ columnType: (name: string) => string;
11
+ connection: (options?: DatasourceOptions) => IConnection;
12
+ command: (connection: IConnection) => ICommand;
13
+ transaction: (connection: IConnection, _isolation?: IsolationLevel) => ITransaction;
14
+ }
@@ -0,0 +1,62 @@
1
+ import { columnType as identityColumnType, DefaultValueConverter, DeterministicTypeConverter, StatementTextRenderer, StubTransaction, } from "@deterministic-code/datasources";
2
+ import { SqlServerConnection } from "./connection.js";
3
+ import { SqlServerStatementRenderer } from "./SqlServerStatementRenderer.js";
4
+ const statements = new StatementTextRenderer(t => new SqlServerStatementRenderer(t));
5
+ export class SqlServerDriver {
6
+ statementRenderer = statements;
7
+ information = {
8
+ descriptions: ["SQL Server driver."],
9
+ overrides: [
10
+ "Overrides CreateCreateStoredProcedureStatement to PROCEDURE Create{Plural}",
11
+ "Overrides CreateReadStoredProcedureStatement to PROCEDURE Read{Plural}By{Properties}",
12
+ "Overrides CreateUpdateStoredProcedureStatement to PROCEDURE Update{Plural}By{Properties}",
13
+ "Overrides CreateDeleteStoredProcedureStatement to PROCEDURE Delete{Plural}By{Properties}",
14
+ "Overrides CreateBulkCreateStoredProcedureStatement to PROCEDURE BulkCreate{Plural}",
15
+ "Overrides CreateBulkUpdateStoredProcedureStatement to PROCEDURE BulkUpdate{Plural}",
16
+ "Overrides CreateBulkDeleteStoredProcedureStatement to PROCEDURE BulkDelete{Plural}",
17
+ ],
18
+ changeLogs: [],
19
+ };
20
+ rowTypeConverters = {};
21
+ quoteLeft = "[";
22
+ quoteRight = "]";
23
+ typeConverter = new DeterministicTypeConverter({
24
+ string: "NVARCHAR(MAX)",
25
+ character: "NCHAR(1)",
26
+ number: "INT",
27
+ integer: "INT",
28
+ unsignedinteger: "BIGINT",
29
+ smallinteger: "SMALLINT",
30
+ unsignedsmallinteger: "INT",
31
+ biginteger: "BIGINT",
32
+ unsignedbiginteger: "DECIMAL(20)",
33
+ float: "FLOAT",
34
+ decimal: "DECIMAL",
35
+ boolean: "BIT",
36
+ datetime: "DATETIME2",
37
+ binary: "VARBINARY(MAX)",
38
+ uuid: "UNIQUEIDENTIFIER",
39
+ reference: "INT",
40
+ }, {
41
+ dialectName: "sqlserver",
42
+ stringUnlimited: "NVARCHAR(MAX)",
43
+ stringSized: (n) => `NVARCHAR(${n})`,
44
+ character: "NCHAR",
45
+ decimal: { kind: "required", type: "DECIMAL" },
46
+ binaryUnlimited: "VARBINARY(MAX)",
47
+ binarySized: (n) => `VARBINARY(${n})`,
48
+ });
49
+ defaultValueConverter = new DefaultValueConverter({
50
+ newId: () => "NEWID()",
51
+ now: () => "GETDATE()",
52
+ utcNow: () => "GETUTCDATE()",
53
+ booleanOn: "1",
54
+ booleanOff: "0",
55
+ hex: (arg) => `0x${arg}`,
56
+ hexReverse: /^0x(.*)$/,
57
+ });
58
+ columnType = identityColumnType;
59
+ connection = (options) => SqlServerConnection.from(options);
60
+ command = (connection) => connection.createCommand();
61
+ transaction = (connection, _isolation) => new StubTransaction(connection.provider, connection);
62
+ }
@@ -0,0 +1,4 @@
1
+ import { DropIndexStatementTextRenderer, type DropIndexStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerDropIndexStatementRenderer extends DropIndexStatementTextRenderer {
3
+ render(statement: DropIndexStatement): string;
4
+ }
@@ -0,0 +1,6 @@
1
+ import { DropIndexStatementTextRenderer } from "@deterministic-code/datasources";
2
+ export class SqlServerDropIndexStatementRenderer extends DropIndexStatementTextRenderer {
3
+ render(statement) {
4
+ return `DROP INDEX ${statement.name} ON ${statement.table}`;
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ import { DropRoutineStatementTextRenderer, type DropRoutineStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerDropRoutineStatementRenderer extends DropRoutineStatementTextRenderer {
3
+ render(statement: DropRoutineStatement): string;
4
+ }
@@ -0,0 +1,6 @@
1
+ import { DropRoutineStatementTextRenderer } from "@deterministic-code/datasources";
2
+ export class SqlServerDropRoutineStatementRenderer extends DropRoutineStatementTextRenderer {
3
+ render(statement) {
4
+ return `DROP PROCEDURE IF EXISTS ${statement.name}`;
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ import { IdentityInsertStatementTextRenderer, type IdentityInsertStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerIdentityInsertStatementRenderer extends IdentityInsertStatementTextRenderer {
3
+ render(statement: IdentityInsertStatement): string;
4
+ }
@@ -0,0 +1,12 @@
1
+ import { IdentityInsertStatementTextRenderer, } from "@deterministic-code/datasources";
2
+ export class SqlServerIdentityInsertStatementRenderer extends IdentityInsertStatementTextRenderer {
3
+ render(statement) {
4
+ const inserts = super.render(statement);
5
+ if (!statement.identity || statement.inserts.length === 0)
6
+ return inserts;
7
+ const quoted = statement.inserts[0].table;
8
+ return `SET IDENTITY_INSERT ${quoted} ON;
9
+ ${inserts}
10
+ SET IDENTITY_INSERT ${quoted} OFF`;
11
+ }
12
+ }
@@ -0,0 +1,17 @@
1
+ import { AlterTableStatement, CreateBulkCreateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateCreateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateTableStatement, CreateTriggerStatement, CreateUpdateStoredProcedureStatement, DropIndexStatement, DropRoutineStatement, IdentityInsertStatement, StatementRenderer, type StatementTextRenderer } from "@deterministic-code/datasources";
2
+ export declare class SqlServerStatementRenderer extends StatementRenderer {
3
+ constructor(text: StatementTextRenderer);
4
+ protected visitCreateTable(create: CreateTableStatement): string;
5
+ protected visitAlterTable(alter: AlterTableStatement): string;
6
+ protected visitDropIndex(index: DropIndexStatement): string;
7
+ protected visitCreateTrigger(trigger: CreateTriggerStatement): string;
8
+ protected visitIdentityInsert(insert: IdentityInsertStatement): string;
9
+ protected visitDropRoutine(routine: DropRoutineStatement): string;
10
+ protected visitCreateCreateStoredProcedureStatement(statement: CreateCreateStoredProcedureStatement): string;
11
+ protected visitCreateReadStoredProcedureStatement(statement: CreateReadStoredProcedureStatement): string;
12
+ protected visitCreateUpdateStoredProcedureStatement(statement: CreateUpdateStoredProcedureStatement): string;
13
+ protected visitCreateDeleteStoredProcedureStatement(statement: CreateDeleteStoredProcedureStatement): string;
14
+ protected visitCreateBulkCreateStoredProcedureStatement(statement: CreateBulkCreateStoredProcedureStatement): string;
15
+ protected visitCreateBulkUpdateStoredProcedureStatement(statement: CreateBulkUpdateStoredProcedureStatement): string;
16
+ protected visitCreateBulkDeleteStoredProcedureStatement(statement: CreateBulkDeleteStoredProcedureStatement): string;
17
+ }
@@ -0,0 +1,52 @@
1
+ import { StatementRenderer, } from "@deterministic-code/datasources";
2
+ import { SqlServerAlterTableStatementRenderer } from "./SqlServerAlterTableStatementRenderer.js";
3
+ import { SqlServerCreateTableStatementRenderer } from "./SqlServerCreateTableStatementRenderer.js";
4
+ import { SqlServerCreateTriggerStatementRenderer } from "./SqlServerCreateTriggerStatementRenderer.js";
5
+ import { SqlServerDropIndexStatementRenderer } from "./SqlServerDropIndexStatementRenderer.js";
6
+ import { SqlServerDropRoutineStatementRenderer } from "./SqlServerDropRoutineStatementRenderer.js";
7
+ import { SqlServerStoredProcedureStatementRenderer } from "./SqlServerStoredProcedureStatementRenderer.js";
8
+ import { SqlServerIdentityInsertStatementRenderer } from "./SqlServerIdentityInsertStatementRenderer.js";
9
+ export class SqlServerStatementRenderer extends StatementRenderer {
10
+ constructor(text) {
11
+ super(text);
12
+ }
13
+ visitCreateTable(create) {
14
+ return new SqlServerCreateTableStatementRenderer().render(create);
15
+ }
16
+ visitAlterTable(alter) {
17
+ return new SqlServerAlterTableStatementRenderer().renderAlter(alter);
18
+ }
19
+ visitDropIndex(index) {
20
+ return new SqlServerDropIndexStatementRenderer().render(index);
21
+ }
22
+ visitCreateTrigger(trigger) {
23
+ return new SqlServerCreateTriggerStatementRenderer().render(trigger);
24
+ }
25
+ visitIdentityInsert(insert) {
26
+ return new SqlServerIdentityInsertStatementRenderer().render(insert);
27
+ }
28
+ visitDropRoutine(routine) {
29
+ return new SqlServerDropRoutineStatementRenderer().render(routine);
30
+ }
31
+ visitCreateCreateStoredProcedureStatement(statement) {
32
+ return new SqlServerStoredProcedureStatementRenderer().renderCreate(statement);
33
+ }
34
+ visitCreateReadStoredProcedureStatement(statement) {
35
+ return new SqlServerStoredProcedureStatementRenderer().renderRead(statement);
36
+ }
37
+ visitCreateUpdateStoredProcedureStatement(statement) {
38
+ return new SqlServerStoredProcedureStatementRenderer().renderUpdate(statement);
39
+ }
40
+ visitCreateDeleteStoredProcedureStatement(statement) {
41
+ return new SqlServerStoredProcedureStatementRenderer().renderDelete(statement);
42
+ }
43
+ visitCreateBulkCreateStoredProcedureStatement(statement) {
44
+ return new SqlServerStoredProcedureStatementRenderer().renderBulkCreate(statement);
45
+ }
46
+ visitCreateBulkUpdateStoredProcedureStatement(statement) {
47
+ return new SqlServerStoredProcedureStatementRenderer().renderBulkUpdate(statement);
48
+ }
49
+ visitCreateBulkDeleteStoredProcedureStatement(statement) {
50
+ return new SqlServerStoredProcedureStatementRenderer().renderBulkDelete(statement);
51
+ }
52
+ }
@@ -0,0 +1,10 @@
1
+ import type { CreateBulkCreateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateCreateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateUpdateStoredProcedureStatement } from "@deterministic-code/datasources";
2
+ export declare class SqlServerStoredProcedureStatementRenderer {
3
+ renderCreate(statement: CreateCreateStoredProcedureStatement): string;
4
+ renderRead(statement: CreateReadStoredProcedureStatement): string;
5
+ renderUpdate(statement: CreateUpdateStoredProcedureStatement): string;
6
+ renderDelete(statement: CreateDeleteStoredProcedureStatement): string;
7
+ renderBulkCreate(statement: CreateBulkCreateStoredProcedureStatement): string;
8
+ renderBulkUpdate(statement: CreateBulkUpdateStoredProcedureStatement): string;
9
+ renderBulkDelete(statement: CreateBulkDeleteStoredProcedureStatement): string;
10
+ }
@@ -0,0 +1,112 @@
1
+ const params = (list) => list.map((p) => ` @${p.name} ${p.type}`).join(",\n");
2
+ const openjson = (columns) => columns.map((c) => `${c.name} ${c.type} '$.${c.name}'`).join(", ");
3
+ export class SqlServerStoredProcedureStatementRenderer {
4
+ renderCreate(statement) {
5
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
6
+ ${params(statement.parameters)}
7
+ AS
8
+ BEGIN
9
+ INSERT INTO ${statement.table} (${statement.parameters.map((p) => p.name).join(", ")})
10
+ VALUES (${statement.parameters.map((p) => `@${p.name}`).join(", ")});
11
+ SELECT CAST(SCOPE_IDENTITY() AS BIGINT) AS ${statement.key};
12
+ END;
13
+ GO`;
14
+ }
15
+ renderRead(statement) {
16
+ const cols = statement.columns.join(", ");
17
+ if (statement.byProperties.length === 0) {
18
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
19
+ AS
20
+ BEGIN
21
+ SELECT ${cols} FROM ${statement.table} ORDER BY ${statement.key};
22
+ END;
23
+ GO`;
24
+ }
25
+ const signature = statement.byProperties
26
+ .map((c) => `@${c} ${statement.parameters.find((p) => p.name === c)?.type ?? statement.keyType}`)
27
+ .join(", ");
28
+ const pred = statement.byProperties.map((c) => `${c} = @${c}`).join(" AND ");
29
+ return `CREATE OR ALTER PROCEDURE ${statement.name} ${signature}
30
+ AS
31
+ BEGIN
32
+ SELECT ${cols} FROM ${statement.table} WHERE ${pred};
33
+ END;
34
+ GO`;
35
+ }
36
+ renderUpdate(statement) {
37
+ const sets = statement.writable.map((c) => ` ${c} = @${c}`);
38
+ if (statement.auditUpdated !== undefined) {
39
+ const auditParam = statement.parameters.find((p) => p.name.includes("new_updated"));
40
+ if (auditParam)
41
+ sets.push(` ${statement.auditUpdated} = @${auditParam.name}`);
42
+ }
43
+ const by = statement.byProperties.length > 0 ? statement.byProperties : [statement.key];
44
+ const pred = by.map((c) => `${c} = @${c}`).join(" AND ");
45
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
46
+ ${params(statement.parameters)}
47
+ AS
48
+ BEGIN
49
+ UPDATE ${statement.table}
50
+ SET
51
+ ${sets.join(",\n")}
52
+ WHERE ${pred};
53
+ SELECT @@ROWCOUNT AS affected;
54
+ END;
55
+ GO`;
56
+ }
57
+ renderDelete(statement) {
58
+ const by = statement.byProperties.length > 0 ? statement.byProperties : [statement.key];
59
+ const signature = by
60
+ .map((c) => `@${c} ${statement.parameters.find((p) => p.name === c)?.type ?? statement.keyType}`)
61
+ .join(", ");
62
+ const pred = by.map((c) => `${c} = @${c}`).join(" AND ");
63
+ return `CREATE OR ALTER PROCEDURE ${statement.name} ${signature}
64
+ AS
65
+ BEGIN
66
+ DELETE FROM ${statement.table} WHERE ${pred};
67
+ SELECT @@ROWCOUNT AS affected;
68
+ END;
69
+ GO`;
70
+ }
71
+ renderBulkCreate(statement) {
72
+ const cols = statement.columns.map((c) => c.name).join(", ");
73
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
74
+ @${statement.payload.name} NVARCHAR(MAX),
75
+ @ids NVARCHAR(MAX) OUTPUT
76
+ AS
77
+ BEGIN
78
+ INSERT INTO ${statement.table} (${cols})
79
+ SELECT ${cols}
80
+ FROM OPENJSON(@${statement.payload.name}) WITH (${openjson(statement.columns)});
81
+ SET @ids = (SELECT ${statement.key} FROM ${statement.table} WHERE ${statement.key} >= SCOPE_IDENTITY() FOR JSON PATH);
82
+ END;
83
+ GO`;
84
+ }
85
+ renderBulkUpdate(statement) {
86
+ const sets = statement.columns
87
+ .filter((c) => c.name !== statement.key)
88
+ .map((c) => `t.${c.name} = payload_rows.${c.name}`)
89
+ .join(", ");
90
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
91
+ @${statement.payload.name} NVARCHAR(MAX)
92
+ AS
93
+ BEGIN
94
+ UPDATE t SET ${sets}
95
+ FROM ${statement.table} t
96
+ JOIN OPENJSON(@${statement.payload.name}) WITH (${openjson(statement.columns)}) AS payload_rows
97
+ ON t.${statement.key} = payload_rows.${statement.key};
98
+ END;
99
+ GO`;
100
+ }
101
+ renderBulkDelete(statement) {
102
+ return `CREATE OR ALTER PROCEDURE ${statement.name}
103
+ @${statement.payload.name} NVARCHAR(MAX)
104
+ AS
105
+ BEGIN
106
+ DELETE t FROM ${statement.table} t
107
+ JOIN OPENJSON(@${statement.payload.name}) WITH (${statement.key} ${statement.keyType} '$.${statement.key}') AS payload_rows
108
+ ON t.${statement.key} = payload_rows.${statement.key};
109
+ END;
110
+ GO`;
111
+ }
112
+ }
@@ -0,0 +1,6 @@
1
+ import { StubConnection, type DatasourceOptions, type ICommand } from "@deterministic-code/datasources";
2
+ export declare class SqlServerConnection extends StubConnection {
3
+ constructor(_options?: DatasourceOptions);
4
+ createCommand: () => ICommand;
5
+ static from: (options?: DatasourceOptions) => SqlServerConnection;
6
+ }
@@ -0,0 +1,8 @@
1
+ import { StubCommand, StubConnection, } from "@deterministic-code/datasources";
2
+ export class SqlServerConnection extends StubConnection {
3
+ constructor(_options) {
4
+ super("sqlserver");
5
+ }
6
+ createCommand = () => new StubCommand(this.provider, this);
7
+ static from = (options) => new SqlServerConnection(options);
8
+ }
@@ -0,0 +1 @@
1
+ export { SqlServerDriver } from "./SqlServerDriver.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { SqlServerDriver } from "./SqlServerDriver.js";
package/package.json CHANGED
@@ -1,6 +1,23 @@
1
1
  {
2
2
  "name": "@deterministic-code/datasources-sqlserver",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.js",
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "dependencies": {
21
+ "@deterministic-code/datasources": "^0.1.2"
22
+ }
23
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.