@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 +96 -96
- package/lib/cjs/compilers.js +7 -7
- package/lib/mjs/compilers.js +7 -7
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +68 -66
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
|
+
```
|
package/lib/cjs/compilers.js
CHANGED
|
@@ -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
|
}
|
package/lib/mjs/compilers.js
CHANGED
|
@@ -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
|
}
|