@spinajs/orm-mssql 2.0.490 → 2.0.494

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.
package/README.md CHANGED
@@ -1,96 +1,96 @@
1
- # `@spinajs/orm-mssql`
2
-
3
- The Microsoft SQL Server dialect driver for [`@spinajs/orm`](../orm), built on
4
- [`@spinajs/orm-sql`](../orm-sql).
5
-
6
- ## Known defect: inserts fail
7
-
8
- **This driver registers no `ServerResponseMapper`.** Every driver must — the shape of an insert
9
- response is dialect-specific and the base class has no default. Any path that reads an insert
10
- response therefore throws:
11
-
12
- ```
13
- no ServerResponseMapper is registered for this connection. Every driver must register one:
14
- container.register(MyMapper).as(ServerResponseMapper)
15
- ```
16
-
17
- That covers `Model.insert()`, `model.insert()`, `model.save()` and every upsert. It reproduces
18
- from this package's own suite — `npm test` gives **10 passing, 2 failing**, both with that
19
- message.
20
-
21
- The fix is a mapper reading the `SELECT SCOPE_IDENTITY() as ID` that `MsSqlInsertQueryCompiler`
22
- already appends to every insert, registered in `resolve()`. See
23
- [docs/README.md](docs/README.md) for a working implementation.
24
-
25
- Until then, treat this driver as **read-capable only**. Selects, schema operations and
26
- transactions all work.
27
-
28
- ## Install
29
-
30
- ```bash
31
- npm install @spinajs/orm @spinajs/orm-mssql
32
- ```
33
-
34
- ## Usage
35
-
36
- ```ts
37
- import { DI } from '@spinajs/di';
38
- import { Orm } from '@spinajs/orm';
39
- import { MsSqlOrmDriver } from '@spinajs/orm-mssql';
40
-
41
- DI.register(MsSqlOrmDriver).as('orm-driver-mssql');
42
- await DI.resolve(Orm);
43
- ```
44
-
45
- ```ts
46
- // configuration
47
- {
48
- db: {
49
- DefaultConnection: 'mssql',
50
- Connections: [
51
- {
52
- Name: 'mssql',
53
- Driver: 'orm-driver-mssql',
54
- Host: '127.0.0.1',
55
- Port: 1433,
56
- User: 'sa',
57
- Password: 'Str0ng!Passw0rd',
58
- Database: 'app',
59
- Options: { Schema: 'dbo', encrypt: false, trustServerCertificate: true },
60
- },
61
- ],
62
- },
63
- }
64
- ```
65
-
66
- ## What is distinctive
67
-
68
- - **`AliasSeparator` defaults to `#`, not `$`** — `$` begins a pseudo-column in T-SQL.
69
- - **Backticks are stripped** from every statement before it is sent, since T-SQL quotes with
70
- `[brackets]`.
71
- - **Three-part table names** — `[database].[schema].[table]`, via `Options.Schema`.
72
- - **`OFFSET ... FETCH NEXT`** instead of `LIMIT`. It is emitted only when a limit is set, so
73
- `skip()` without `take()` applies no offset — and T-SQL requires an `ORDER BY` before `OFFSET`.
74
- - **`DELETE TOP (n)`** for limited deletes.
75
- - **`INSERT IGNORE` throws** — `InsertBehaviour.InsertOrIgnore` is unsupported.
76
- - **Multi-column `ORDER BY` is reduced to one column.**
77
- - **No native `SET`, `ENUM` or `JSON`**, so `whereInSet` / `whereNotInSet` do not work here and
78
- `@Json()` is required for JSON columns.
79
- - **DDL *is* transactional**, unlike MySQL — `Migration.Transaction.Mode = PerMigration` gives a
80
- genuinely atomic migration.
81
-
82
- ## Documentation
83
-
84
- Full documentation lives in **[docs/](docs/)**.
85
-
86
- | | Page |
87
- | --- | --- |
88
- | 01 | [Configuration](docs/01-configuration.md) |
89
- | 02 | [Dialect notes](docs/02-dialect-notes.md) |
90
-
91
- ## Development
92
-
93
- ```bash
94
- npm test # 10 passing, 2 failing — see the defect above
95
- npm run build
96
- ```
1
+ # `@spinajs/orm-mssql`
2
+
3
+ The Microsoft SQL Server dialect driver for [`@spinajs/orm`](../orm), built on
4
+ [`@spinajs/orm-sql`](../orm-sql).
5
+
6
+ ## Known defect: inserts fail
7
+
8
+ **This driver registers no `ServerResponseMapper`.** Every driver must — the shape of an insert
9
+ response is dialect-specific and the base class has no default. Any path that reads an insert
10
+ response therefore throws:
11
+
12
+ ```
13
+ no ServerResponseMapper is registered for this connection. Every driver must register one:
14
+ container.register(MyMapper).as(ServerResponseMapper)
15
+ ```
16
+
17
+ That covers `Model.insert()`, `model.insert()`, `model.save()` and every upsert. It reproduces
18
+ from this package's own suite — `npm test` gives **10 passing, 2 failing**, both with that
19
+ message.
20
+
21
+ The fix is a mapper reading the `SELECT SCOPE_IDENTITY() as ID` that `MsSqlInsertQueryCompiler`
22
+ already appends to every insert, registered in `resolve()`. See
23
+ [docs/README.md](docs/README.md) for a working implementation.
24
+
25
+ Until then, treat this driver as **read-capable only**. Selects, schema operations and
26
+ transactions all work.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ npm install @spinajs/orm @spinajs/orm-mssql
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```ts
37
+ import { DI } from '@spinajs/di';
38
+ import { Orm } from '@spinajs/orm';
39
+ import { MsSqlOrmDriver } from '@spinajs/orm-mssql';
40
+
41
+ DI.register(MsSqlOrmDriver).as('orm-driver-mssql');
42
+ await DI.resolve(Orm);
43
+ ```
44
+
45
+ ```ts
46
+ // configuration
47
+ {
48
+ db: {
49
+ DefaultConnection: 'mssql',
50
+ Connections: [
51
+ {
52
+ Name: 'mssql',
53
+ Driver: 'orm-driver-mssql',
54
+ Host: '127.0.0.1',
55
+ Port: 1433,
56
+ User: 'sa',
57
+ Password: 'Str0ng!Passw0rd',
58
+ Database: 'app',
59
+ Options: { Schema: 'dbo', encrypt: false, trustServerCertificate: true },
60
+ },
61
+ ],
62
+ },
63
+ }
64
+ ```
65
+
66
+ ## What is distinctive
67
+
68
+ - **`AliasSeparator` defaults to `#`, not `$`** — `$` begins a pseudo-column in T-SQL.
69
+ - **Backticks are stripped** from every statement before it is sent, since T-SQL quotes with
70
+ `[brackets]`.
71
+ - **Three-part table names** — `[database].[schema].[table]`, via `Options.Schema`.
72
+ - **`OFFSET ... FETCH NEXT`** instead of `LIMIT`. It is emitted only when a limit is set, so
73
+ `skip()` without `take()` applies no offset — and T-SQL requires an `ORDER BY` before `OFFSET`.
74
+ - **`DELETE TOP (n)`** for limited deletes.
75
+ - **`INSERT IGNORE` throws** — `InsertBehaviour.InsertOrIgnore` is unsupported.
76
+ - **Multi-column `ORDER BY` is reduced to one column.**
77
+ - **No native `SET`, `ENUM` or `JSON`**, so `whereInSet` / `whereNotInSet` do not work here and
78
+ `@Json()` is required for JSON columns.
79
+ - **DDL *is* transactional**, unlike MySQL — `Migration.Transaction.Mode = PerMigration` gives a
80
+ genuinely atomic migration.
81
+
82
+ ## Documentation
83
+
84
+ Full documentation lives in **[docs/](docs/)**.
85
+
86
+ | | Page |
87
+ | --- | --- |
88
+ | 01 | [Configuration](docs/01-configuration.md) |
89
+ | 02 | [Dialect notes](docs/02-dialect-notes.md) |
90
+
91
+ ## Development
92
+
93
+ ```bash
94
+ npm test # 10 passing, 2 failing — see the defect above
95
+ npm run build
96
+ ```
@@ -59,15 +59,15 @@ let MsSqlOnDuplicateQueryCompiler = class MsSqlOnDuplicateQueryCompiler extends
59
59
  });
60
60
  return {
61
61
  bindings: wBindings.concat(bindings),
62
- expression: `MERGE INTO ${table} WITH (HOLDLOCK) AS target
62
+ expression: `MERGE INTO ${table} WITH (HOLDLOCK) AS target
63
63
  USING (SELECT * FROM ${table} WHERE ${this._builder.getColumn().map((c) => {
64
64
  return `${c} = ?`;
65
- })}) as source
66
- ON (target.${descriptor.PrimaryKey[0]} = source.${descriptor.PrimaryKey[0]})
67
- WHEN MATCHED
68
- THEN UPDATE
69
- SET ${columns}
70
- WHEN NOT MATCHED
65
+ })}) as source
66
+ ON (target.${descriptor.PrimaryKey[0]} = source.${descriptor.PrimaryKey[0]})
67
+ WHEN MATCHED
68
+ THEN UPDATE
69
+ SET ${columns}
70
+ WHEN NOT MATCHED
71
71
  THEN `.replace(/(\r\n|\n|\r)/gm, ''),
72
72
  };
73
73
  }
@@ -53,15 +53,15 @@ let MsSqlOnDuplicateQueryCompiler = class MsSqlOnDuplicateQueryCompiler extends
53
53
  });
54
54
  return {
55
55
  bindings: wBindings.concat(bindings),
56
- expression: `MERGE INTO ${table} WITH (HOLDLOCK) AS target
56
+ expression: `MERGE INTO ${table} WITH (HOLDLOCK) AS target
57
57
  USING (SELECT * FROM ${table} WHERE ${this._builder.getColumn().map((c) => {
58
58
  return `${c} = ?`;
59
- })}) as source
60
- ON (target.${descriptor.PrimaryKey[0]} = source.${descriptor.PrimaryKey[0]})
61
- WHEN MATCHED
62
- THEN UPDATE
63
- SET ${columns}
64
- WHEN NOT MATCHED
59
+ })}) as source
60
+ ON (target.${descriptor.PrimaryKey[0]} = source.${descriptor.PrimaryKey[0]})
61
+ WHEN MATCHED
62
+ THEN UPDATE
63
+ SET ${columns}
64
+ WHEN NOT MATCHED
65
65
  THEN `.replace(/(\r\n|\n|\r)/gm, ''),
66
66
  };
67
67
  }