velocious 1.0.567 → 1.0.569
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 +49 -1
- package/build/configuration.js +36 -0
- package/build/database/drivers/base-table.js +4 -3
- package/build/database/drivers/base.js +195 -54
- package/build/database/drivers/index-metadata.js +28 -0
- package/build/database/drivers/mssql/column.js +2 -34
- package/build/database/drivers/mssql/columns-index.js +37 -0
- package/build/database/drivers/mssql/index.js +10 -7
- package/build/database/drivers/mssql/table.js +55 -11
- package/build/database/drivers/mysql/index.js +10 -5
- package/build/database/drivers/mysql/sql/alter-table.js +13 -0
- package/build/database/drivers/pgsql/column.js +2 -27
- package/build/database/drivers/pgsql/columns-index.js +37 -0
- package/build/database/drivers/pgsql/index.js +4 -4
- package/build/database/drivers/pgsql/table.js +61 -10
- package/build/database/drivers/sqlite/base.js +2 -2
- package/build/database/drivers/sqlite/connection-sql-js.js +62 -2
- package/build/database/drivers/sqlite/index.web.js +74 -0
- package/build/database/drivers/sqlite/sql/alter-table.js +18 -0
- package/build/database/migration/index.js +92 -3
- package/build/database/operation-connection.js +110 -0
- package/build/database/operation-lease.js +47 -0
- package/build/database/operation.js +140 -0
- package/build/database/pool/base.js +26 -1
- package/build/database/pool/single-multi-use.js +49 -0
- package/build/database/query/alter-table-base.js +20 -1
- package/build/database/query/model-class-query.js +38 -7
- package/build/database/query/preloader/belongs-to.js +3 -2
- package/build/database/query/preloader/has-many.js +4 -3
- package/build/database/query/preloader/has-one.js +2 -1
- package/build/database/query/preloader/query-for-model.js +17 -0
- package/build/database/query/query-data.js +12 -3
- package/build/database/query/with-count.js +5 -3
- package/build/database/record/acts-as-list.js +11 -8
- package/build/database/record/attachments/normalize-input.js +38 -10
- package/build/database/record/attachments/storage-drivers/filesystem.js +33 -2
- package/build/database/record/attachments/storage-drivers/native.js +17 -2
- package/build/database/record/attachments/storage-drivers/s3.js +27 -7
- package/build/database/record/attachments/store.js +173 -53
- package/build/database/record/auditing.js +12 -9
- package/build/database/record/counter-cache-magnitude.js +5 -3
- package/build/database/record/index.js +95 -14
- package/build/database/record/instance-relationships/belongs-to.js +4 -2
- package/build/database/record/instance-relationships/has-many.js +7 -5
- package/build/database/record/instance-relationships/has-one.js +4 -2
- package/build/database/record/validators/uniqueness.js +3 -2
- package/build/database/table-data/table-foreign-key.js +9 -1
- package/build/environment-handlers/base.js +1 -1
- package/build/environment-handlers/node/attachment-path-source.js +144 -0
- package/build/environment-handlers/node.js +28 -3
- package/build/frontend-models/websocket-publishers.js +2 -2
- package/build/src/configuration.d.ts +12 -0
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +35 -1
- package/build/src/database/drivers/base-table.d.ts.map +1 -1
- package/build/src/database/drivers/base-table.js +4 -3
- package/build/src/database/drivers/base.d.ts +73 -20
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +181 -54
- package/build/src/database/drivers/index-metadata.d.ts +41 -0
- package/build/src/database/drivers/index-metadata.d.ts.map +1 -0
- package/build/src/database/drivers/index-metadata.js +26 -0
- package/build/src/database/drivers/mssql/column.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/column.js +3 -31
- package/build/src/database/drivers/mssql/columns-index.d.ts +41 -0
- package/build/src/database/drivers/mssql/columns-index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/columns-index.js +35 -1
- package/build/src/database/drivers/mssql/index.d.ts +4 -1
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +11 -8
- package/build/src/database/drivers/mssql/table.d.ts +42 -0
- package/build/src/database/drivers/mssql/table.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/table.js +49 -12
- package/build/src/database/drivers/mysql/index.d.ts +2 -1
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +10 -6
- package/build/src/database/drivers/mysql/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/alter-table.js +12 -1
- package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/column.js +3 -24
- package/build/src/database/drivers/pgsql/columns-index.d.ts +41 -0
- package/build/src/database/drivers/pgsql/columns-index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/columns-index.js +35 -1
- package/build/src/database/drivers/pgsql/index.d.ts +2 -1
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/index.js +5 -5
- package/build/src/database/drivers/pgsql/table.d.ts +42 -0
- package/build/src/database/drivers/pgsql/table.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/table.js +54 -11
- package/build/src/database/drivers/sqlite/base.d.ts +1 -1
- package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/base.js +3 -3
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts +20 -0
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/connection-sql-js.js +56 -3
- package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.web.js +64 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.js +15 -1
- package/build/src/database/migration/index.d.ts +35 -1
- package/build/src/database/migration/index.d.ts.map +1 -1
- package/build/src/database/migration/index.js +78 -4
- package/build/src/database/operation-connection.d.ts +61 -0
- package/build/src/database/operation-connection.d.ts.map +1 -0
- package/build/src/database/operation-connection.js +93 -0
- package/build/src/database/operation-lease.d.ts +27 -0
- package/build/src/database/operation-lease.d.ts.map +1 -0
- package/build/src/database/operation-lease.js +44 -0
- package/build/src/database/operation.d.ts +77 -0
- package/build/src/database/operation.d.ts.map +1 -0
- package/build/src/database/operation.js +123 -0
- package/build/src/database/pool/base.d.ts +14 -0
- package/build/src/database/pool/base.d.ts.map +1 -1
- package/build/src/database/pool/base.js +24 -2
- package/build/src/database/pool/single-multi-use.d.ts +1 -0
- package/build/src/database/pool/single-multi-use.d.ts.map +1 -1
- package/build/src/database/pool/single-multi-use.js +49 -1
- package/build/src/database/query/alter-table-base.d.ts +6 -0
- package/build/src/database/query/alter-table-base.d.ts.map +1 -1
- package/build/src/database/query/alter-table-base.js +18 -2
- package/build/src/database/query/model-class-query.d.ts +14 -0
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +32 -8
- package/build/src/database/query/preloader/belongs-to.d.ts.map +1 -1
- package/build/src/database/query/preloader/belongs-to.js +4 -3
- package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-many.js +5 -4
- package/build/src/database/query/preloader/has-one.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-one.js +3 -2
- package/build/src/database/query/preloader/query-for-model.d.ts +10 -0
- package/build/src/database/query/preloader/query-for-model.d.ts.map +1 -0
- package/build/src/database/query/preloader/query-for-model.js +16 -0
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +13 -4
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +6 -4
- package/build/src/database/record/acts-as-list.js +12 -9
- package/build/src/database/record/attachments/attachment-record.d.ts +9 -0
- package/build/src/database/record/attachments/attachment-record.d.ts.map +1 -1
- package/build/src/database/record/attachments/normalize-input.d.ts +33 -4
- package/build/src/database/record/attachments/normalize-input.d.ts.map +1 -1
- package/build/src/database/record/attachments/normalize-input.js +39 -11
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts +2 -5
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/filesystem.js +28 -3
- package/build/src/database/record/attachments/storage-drivers/native.d.ts +2 -6
- package/build/src/database/record/attachments/storage-drivers/native.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/native.js +14 -3
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts +2 -6
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/s3.js +29 -8
- package/build/src/database/record/attachments/store.d.ts +31 -2
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +158 -54
- package/build/src/database/record/auditing.d.ts.map +1 -1
- package/build/src/database/record/auditing.js +13 -10
- package/build/src/database/record/counter-cache-magnitude.js +6 -4
- package/build/src/database/record/index.d.ts +42 -2
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +87 -15
- package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/belongs-to.js +4 -3
- package/build/src/database/record/instance-relationships/has-many.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-many.js +7 -5
- package/build/src/database/record/instance-relationships/has-one.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-one.js +4 -3
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +4 -3
- package/build/src/database/table-data/table-foreign-key.d.ts +9 -1
- package/build/src/database/table-data/table-foreign-key.d.ts.map +1 -1
- package/build/src/database/table-data/table-foreign-key.js +9 -2
- package/build/src/environment-handlers/base.d.ts +2 -5
- package/build/src/environment-handlers/base.d.ts.map +1 -1
- package/build/src/environment-handlers/base.js +2 -2
- package/build/src/environment-handlers/node/attachment-path-source.d.ts +64 -0
- package/build/src/environment-handlers/node/attachment-path-source.d.ts.map +1 -0
- package/build/src/environment-handlers/node/attachment-path-source.js +116 -0
- package/build/src/environment-handlers/node.d.ts +12 -0
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +24 -4
- package/build/src/frontend-models/websocket-publishers.js +3 -3
- package/build/src/sync/server-sequence-allocator.d.ts +16 -4
- package/build/src/sync/server-sequence-allocator.d.ts.map +1 -1
- package/build/src/sync/server-sequence-allocator.js +37 -11
- package/build/src/sync/sync-client.d.ts.map +1 -1
- package/build/src/sync/sync-client.js +7 -3
- package/build/src/sync/sync-publisher.d.ts +2 -1
- package/build/src/sync/sync-publisher.d.ts.map +1 -1
- package/build/src/sync/sync-publisher.js +11 -6
- package/build/sync/server-sequence-allocator.js +43 -10
- package/build/sync/sync-client.js +6 -2
- package/build/sync/sync-publisher.js +10 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/configuration.js +36 -0
- package/src/database/drivers/base-table.js +4 -3
- package/src/database/drivers/base.js +195 -54
- package/src/database/drivers/index-metadata.js +28 -0
- package/src/database/drivers/mssql/column.js +2 -34
- package/src/database/drivers/mssql/columns-index.js +37 -0
- package/src/database/drivers/mssql/index.js +10 -7
- package/src/database/drivers/mssql/table.js +55 -11
- package/src/database/drivers/mysql/index.js +10 -5
- package/src/database/drivers/mysql/sql/alter-table.js +13 -0
- package/src/database/drivers/pgsql/column.js +2 -27
- package/src/database/drivers/pgsql/columns-index.js +37 -0
- package/src/database/drivers/pgsql/index.js +4 -4
- package/src/database/drivers/pgsql/table.js +61 -10
- package/src/database/drivers/sqlite/base.js +2 -2
- package/src/database/drivers/sqlite/connection-sql-js.js +62 -2
- package/src/database/drivers/sqlite/index.web.js +74 -0
- package/src/database/drivers/sqlite/sql/alter-table.js +18 -0
- package/src/database/migration/index.js +92 -3
- package/src/database/operation-connection.js +110 -0
- package/src/database/operation-lease.js +47 -0
- package/src/database/operation.js +140 -0
- package/src/database/pool/base.js +26 -1
- package/src/database/pool/single-multi-use.js +49 -0
- package/src/database/query/alter-table-base.js +20 -1
- package/src/database/query/model-class-query.js +38 -7
- package/src/database/query/preloader/belongs-to.js +3 -2
- package/src/database/query/preloader/has-many.js +4 -3
- package/src/database/query/preloader/has-one.js +2 -1
- package/src/database/query/preloader/query-for-model.js +17 -0
- package/src/database/query/query-data.js +12 -3
- package/src/database/query/with-count.js +5 -3
- package/src/database/record/acts-as-list.js +11 -8
- package/src/database/record/attachments/normalize-input.js +38 -10
- package/src/database/record/attachments/storage-drivers/filesystem.js +33 -2
- package/src/database/record/attachments/storage-drivers/native.js +17 -2
- package/src/database/record/attachments/storage-drivers/s3.js +27 -7
- package/src/database/record/attachments/store.js +173 -53
- package/src/database/record/auditing.js +12 -9
- package/src/database/record/counter-cache-magnitude.js +5 -3
- package/src/database/record/index.js +95 -14
- package/src/database/record/instance-relationships/belongs-to.js +4 -2
- package/src/database/record/instance-relationships/has-many.js +7 -5
- package/src/database/record/instance-relationships/has-one.js +4 -2
- package/src/database/record/validators/uniqueness.js +3 -2
- package/src/database/table-data/table-foreign-key.js +9 -1
- package/src/environment-handlers/base.js +1 -1
- package/src/environment-handlers/node/attachment-path-source.js +144 -0
- package/src/environment-handlers/node.js +28 -3
- package/src/frontend-models/websocket-publishers.js +2 -2
- package/src/sync/server-sequence-allocator.js +43 -10
- package/src/sync/sync-client.js +6 -2
- package/src/sync/sync-publisher.js +10 -5
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { forcedBoolean, forcedString } from "typanic"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* IndexMetadataType type.
|
|
7
|
+
* @typedef {object} IndexMetadataType
|
|
8
|
+
* @property {string} column_name - Index column name.
|
|
9
|
+
* @property {string} index_name - Index name.
|
|
10
|
+
* @property {boolean} is_primary_key - Whether the index is primary.
|
|
11
|
+
* @property {boolean} is_unique - Whether the index is unique.
|
|
12
|
+
* @property {string} table_name - Table name.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Normalizes one untrusted database index metadata row.
|
|
17
|
+
* @param {import("./base.js").QueryRowType} row - Database index metadata row.
|
|
18
|
+
* @returns {IndexMetadataType} - Validated index metadata.
|
|
19
|
+
*/
|
|
20
|
+
export function normalizeIndexMetadataRow(row) {
|
|
21
|
+
return {
|
|
22
|
+
column_name: forcedString(row.column_name, "index column_name"),
|
|
23
|
+
index_name: forcedString(row.index_name, "index index_name"),
|
|
24
|
+
is_primary_key: forcedBoolean(row.is_primary_key, "index is_primary_key"),
|
|
25
|
+
is_unique: forcedBoolean(row.is_unique, "index is_unique"),
|
|
26
|
+
table_name: forcedString(row.table_name, "index table_name")
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import BaseColumn from "../base-column.js"
|
|
4
|
-
import ColumnsIndex from "./columns-index.js"
|
|
5
4
|
import {digg} from "diggerize"
|
|
6
5
|
|
|
7
6
|
export default class VelociousDatabaseDriversMssqlColumn extends BaseColumn {
|
|
@@ -19,39 +18,9 @@ export default class VelociousDatabaseDriversMssqlColumn extends BaseColumn {
|
|
|
19
18
|
getAutoIncrement() { return digg(this, "data", "isIdentity") === 1 }
|
|
20
19
|
|
|
21
20
|
async getIndexes() {
|
|
22
|
-
const
|
|
23
|
-
const sql = `
|
|
24
|
-
SELECT
|
|
25
|
-
sys.tables.name AS TableName,
|
|
26
|
-
sys.columns.name AS ColumnName,
|
|
27
|
-
sys.indexes.name AS index_name,
|
|
28
|
-
sys.indexes.type_desc AS IndexType,
|
|
29
|
-
sys.index_columns.is_included_column AS IsIncludedColumn,
|
|
30
|
-
sys.indexes.is_unique,
|
|
31
|
-
sys.indexes.is_primary_key,
|
|
32
|
-
sys.indexes.is_unique_constraint
|
|
33
|
-
FROM sys.indexes
|
|
34
|
-
INNER JOIN sys.index_columns ON sys.indexes.object_id = sys.index_columns.object_id AND sys.indexes.index_id = sys.index_columns.index_id
|
|
35
|
-
INNER JOIN sys.columns ON sys.index_columns.object_id = sys.columns.object_id AND sys.index_columns.column_id = sys.columns.column_id
|
|
36
|
-
INNER JOIN sys.tables ON sys.indexes.object_id = sys.tables.object_id
|
|
37
|
-
WHERE
|
|
38
|
-
sys.tables.name = ${options.quote(this.getTable().getName())} AND
|
|
39
|
-
sys.columns.name = ${options.quote(this.getName())}
|
|
40
|
-
ORDER BY
|
|
41
|
-
sys.indexes.name,
|
|
42
|
-
sys.index_columns.key_ordinal
|
|
43
|
-
`
|
|
21
|
+
const indexes = await this.getTable().getIndexes()
|
|
44
22
|
|
|
45
|
-
|
|
46
|
-
const indexes = []
|
|
47
|
-
|
|
48
|
-
for (const row of rows) {
|
|
49
|
-
const index = new ColumnsIndex(this.getTable(), row)
|
|
50
|
-
|
|
51
|
-
indexes.push(index)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return indexes
|
|
23
|
+
return indexes.filter((index) => index.getColumnNames().includes(this.getName()))
|
|
55
24
|
}
|
|
56
25
|
|
|
57
26
|
getDefault() { return digg(this, "data", "COLUMN_DEFAULT") }
|
|
@@ -71,4 +40,3 @@ export default class VelociousDatabaseDriversMssqlColumn extends BaseColumn {
|
|
|
71
40
|
getPrimaryKey() { return digg(this, "data", "isIdentity") === 1 }
|
|
72
41
|
getType() { return digg(this, "data", "DATA_TYPE") }
|
|
73
42
|
}
|
|
74
|
-
|
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import BaseColumnsIndex from "../base-columns-index.js"
|
|
4
|
+
import TableIndex from "../../table-data/table-index.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MssqlColumnsIndexDataType type.
|
|
8
|
+
* @typedef {object} MssqlColumnsIndexDataType
|
|
9
|
+
* @property {string[]} columnNames - Ordered index column names.
|
|
10
|
+
* @property {string} index_name - Index name.
|
|
11
|
+
* @property {boolean} is_primary_key - Whether the index is primary.
|
|
12
|
+
* @property {boolean} is_unique - Whether the index is unique.
|
|
13
|
+
* @property {string} table_name - Table name.
|
|
14
|
+
*/
|
|
4
15
|
|
|
5
16
|
export default class VelociousDatabaseDriversMssqlColumnsIndex extends BaseColumnsIndex {
|
|
17
|
+
/**
|
|
18
|
+
* Runs constructor.
|
|
19
|
+
* @param {import("../base-table.js").default} table - Table.
|
|
20
|
+
* @param {MssqlColumnsIndexDataType} data - Grouped index metadata.
|
|
21
|
+
*/
|
|
22
|
+
constructor(table, data) {
|
|
23
|
+
super(table, data)
|
|
24
|
+
this.indexData = data
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Runs get column names.
|
|
29
|
+
* @returns {string[]} - Ordered index column names.
|
|
30
|
+
*/
|
|
31
|
+
getColumnNames() { return this.indexData.columnNames }
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Runs get table data index.
|
|
35
|
+
* @returns {TableIndex} - Table-data index.
|
|
36
|
+
*/
|
|
37
|
+
getTableDataIndex() {
|
|
38
|
+
return new TableIndex(this.getColumnNames(), {
|
|
39
|
+
name: this.getName(),
|
|
40
|
+
unique: this.isUnique()
|
|
41
|
+
})
|
|
42
|
+
}
|
|
6
43
|
}
|
|
@@ -463,8 +463,8 @@ export default class VelociousDatabaseDriversMssql extends Base{
|
|
|
463
463
|
})
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
-
async lastInsertID() {
|
|
467
|
-
const result = await this.query("SELECT SCOPE_IDENTITY() AS last_insert_id")
|
|
466
|
+
async lastInsertID(options = {}) {
|
|
467
|
+
const result = await this.query("SELECT SCOPE_IDENTITY() AS last_insert_id", options)
|
|
468
468
|
const lastInsertID = digg(result, 0, "last_insert_id")
|
|
469
469
|
|
|
470
470
|
if (lastInsertID === null) throw new Error("Couldn't get the last inserted ID")
|
|
@@ -534,29 +534,32 @@ export default class VelociousDatabaseDriversMssql extends Base{
|
|
|
534
534
|
/**
|
|
535
535
|
* Runs start save point action.
|
|
536
536
|
* @param {string} savePointName - Save point name.
|
|
537
|
+
* @param {Pick<import("../base.js").QueryOptions, "operationOwner">} [options] - Transaction ownership.
|
|
537
538
|
* @returns {Promise<void>} - Resolves when complete.
|
|
538
539
|
*/
|
|
539
|
-
async _startSavePointAction(savePointName) {
|
|
540
|
-
await this.query(`SAVE TRANSACTION [${savePointName}]
|
|
540
|
+
async _startSavePointAction(savePointName, options = {}) {
|
|
541
|
+
await this.query(`SAVE TRANSACTION [${savePointName}]`, options)
|
|
541
542
|
}
|
|
542
543
|
|
|
543
544
|
/**
|
|
544
545
|
* Runs release save point action.
|
|
545
546
|
* @param {string} savePointName - Save point name.
|
|
547
|
+
* @param {Pick<import("../base.js").QueryOptions, "operationOwner">} [_options] - Transaction ownership.
|
|
546
548
|
* @returns {Promise<void>} - Resolves when complete.
|
|
547
549
|
*/
|
|
548
|
-
async _releaseSavePointAction(savePointName
|
|
550
|
+
async _releaseSavePointAction(savePointName, _options = {}) {
|
|
549
551
|
// Do nothing in MS-SQL.
|
|
550
552
|
}
|
|
551
553
|
|
|
552
554
|
/**
|
|
553
555
|
* Runs rollback save point action.
|
|
554
556
|
* @param {string} savePointName - Save point name.
|
|
557
|
+
* @param {Pick<import("../base.js").QueryOptions, "operationOwner">} [options] - Transaction ownership.
|
|
555
558
|
* @returns {Promise<void>} - Resolves when complete.
|
|
556
559
|
*/
|
|
557
|
-
async _rollbackSavePointAction(savePointName) {
|
|
560
|
+
async _rollbackSavePointAction(savePointName, options = {}) {
|
|
558
561
|
try {
|
|
559
|
-
await this.query(`ROLLBACK TRANSACTION [${savePointName}]
|
|
562
|
+
await this.query(`ROLLBACK TRANSACTION [${savePointName}]`, options)
|
|
560
563
|
} catch (error) {
|
|
561
564
|
const message = error instanceof Error ? error.message : `${error}`
|
|
562
565
|
|
|
@@ -5,6 +5,51 @@ import Column from "./column.js"
|
|
|
5
5
|
import ColumnsIndex from "./columns-index.js"
|
|
6
6
|
import {digg} from "diggerize"
|
|
7
7
|
import ForeignKey from "./foreign-key.js"
|
|
8
|
+
import { normalizeIndexMetadataRow } from "../index-metadata.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* MssqlGroupedIndexDataType type.
|
|
12
|
+
* @typedef {object} MssqlGroupedIndexDataType
|
|
13
|
+
* @property {string[]} columnNames - Ordered index column names.
|
|
14
|
+
* @property {string} index_name - Index name.
|
|
15
|
+
* @property {boolean} is_primary_key - Whether the index is primary.
|
|
16
|
+
* @property {boolean} is_unique - Whether the index is unique.
|
|
17
|
+
* @property {string} table_name - Table name.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Groups ordered SQL Server index rows into one metadata value per index.
|
|
22
|
+
* @param {import("../index-metadata.js").IndexMetadataType[]} indexRows - Ordered index metadata rows.
|
|
23
|
+
* @returns {MssqlGroupedIndexDataType[]} - Grouped index metadata.
|
|
24
|
+
*/
|
|
25
|
+
export function groupMssqlIndexRows(indexRows) {
|
|
26
|
+
/** @type {Map<string, MssqlGroupedIndexDataType>} */
|
|
27
|
+
const indexDataByName = new Map()
|
|
28
|
+
/** @type {MssqlGroupedIndexDataType[]} */
|
|
29
|
+
const groupedIndexData = []
|
|
30
|
+
|
|
31
|
+
for (const indexRow of indexRows) {
|
|
32
|
+
const existingIndexData = indexDataByName.get(indexRow.index_name)
|
|
33
|
+
|
|
34
|
+
if (existingIndexData) {
|
|
35
|
+
existingIndexData.columnNames.push(indexRow.column_name)
|
|
36
|
+
continue
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const indexData = {
|
|
40
|
+
columnNames: [indexRow.column_name],
|
|
41
|
+
index_name: indexRow.index_name,
|
|
42
|
+
is_primary_key: indexRow.is_primary_key,
|
|
43
|
+
is_unique: indexRow.is_unique,
|
|
44
|
+
table_name: indexRow.table_name
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
indexDataByName.set(indexRow.index_name, indexData)
|
|
48
|
+
groupedIndexData.push(indexData)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return groupedIndexData
|
|
52
|
+
}
|
|
8
53
|
|
|
9
54
|
export default class VelociousDatabaseDriversMssqlTable extends BaseTable {
|
|
10
55
|
/**
|
|
@@ -43,7 +88,7 @@ export default class VelociousDatabaseDriversMssqlTable extends BaseTable {
|
|
|
43
88
|
return await this.getDriver()._cachedTableSchemaMetadata(this.getName(), "foreignKeys", async () => {
|
|
44
89
|
const sql = `
|
|
45
90
|
SELECT
|
|
46
|
-
fk.name AS
|
|
91
|
+
fk.name AS CONSTRAINT_NAME,
|
|
47
92
|
tp.name AS ParentTable,
|
|
48
93
|
ref.name AS ReferencedTable,
|
|
49
94
|
cp.name AS ParentColumn,
|
|
@@ -63,7 +108,7 @@ export default class VelociousDatabaseDriversMssqlTable extends BaseTable {
|
|
|
63
108
|
ON fkc.referenced_object_id = cref.object_id
|
|
64
109
|
AND fkc.referenced_column_id = cref.column_id
|
|
65
110
|
WHERE tp.name = ${this.driver.quote(this.getName())}
|
|
66
|
-
ORDER BY
|
|
111
|
+
ORDER BY CONSTRAINT_NAME, ParentTable, ReferencedTable;
|
|
67
112
|
`
|
|
68
113
|
|
|
69
114
|
const foreignKeyRows = await this.driver.query(sql)
|
|
@@ -84,20 +129,18 @@ export default class VelociousDatabaseDriversMssqlTable extends BaseTable {
|
|
|
84
129
|
const options = this.getOptions()
|
|
85
130
|
const sql = `
|
|
86
131
|
SELECT
|
|
87
|
-
sys.tables.name AS
|
|
88
|
-
sys.columns.name AS
|
|
132
|
+
sys.tables.name AS table_name,
|
|
133
|
+
sys.columns.name AS column_name,
|
|
89
134
|
sys.indexes.name AS index_name,
|
|
90
|
-
sys.indexes.type_desc AS IndexType,
|
|
91
|
-
sys.index_columns.is_included_column AS IsIncludedColumn,
|
|
92
135
|
sys.indexes.is_unique,
|
|
93
|
-
sys.indexes.is_primary_key
|
|
94
|
-
sys.indexes.is_unique_constraint
|
|
136
|
+
sys.indexes.is_primary_key
|
|
95
137
|
FROM sys.indexes
|
|
96
138
|
INNER JOIN sys.index_columns ON sys.indexes.object_id = sys.index_columns.object_id AND sys.indexes.index_id = sys.index_columns.index_id
|
|
97
139
|
INNER JOIN sys.columns ON sys.index_columns.object_id = sys.columns.object_id AND sys.index_columns.column_id = sys.columns.column_id
|
|
98
140
|
INNER JOIN sys.tables ON sys.indexes.object_id = sys.tables.object_id
|
|
99
141
|
WHERE
|
|
100
|
-
sys.tables.name = ${options.quote(this.getName())}
|
|
142
|
+
sys.tables.name = ${options.quote(this.getName())} AND
|
|
143
|
+
sys.index_columns.is_included_column = 0
|
|
101
144
|
ORDER BY
|
|
102
145
|
sys.indexes.name,
|
|
103
146
|
sys.index_columns.key_ordinal
|
|
@@ -105,9 +148,10 @@ export default class VelociousDatabaseDriversMssqlTable extends BaseTable {
|
|
|
105
148
|
|
|
106
149
|
const rows = await this.getDriver().query(sql)
|
|
107
150
|
const indexes = []
|
|
151
|
+
const indexRows = rows.map((row) => normalizeIndexMetadataRow(row))
|
|
108
152
|
|
|
109
|
-
for (const
|
|
110
|
-
const index = new ColumnsIndex(this,
|
|
153
|
+
for (const indexData of groupMssqlIndexRows(indexRows)) {
|
|
154
|
+
const index = new ColumnsIndex(this, indexData)
|
|
111
155
|
|
|
112
156
|
indexes.push(index)
|
|
113
157
|
}
|
|
@@ -403,9 +403,12 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
403
403
|
* large result set is read incrementally instead of being buffered. Overrides the base
|
|
404
404
|
* buffered fallback with true server-side streaming.
|
|
405
405
|
* @param {string} sql - SQL string to stream.
|
|
406
|
+
* @param {import("../base.js").QueryOptions} [options] - Query ownership options.
|
|
406
407
|
* @yields {Record<string, unknown>} - The result rows, one at a time.
|
|
407
408
|
*/
|
|
408
|
-
async *queryStream(sql) {
|
|
409
|
+
async *queryStream(sql, options = {}) {
|
|
410
|
+
await this._waitForOperationLease(options.operationOwner)
|
|
411
|
+
|
|
409
412
|
if (!this.pool) await this.connect()
|
|
410
413
|
if (!this.pool) throw new Error("MySQL pool failed to initialize")
|
|
411
414
|
|
|
@@ -554,10 +557,11 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
554
557
|
|
|
555
558
|
/**
|
|
556
559
|
* Runs last insert id.
|
|
560
|
+
* @param {import("../base.js").QueryOptions} [options] - Query ownership options.
|
|
557
561
|
* @returns {Promise<number>} - Resolves with the last insert id.
|
|
558
562
|
*/
|
|
559
|
-
async lastInsertID() {
|
|
560
|
-
const result = await this.query("SELECT LAST_INSERT_ID() AS last_insert_id")
|
|
563
|
+
async lastInsertID(options = {}) {
|
|
564
|
+
const result = await this.query("SELECT LAST_INSERT_ID() AS last_insert_id", options)
|
|
561
565
|
|
|
562
566
|
return digg(result, 0, "last_insert_id")
|
|
563
567
|
}
|
|
@@ -574,10 +578,11 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
574
578
|
|
|
575
579
|
/**
|
|
576
580
|
* Runs start transaction action.
|
|
581
|
+
* @param {Pick<import("../base.js").QueryOptions, "operationOwner">} [options] - Transaction ownership.
|
|
577
582
|
* @returns {Promise<void>} - Resolves when complete.
|
|
578
583
|
*/
|
|
579
|
-
async _startTransactionAction() {
|
|
580
|
-
await this.query("START TRANSACTION")
|
|
584
|
+
async _startTransactionAction(options = {}) {
|
|
585
|
+
await this.query("START TRANSACTION", options)
|
|
581
586
|
}
|
|
582
587
|
|
|
583
588
|
/**
|
|
@@ -4,6 +4,19 @@ import AlterTableBase from "../../../query/alter-table-base.js"
|
|
|
4
4
|
import TableColumn from "../../../table-data/table-column.js"
|
|
5
5
|
|
|
6
6
|
export default class VelociousDatabaseConnectionDriversMysqlSqlAlterTable extends AlterTableBase {
|
|
7
|
+
/**
|
|
8
|
+
* Runs get drop foreign key sql.
|
|
9
|
+
* @param {import("../../../table-data/table-foreign-key.js").default} foreignKey - Foreign key to drop.
|
|
10
|
+
* @returns {string} - SQL fragment that removes the foreign key.
|
|
11
|
+
*/
|
|
12
|
+
getDropForeignKeySQL(foreignKey) {
|
|
13
|
+
const name = foreignKey.getName()
|
|
14
|
+
|
|
15
|
+
if (!name) throw new Error(`Cannot remove unnamed foreign key on ${foreignKey.getTableName()}.${foreignKey.getColumnName()}`)
|
|
16
|
+
|
|
17
|
+
return `DROP FOREIGN KEY ${this.getOptions().quoteIndexName(name)}`
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
/**
|
|
8
21
|
* Builds MySQL ALTER TABLE statements, adding indexes atomically with columns.
|
|
9
22
|
* @returns {Promise<string[]>} - Resolves with SQL statements.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import BaseColumn from "../base-column.js"
|
|
4
|
-
import ColumnsIndex from "./columns-index.js"
|
|
5
4
|
import {digg} from "diggerize"
|
|
6
5
|
|
|
7
6
|
export default class VelociousDatabaseDriversPgsqlColumn extends BaseColumn {
|
|
@@ -25,33 +24,9 @@ export default class VelociousDatabaseDriversPgsqlColumn extends BaseColumn {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
async getIndexes() {
|
|
28
|
-
const
|
|
27
|
+
const indexes = await this.getTable().getIndexes()
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
SELECT
|
|
32
|
-
pg_attribute.attname AS column_name,
|
|
33
|
-
pg_index.indexrelid::regclass as index_name,
|
|
34
|
-
pg_class.relnamespace::regnamespace as schema_name,
|
|
35
|
-
pg_class.relname as table_name,
|
|
36
|
-
pg_index.indisprimary as is_primary_key,
|
|
37
|
-
pg_index.indisunique as is_unique
|
|
38
|
-
FROM pg_index
|
|
39
|
-
JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
|
40
|
-
JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY(pg_index.indkey)
|
|
41
|
-
WHERE
|
|
42
|
-
pg_attribute.attname = ${options.quote(this.getName())} AND
|
|
43
|
-
pg_class.relname = ${options.quote(this.getTable().getName())}
|
|
44
|
-
`)
|
|
45
|
-
|
|
46
|
-
const indexes = []
|
|
47
|
-
|
|
48
|
-
for (const indexRow of indexesRows) {
|
|
49
|
-
const columnsIndex = new ColumnsIndex(this.getTable(), indexRow)
|
|
50
|
-
|
|
51
|
-
indexes.push(columnsIndex)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return indexes
|
|
29
|
+
return indexes.filter((index) => index.getColumnNames().includes(this.getName()))
|
|
55
30
|
}
|
|
56
31
|
|
|
57
32
|
getDefault() {
|
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import BaseColumnsIndex from "../base-columns-index.js"
|
|
4
|
+
import TableIndex from "../../table-data/table-index.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PgsqlColumnsIndexDataType type.
|
|
8
|
+
* @typedef {object} PgsqlColumnsIndexDataType
|
|
9
|
+
* @property {string[]} columnNames - Ordered index column names.
|
|
10
|
+
* @property {string} index_name - Index name.
|
|
11
|
+
* @property {boolean} is_primary_key - Whether the index is primary.
|
|
12
|
+
* @property {boolean} is_unique - Whether the index is unique.
|
|
13
|
+
* @property {string} table_name - Table name.
|
|
14
|
+
*/
|
|
4
15
|
|
|
5
16
|
export default class VelociousDatabaseDriversPgsqlColumn extends BaseColumnsIndex {
|
|
17
|
+
/**
|
|
18
|
+
* Runs constructor.
|
|
19
|
+
* @param {import("../base-table.js").default} table - Table.
|
|
20
|
+
* @param {PgsqlColumnsIndexDataType} data - Grouped index metadata.
|
|
21
|
+
*/
|
|
22
|
+
constructor(table, data) {
|
|
23
|
+
super(table, data)
|
|
24
|
+
this.indexData = data
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Runs get column names.
|
|
29
|
+
* @returns {string[]} - Ordered index column names.
|
|
30
|
+
*/
|
|
31
|
+
getColumnNames() { return this.indexData.columnNames }
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Runs get table data index.
|
|
35
|
+
* @returns {TableIndex} - Table-data index.
|
|
36
|
+
*/
|
|
37
|
+
getTableDataIndex() {
|
|
38
|
+
return new TableIndex(this.getColumnNames(), {
|
|
39
|
+
name: this.getName(),
|
|
40
|
+
unique: this.isUnique()
|
|
41
|
+
})
|
|
42
|
+
}
|
|
6
43
|
}
|
|
@@ -326,8 +326,8 @@ export default class VelociousDatabaseDriversPgsql extends Base{
|
|
|
326
326
|
})
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
async lastInsertID() {
|
|
330
|
-
const result = await this.query("SELECT LASTVAL() AS last_insert_id")
|
|
329
|
+
async lastInsertID(options = {}) {
|
|
330
|
+
const result = await this.query("SELECT LASTVAL() AS last_insert_id", options)
|
|
331
331
|
|
|
332
332
|
return digg(result, 0, "last_insert_id")
|
|
333
333
|
}
|
|
@@ -338,8 +338,8 @@ export default class VelociousDatabaseDriversPgsql extends Base{
|
|
|
338
338
|
return this._options
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
async _startTransactionAction() {
|
|
342
|
-
await this.query("START TRANSACTION")
|
|
341
|
+
async _startTransactionAction(options = {}) {
|
|
342
|
+
await this.query("START TRANSACTION", options)
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
/**
|
|
@@ -4,6 +4,51 @@ import BaseTable from "../base-table.js"
|
|
|
4
4
|
import Column from "./column.js"
|
|
5
5
|
import ColumnsIndex from "./columns-index.js"
|
|
6
6
|
import ForeignKey from "./foreign-key.js"
|
|
7
|
+
import { normalizeIndexMetadataRow } from "../index-metadata.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* PgsqlGroupedIndexDataType type.
|
|
11
|
+
* @typedef {object} PgsqlGroupedIndexDataType
|
|
12
|
+
* @property {string[]} columnNames - Ordered index column names.
|
|
13
|
+
* @property {string} index_name - Index name.
|
|
14
|
+
* @property {boolean} is_primary_key - Whether the index is primary.
|
|
15
|
+
* @property {boolean} is_unique - Whether the index is unique.
|
|
16
|
+
* @property {string} table_name - Table name.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Groups ordered PostgreSQL index rows into one metadata value per index.
|
|
21
|
+
* @param {import("../index-metadata.js").IndexMetadataType[]} indexRows - Ordered index metadata rows.
|
|
22
|
+
* @returns {PgsqlGroupedIndexDataType[]} - Grouped index metadata.
|
|
23
|
+
*/
|
|
24
|
+
export function groupPgsqlIndexRows(indexRows) {
|
|
25
|
+
/** @type {Map<string, PgsqlGroupedIndexDataType>} */
|
|
26
|
+
const indexDataByName = new Map()
|
|
27
|
+
/** @type {PgsqlGroupedIndexDataType[]} */
|
|
28
|
+
const groupedIndexData = []
|
|
29
|
+
|
|
30
|
+
for (const indexRow of indexRows) {
|
|
31
|
+
const existingIndexData = indexDataByName.get(indexRow.index_name)
|
|
32
|
+
|
|
33
|
+
if (existingIndexData) {
|
|
34
|
+
existingIndexData.columnNames.push(indexRow.column_name)
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const indexData = {
|
|
39
|
+
columnNames: [indexRow.column_name],
|
|
40
|
+
index_name: indexRow.index_name,
|
|
41
|
+
is_primary_key: indexRow.is_primary_key,
|
|
42
|
+
is_unique: indexRow.is_unique,
|
|
43
|
+
table_name: indexRow.table_name
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
indexDataByName.set(indexRow.index_name, indexData)
|
|
47
|
+
groupedIndexData.push(indexData)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return groupedIndexData
|
|
51
|
+
}
|
|
7
52
|
|
|
8
53
|
export default class VelociousDatabaseDriversPgsqlTable extends BaseTable {
|
|
9
54
|
/**
|
|
@@ -100,23 +145,29 @@ export default class VelociousDatabaseDriversPgsqlTable extends BaseTable {
|
|
|
100
145
|
|
|
101
146
|
const indexesRows = await this.getDriver().query(`
|
|
102
147
|
SELECT
|
|
103
|
-
|
|
104
|
-
pg_index.indexrelid::regclass
|
|
105
|
-
pg_class.
|
|
106
|
-
|
|
107
|
-
pg_index.
|
|
108
|
-
pg_index.indisunique as is_unique
|
|
148
|
+
index_attribute.attname AS column_name,
|
|
149
|
+
pg_index.indexrelid::regclass AS index_name,
|
|
150
|
+
pg_class.relname AS table_name,
|
|
151
|
+
pg_index.indisprimary AS is_primary_key,
|
|
152
|
+
pg_index.indisunique AS is_unique
|
|
109
153
|
FROM pg_index
|
|
110
154
|
JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
|
111
|
-
JOIN
|
|
155
|
+
JOIN LATERAL unnest(pg_index.indkey) WITH ORDINALITY AS index_columns(attribute_number, ordinal_position) ON true
|
|
156
|
+
JOIN pg_attribute AS index_attribute ON index_attribute.attrelid = pg_class.oid AND index_attribute.attnum = index_columns.attribute_number
|
|
112
157
|
WHERE
|
|
113
|
-
pg_class.relname = ${options.quote(this.getName())}
|
|
158
|
+
pg_class.relname = ${options.quote(this.getName())} AND
|
|
159
|
+
index_columns.ordinal_position <= pg_index.indnkeyatts
|
|
160
|
+
ORDER BY
|
|
161
|
+
pg_index.indexrelid,
|
|
162
|
+
index_columns.ordinal_position
|
|
114
163
|
`)
|
|
115
164
|
|
|
116
165
|
const indexes = []
|
|
117
166
|
|
|
118
|
-
|
|
119
|
-
|
|
167
|
+
const indexRows = indexesRows.map((indexRow) => normalizeIndexMetadataRow(indexRow))
|
|
168
|
+
|
|
169
|
+
for (const indexData of groupPgsqlIndexRows(indexRows)) {
|
|
170
|
+
const columnsIndex = new ColumnsIndex(this, indexData)
|
|
120
171
|
|
|
121
172
|
indexes.push(columnsIndex)
|
|
122
173
|
}
|
|
@@ -262,8 +262,8 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
262
262
|
})
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
async lastInsertID() {
|
|
266
|
-
const result = await this.query("SELECT LAST_INSERT_ROWID() AS last_insert_id")
|
|
265
|
+
async lastInsertID(options = {}) {
|
|
266
|
+
const result = await this.query("SELECT LAST_INSERT_ROWID() AS last_insert_id", options)
|
|
267
267
|
|
|
268
268
|
return digg(result, 0, "last_insert_id")
|
|
269
269
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import debounce from "debounce"
|
|
4
|
+
import Mutex from "epic-locks/build/mutex.js"
|
|
4
5
|
import queryWeb from "./query.web.js"
|
|
5
6
|
|
|
6
7
|
export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
|
|
@@ -12,6 +13,9 @@ export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
|
|
|
12
13
|
*/
|
|
13
14
|
constructor(driver, connection, persistence) {
|
|
14
15
|
this.connection = connection
|
|
16
|
+
this.databaseSaveDeferred = false
|
|
17
|
+
this.databaseSaveMutex = new Mutex()
|
|
18
|
+
this.databaseTransactionStarting = false
|
|
15
19
|
this.driver = driver
|
|
16
20
|
this.persistence = persistence
|
|
17
21
|
}
|
|
@@ -30,6 +34,54 @@ export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
|
|
|
30
34
|
await this.saveDatabase()
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Flushes only when a mutation save is pending or was deferred by a transaction.
|
|
39
|
+
* @returns {Promise<void>} - Resolves when pending database bytes are stored.
|
|
40
|
+
*/
|
|
41
|
+
async flushPendingDatabaseSave() {
|
|
42
|
+
if (!this.saveDatabaseDebounce.isPending && !this.databaseSaveDeferred) return
|
|
43
|
+
|
|
44
|
+
await this.flushDatabaseSave()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Drains active and queued persistence before atomically starting an outer transaction.
|
|
49
|
+
* @param {() => Promise<void>} callback - Starts the SQL transaction.
|
|
50
|
+
* @returns {Promise<void>} - Resolves after BEGIN succeeds.
|
|
51
|
+
*/
|
|
52
|
+
async withTransactionStart(callback) {
|
|
53
|
+
if (this.saveDatabaseDebounce.isPending) {
|
|
54
|
+
this.saveDatabaseDebounce.clear()
|
|
55
|
+
this.databaseSaveDeferred = true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await this.databaseSaveMutex.sync(async () => {
|
|
59
|
+
if (this.databaseSaveDeferred) {
|
|
60
|
+
this.databaseSaveDeferred = false
|
|
61
|
+
const databaseContent = this.connection.export()
|
|
62
|
+
|
|
63
|
+
await this.persistence.save(databaseContent)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.databaseTransactionStarting = true
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
await callback()
|
|
70
|
+
} catch (error) {
|
|
71
|
+
this.databaseTransactionStarting = false
|
|
72
|
+
throw error
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Marks successful outer transaction admission complete after driver state is updated.
|
|
79
|
+
* @returns {void}
|
|
80
|
+
*/
|
|
81
|
+
completeTransactionStart() {
|
|
82
|
+
this.databaseTransactionStarting = false
|
|
83
|
+
}
|
|
84
|
+
|
|
33
85
|
/**
|
|
34
86
|
* Runs query.
|
|
35
87
|
* @param {string} sql - SQL string.
|
|
@@ -59,9 +111,17 @@ export default class VelociousDatabaseDriversSqliteConnectionSqlJs {
|
|
|
59
111
|
}
|
|
60
112
|
|
|
61
113
|
saveDatabase = async () => {
|
|
62
|
-
|
|
114
|
+
await this.databaseSaveMutex.sync(async () => {
|
|
115
|
+
if (this.driver.insideTransaction() || this.databaseTransactionStarting) {
|
|
116
|
+
this.databaseSaveDeferred = true
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this.databaseSaveDeferred = false
|
|
121
|
+
const databaseContent = this.connection.export()
|
|
63
122
|
|
|
64
|
-
|
|
123
|
+
await this.persistence.save(databaseContent)
|
|
124
|
+
})
|
|
65
125
|
}
|
|
66
126
|
|
|
67
127
|
saveDatabaseDebounce = debounce(this.saveDatabase, 500)
|