@spinajs/orm-sql 2.0.491 → 2.0.495
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 +69 -69
- package/lib/cjs/compilers.js +26 -26
- package/lib/mjs/compilers.js +26 -26
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +64 -62
package/README.md
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
# `@spinajs/orm-sql`
|
|
2
|
-
|
|
3
|
-
The generic SQL layer for [`@spinajs/orm`](../orm): concrete, dialect-neutral statements and
|
|
4
|
-
compilers, plus `SqlDriver` — the base class every dialect driver extends.
|
|
5
|
-
|
|
6
|
-
You rarely install it directly. It arrives as a dependency of
|
|
7
|
-
[`@spinajs/orm-sqlite`](../orm-sqlite), [`@spinajs/orm-mysql`](../orm-mysql) or
|
|
8
|
-
[`@spinajs/orm-mssql`](../orm-mssql).
|
|
9
|
-
|
|
10
|
-
## What it provides
|
|
11
|
-
|
|
12
|
-
- **`SqlDriver`** — implements `OrmDriver.execute()` in terms of one abstract method,
|
|
13
|
-
`executeOnDb(stmt, params, context)`. A dialect driver only has to know how to send a string
|
|
14
|
-
with bindings to its server.
|
|
15
|
-
- **Statements** — `SqlWhereStatement`, `SqlJoinStatement`, `SqlColumnStatement`,
|
|
16
|
-
`SqlInStatement`, `SqlExistsQueryStatement` and the rest.
|
|
17
|
-
- **Compilers** — one per query shape, from `SqlSelectQueryCompiler` to
|
|
18
|
-
`SqlTableHistoryQueryCompiler`.
|
|
19
|
-
- **Converters** — `SqlDatetimeValueConverter`, `SqlBooleanValueConverter`,
|
|
20
|
-
`SqlTimeValueConverter`, `SqlSetConverter`.
|
|
21
|
-
|
|
22
|
-
`SqlDriver.resolve()` registers all of it into the driver's own child DI container, so a dialect
|
|
23
|
-
overrides only what genuinely differs.
|
|
24
|
-
|
|
25
|
-
## Usage
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
import { SqlDriver } from '@spinajs/orm-sql';
|
|
29
|
-
import { QueryContext, ServerResponseMapper } from '@spinajs/orm';
|
|
30
|
-
import { Injectable } from '@spinajs/di';
|
|
31
|
-
|
|
32
|
-
@Injectable('orm-driver-mydb')
|
|
33
|
-
export class MyDbOrmDriver extends SqlDriver {
|
|
34
|
-
public async executeOnDb(stmt: string, params: unknown[], _context: QueryContext) {
|
|
35
|
-
return this.withReconnect(() => myClient.query(stmt, params));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public resolve() {
|
|
39
|
-
super.resolve();
|
|
40
|
-
// Mandatory: no generic implementation exists for either of these.
|
|
41
|
-
this.Container.register(MyServerResponseMapper).as(ServerResponseMapper);
|
|
42
|
-
this.Container.register(MyTableExistsCompiler).as(TableExistsCompiler);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ... connect / disconnect / ping / supportedFeatures / tableInfo
|
|
46
|
-
// ... plus the six transaction primitives
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Documentation
|
|
51
|
-
|
|
52
|
-
Full documentation lives in **[docs/](docs/)**.
|
|
53
|
-
|
|
54
|
-
| | Page |
|
|
55
|
-
| --- | --- |
|
|
56
|
-
| 01 | [Overview](docs/01-overview.md) |
|
|
57
|
-
| 02 | [Compilers](docs/02-compilers.md) |
|
|
58
|
-
| 03 | [Statements](docs/03-statements.md) |
|
|
59
|
-
| 04 | [Writing a driver](docs/04-writing-a-driver.md) |
|
|
60
|
-
|
|
61
|
-
See also [the core's architecture page](../orm/docs/12-architecture.md) for how a query becomes
|
|
62
|
-
SQL, end to end.
|
|
63
|
-
|
|
64
|
-
## Development
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
npm test # compiles builders and asserts on the SQL — no database required
|
|
68
|
-
npm run build
|
|
69
|
-
```
|
|
1
|
+
# `@spinajs/orm-sql`
|
|
2
|
+
|
|
3
|
+
The generic SQL layer for [`@spinajs/orm`](../orm): concrete, dialect-neutral statements and
|
|
4
|
+
compilers, plus `SqlDriver` — the base class every dialect driver extends.
|
|
5
|
+
|
|
6
|
+
You rarely install it directly. It arrives as a dependency of
|
|
7
|
+
[`@spinajs/orm-sqlite`](../orm-sqlite), [`@spinajs/orm-mysql`](../orm-mysql) or
|
|
8
|
+
[`@spinajs/orm-mssql`](../orm-mssql).
|
|
9
|
+
|
|
10
|
+
## What it provides
|
|
11
|
+
|
|
12
|
+
- **`SqlDriver`** — implements `OrmDriver.execute()` in terms of one abstract method,
|
|
13
|
+
`executeOnDb(stmt, params, context)`. A dialect driver only has to know how to send a string
|
|
14
|
+
with bindings to its server.
|
|
15
|
+
- **Statements** — `SqlWhereStatement`, `SqlJoinStatement`, `SqlColumnStatement`,
|
|
16
|
+
`SqlInStatement`, `SqlExistsQueryStatement` and the rest.
|
|
17
|
+
- **Compilers** — one per query shape, from `SqlSelectQueryCompiler` to
|
|
18
|
+
`SqlTableHistoryQueryCompiler`.
|
|
19
|
+
- **Converters** — `SqlDatetimeValueConverter`, `SqlBooleanValueConverter`,
|
|
20
|
+
`SqlTimeValueConverter`, `SqlSetConverter`.
|
|
21
|
+
|
|
22
|
+
`SqlDriver.resolve()` registers all of it into the driver's own child DI container, so a dialect
|
|
23
|
+
overrides only what genuinely differs.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { SqlDriver } from '@spinajs/orm-sql';
|
|
29
|
+
import { QueryContext, ServerResponseMapper } from '@spinajs/orm';
|
|
30
|
+
import { Injectable } from '@spinajs/di';
|
|
31
|
+
|
|
32
|
+
@Injectable('orm-driver-mydb')
|
|
33
|
+
export class MyDbOrmDriver extends SqlDriver {
|
|
34
|
+
public async executeOnDb(stmt: string, params: unknown[], _context: QueryContext) {
|
|
35
|
+
return this.withReconnect(() => myClient.query(stmt, params));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public resolve() {
|
|
39
|
+
super.resolve();
|
|
40
|
+
// Mandatory: no generic implementation exists for either of these.
|
|
41
|
+
this.Container.register(MyServerResponseMapper).as(ServerResponseMapper);
|
|
42
|
+
this.Container.register(MyTableExistsCompiler).as(TableExistsCompiler);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ... connect / disconnect / ping / supportedFeatures / tableInfo
|
|
46
|
+
// ... plus the six transaction primitives
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Documentation
|
|
51
|
+
|
|
52
|
+
Full documentation lives in **[docs/](docs/)**.
|
|
53
|
+
|
|
54
|
+
| | Page |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| 01 | [Overview](docs/01-overview.md) |
|
|
57
|
+
| 02 | [Compilers](docs/02-compilers.md) |
|
|
58
|
+
| 03 | [Statements](docs/03-statements.md) |
|
|
59
|
+
| 04 | [Writing a driver](docs/04-writing-a-driver.md) |
|
|
60
|
+
|
|
61
|
+
See also [the core's architecture page](../orm/docs/12-architecture.md) for how a query becomes
|
|
62
|
+
SQL, end to end.
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm test # compiles builders and asserts on the SQL — no database required
|
|
68
|
+
npm run build
|
|
69
|
+
```
|
package/lib/cjs/compilers.js
CHANGED
|
@@ -946,8 +946,8 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends or
|
|
|
946
946
|
...dropUnique,
|
|
947
947
|
{
|
|
948
948
|
bindings: [],
|
|
949
|
-
expression: `ALTER TABLE ${hTtblName}
|
|
950
|
-
CHANGE COLUMN ${pKey.Name} ${pKey.Name} INT NOT NULL ,
|
|
949
|
+
expression: `ALTER TABLE ${hTtblName}
|
|
950
|
+
CHANGE COLUMN ${pKey.Name} ${pKey.Name} INT NOT NULL ,
|
|
951
951
|
DROP PRIMARY KEY;`,
|
|
952
952
|
},
|
|
953
953
|
// remove primary key & add history columns
|
|
@@ -961,12 +961,12 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends or
|
|
|
961
961
|
},
|
|
962
962
|
{
|
|
963
963
|
bindings: [],
|
|
964
|
-
expression: `DELIMITER $$
|
|
965
|
-
CREATE TRIGGER ${hTriggerName}__insert_trigger BEFORE INSERT ON ${hTtblName} FOR EACH ROW
|
|
966
|
-
BEGIN
|
|
967
|
-
DECLARE rev INT;
|
|
968
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
969
|
-
SET NEW.__revision__ = rev + 1;
|
|
964
|
+
expression: `DELIMITER $$
|
|
965
|
+
CREATE TRIGGER ${hTriggerName}__insert_trigger BEFORE INSERT ON ${hTtblName} FOR EACH ROW
|
|
966
|
+
BEGIN
|
|
967
|
+
DECLARE rev INT;
|
|
968
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
969
|
+
SET NEW.__revision__ = rev + 1;
|
|
970
970
|
END;`,
|
|
971
971
|
},
|
|
972
972
|
// create tracking triggers
|
|
@@ -985,32 +985,32 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends or
|
|
|
985
985
|
// insert into history table & update __end__ date for all operations
|
|
986
986
|
{
|
|
987
987
|
bindings: [],
|
|
988
|
-
expression: `DELIMITER $$
|
|
989
|
-
CREATE TRIGGER ${tblTriggerName}__insert_trigger AFTER INSERT ON ${tblName} FOR EACH ROW BEGIN
|
|
990
|
-
DECLARE rev INT;
|
|
991
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
992
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
993
|
-
INSERT INTO ${hTtblName} SELECT 'insert', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
988
|
+
expression: `DELIMITER $$
|
|
989
|
+
CREATE TRIGGER ${tblTriggerName}__insert_trigger AFTER INSERT ON ${tblName} FOR EACH ROW BEGIN
|
|
990
|
+
DECLARE rev INT;
|
|
991
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
992
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
993
|
+
INSERT INTO ${hTtblName} SELECT 'insert', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
994
994
|
END;`,
|
|
995
995
|
},
|
|
996
996
|
{
|
|
997
997
|
bindings: [],
|
|
998
|
-
expression: `DELIMITER $$
|
|
999
|
-
CREATE TRIGGER ${tblTriggerName}__update_trigger AFTER UPDATE ON ${tblName} FOR EACH ROW BEGIN
|
|
1000
|
-
DECLARE rev INT;
|
|
1001
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1002
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1003
|
-
INSERT INTO ${hTtblName} SELECT 'update', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
998
|
+
expression: `DELIMITER $$
|
|
999
|
+
CREATE TRIGGER ${tblTriggerName}__update_trigger AFTER UPDATE ON ${tblName} FOR EACH ROW BEGIN
|
|
1000
|
+
DECLARE rev INT;
|
|
1001
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1002
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1003
|
+
INSERT INTO ${hTtblName} SELECT 'update', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
1004
1004
|
END;`,
|
|
1005
1005
|
},
|
|
1006
1006
|
{
|
|
1007
1007
|
bindings: [],
|
|
1008
|
-
expression: `DELIMITER $$
|
|
1009
|
-
CREATE TRIGGER ${tblTriggerName}__delete_trigger BEFORE DELETE ON ${tblName} FOR EACH ROW BEGIN
|
|
1010
|
-
DECLARE rev INT;
|
|
1011
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1012
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1013
|
-
INSERT INTO ${hTtblName} SELECT 'delete', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
1008
|
+
expression: `DELIMITER $$
|
|
1009
|
+
CREATE TRIGGER ${tblTriggerName}__delete_trigger BEFORE DELETE ON ${tblName} FOR EACH ROW BEGIN
|
|
1010
|
+
DECLARE rev INT;
|
|
1011
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1012
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1013
|
+
INSERT INTO ${hTtblName} SELECT 'delete', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
1014
1014
|
END;`,
|
|
1015
1015
|
},
|
|
1016
1016
|
];
|
package/lib/mjs/compilers.js
CHANGED
|
@@ -936,8 +936,8 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends Ta
|
|
|
936
936
|
...dropUnique,
|
|
937
937
|
{
|
|
938
938
|
bindings: [],
|
|
939
|
-
expression: `ALTER TABLE ${hTtblName}
|
|
940
|
-
CHANGE COLUMN ${pKey.Name} ${pKey.Name} INT NOT NULL ,
|
|
939
|
+
expression: `ALTER TABLE ${hTtblName}
|
|
940
|
+
CHANGE COLUMN ${pKey.Name} ${pKey.Name} INT NOT NULL ,
|
|
941
941
|
DROP PRIMARY KEY;`,
|
|
942
942
|
},
|
|
943
943
|
// remove primary key & add history columns
|
|
@@ -951,12 +951,12 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends Ta
|
|
|
951
951
|
},
|
|
952
952
|
{
|
|
953
953
|
bindings: [],
|
|
954
|
-
expression: `DELIMITER $$
|
|
955
|
-
CREATE TRIGGER ${hTriggerName}__insert_trigger BEFORE INSERT ON ${hTtblName} FOR EACH ROW
|
|
956
|
-
BEGIN
|
|
957
|
-
DECLARE rev INT;
|
|
958
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
959
|
-
SET NEW.__revision__ = rev + 1;
|
|
954
|
+
expression: `DELIMITER $$
|
|
955
|
+
CREATE TRIGGER ${hTriggerName}__insert_trigger BEFORE INSERT ON ${hTtblName} FOR EACH ROW
|
|
956
|
+
BEGIN
|
|
957
|
+
DECLARE rev INT;
|
|
958
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
959
|
+
SET NEW.__revision__ = rev + 1;
|
|
960
960
|
END;`,
|
|
961
961
|
},
|
|
962
962
|
// create tracking triggers
|
|
@@ -975,32 +975,32 @@ let SqlTableHistoryQueryCompiler = class SqlTableHistoryQueryCompiler extends Ta
|
|
|
975
975
|
// insert into history table & update __end__ date for all operations
|
|
976
976
|
{
|
|
977
977
|
bindings: [],
|
|
978
|
-
expression: `DELIMITER $$
|
|
979
|
-
CREATE TRIGGER ${tblTriggerName}__insert_trigger AFTER INSERT ON ${tblName} FOR EACH ROW BEGIN
|
|
980
|
-
DECLARE rev INT;
|
|
981
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
982
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
983
|
-
INSERT INTO ${hTtblName} SELECT 'insert', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
978
|
+
expression: `DELIMITER $$
|
|
979
|
+
CREATE TRIGGER ${tblTriggerName}__insert_trigger AFTER INSERT ON ${tblName} FOR EACH ROW BEGIN
|
|
980
|
+
DECLARE rev INT;
|
|
981
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
982
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
983
|
+
INSERT INTO ${hTtblName} SELECT 'insert', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
984
984
|
END;`,
|
|
985
985
|
},
|
|
986
986
|
{
|
|
987
987
|
bindings: [],
|
|
988
|
-
expression: `DELIMITER $$
|
|
989
|
-
CREATE TRIGGER ${tblTriggerName}__update_trigger AFTER UPDATE ON ${tblName} FOR EACH ROW BEGIN
|
|
990
|
-
DECLARE rev INT;
|
|
991
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
992
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
993
|
-
INSERT INTO ${hTtblName} SELECT 'update', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
988
|
+
expression: `DELIMITER $$
|
|
989
|
+
CREATE TRIGGER ${tblTriggerName}__update_trigger AFTER UPDATE ON ${tblName} FOR EACH ROW BEGIN
|
|
990
|
+
DECLARE rev INT;
|
|
991
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
992
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
993
|
+
INSERT INTO ${hTtblName} SELECT 'update', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
994
994
|
END;`,
|
|
995
995
|
},
|
|
996
996
|
{
|
|
997
997
|
bindings: [],
|
|
998
|
-
expression: `DELIMITER $$
|
|
999
|
-
CREATE TRIGGER ${tblTriggerName}__delete_trigger BEFORE DELETE ON ${tblName} FOR EACH ROW BEGIN
|
|
1000
|
-
DECLARE rev INT;
|
|
1001
|
-
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1002
|
-
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1003
|
-
INSERT INTO ${hTtblName} SELECT 'delete', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
998
|
+
expression: `DELIMITER $$
|
|
999
|
+
CREATE TRIGGER ${tblTriggerName}__delete_trigger BEFORE DELETE ON ${tblName} FOR EACH ROW BEGIN
|
|
1000
|
+
DECLARE rev INT;
|
|
1001
|
+
SET rev = (SELECT IFNULL(MAX(__revision__), 0) FROM ${hTtblName} WHERE Id = NEW.Id);
|
|
1002
|
+
UPDATE ${hTtblName} SET __end__ = NOW() WHERE Id = NEW.Id AND __revision__ = rev;
|
|
1003
|
+
INSERT INTO ${hTtblName} SELECT 'delete', 0, NOW(), NULL, d.* FROM ${tblName} AS d WHERE d.${pKey.Name} = NEW.${pKey.Name};
|
|
1004
1004
|
END;`,
|
|
1005
1005
|
},
|
|
1006
1006
|
];
|