velocious 1.0.548 → 1.0.549

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
@@ -1187,6 +1187,16 @@ npx velocious db:schema:load
1187
1187
 
1188
1188
  `db:schema:load` reads `db/structure-<identifier>.sql` for each configured database identifier and executes those statements against the current connections. Because the structure file includes the migration ledger rows, a load marks every listed version as already applied. The next `db:migrate` sees those versions and skips them, so migrations whose schema changes are already part of the loaded structure do not run again.
1189
1189
 
1190
+ The same load logic is available programmatically for provisioning a database from a structure dump (for example a tenant or test database) in one pass — much faster than materializing a schema table by table:
1191
+
1192
+ ```js
1193
+ import StructureSqlLoader from "velocious/build/src/database/structure-sql-loader.js"
1194
+
1195
+ await new StructureSqlLoader().load({db, structureSql})
1196
+ ```
1197
+
1198
+ `load({db, structureSql})` disables foreign keys around the load (so the order tables reference each other in the dump does not matter) and uses the driver's native multi-statement `exec` in a single round-trip when available. See [docs/database-migrations.md](docs/database-migrations.md).
1199
+
1190
1200
  ## Schema metadata cache
1191
1201
 
1192
1202
  Velocious caches schema metadata on each database driver instance so repeated model initialization, table lookups, column introspection, and structure SQL generation can reuse the same database results. The cache is cleared automatically after schema-changing SQL runs through Velocious, such as migrations, `createTable`, `dropTable`, `renameColumn`, `ALTER TABLE`, `CREATE INDEX`, and `COMMENT ON`. See [docs/schema-metadata-cache.md](docs/schema-metadata-cache.md) for details.
@@ -0,0 +1,68 @@
1
+ // @ts-check
2
+
3
+ import splitSqlStatements from "../utils/split-sql-statements.js"
4
+
5
+ /**
6
+ * Loads a database structure SQL dump into a connection in one pass. Foreign keys are
7
+ * disabled around the load so tables can be created in any order, and the driver's
8
+ * native multi-statement `exec` is used when available (a single round-trip) instead
9
+ * of issuing every statement separately. This is much faster than materializing a
10
+ * schema table by table (e.g. cloning), so it is the preferred way to provision a
11
+ * tenant/test database from a structure dump.
12
+ *
13
+ * Used by the `db:schema:load` CLI command and reusable by any caller that needs to
14
+ * apply a structure dump to a specific connection.
15
+ */
16
+ export default class StructureSqlLoader {
17
+ /**
18
+ * Loads `structureSql` into `db`.
19
+ * @param {object} args - Options object.
20
+ * @param {import("./drivers/base.js").default} args.db - Target database connection.
21
+ * @param {string} args.structureSql - Structure SQL to load.
22
+ * @returns {Promise<void>} - Resolves when the structure has been loaded.
23
+ */
24
+ async load({db, structureSql}) {
25
+ const statements = splitSqlStatements(structureSql)
26
+
27
+ if (statements.length == 0) return
28
+
29
+ const executableConnection = this.executableConnection(db)
30
+
31
+ await db.disableForeignKeys()
32
+
33
+ try {
34
+ if (executableConnection) {
35
+ await executableConnection.exec(structureSql)
36
+ } else {
37
+ for (const statement of statements) {
38
+ await db.query(statement)
39
+ }
40
+ }
41
+ } finally {
42
+ await db.enableForeignKeys()
43
+
44
+ // The native `exec` path mutates the schema outside `Base#query`, so the
45
+ // usual post-DDL schema-cache invalidation never runs. Clear it here so a
46
+ // caller that read schema metadata before provisioning (e.g. an empty table
47
+ // list) does not keep seeing the pre-load schema afterwards. Harmless for the
48
+ // per-statement path, which already invalidates as each DDL statement runs.
49
+ db.clearSchemaCache()
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Returns the underlying connection when it exposes a native multi-statement
55
+ * `exec` (a single round-trip for the whole dump), otherwise undefined so the
56
+ * caller falls back to per-statement execution.
57
+ * @param {import("./drivers/base.js").default} db - Database connection.
58
+ * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
59
+ */
60
+ executableConnection(db) {
61
+ const dbWithConnection = /** @type {import("./drivers/base.js").default & {connection?: ?}} */ (db)
62
+ const connection = dbWithConnection.connection
63
+
64
+ if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
65
+ return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection)
66
+ }
67
+ }
68
+ }
@@ -1,7 +1,7 @@
1
1
  import BaseCommand from "../../../../../../cli/base-command.js"
2
2
  import fs from "fs/promises"
3
3
  import path from "path"
4
- import splitSqlStatements from "../../../../../../utils/split-sql-statements.js"
4
+ import StructureSqlLoader from "../../../../../../database/structure-sql-loader.js"
5
5
 
6
6
  /** Node CLI command for loading DB structure SQL files. */
7
7
  export default class DbSchemaLoad extends BaseCommand {
@@ -11,57 +11,15 @@ export default class DbSchemaLoad extends BaseCommand {
11
11
  async execute() {
12
12
  await this.getConfiguration().ensureConnections({name: "DB schema load"}, async (dbs) => {
13
13
  const dbDir = path.join(this.directory(), "db")
14
+ const loader = new StructureSqlLoader()
14
15
 
15
16
  for (const identifier of Object.keys(dbs)) {
16
17
  const db = dbs[identifier]
17
18
  const structureFilePath = path.join(dbDir, `structure-${identifier}.sql`)
18
19
  const structureSql = await fs.readFile(structureFilePath, "utf8")
19
20
 
20
- await this.loadStructureSql({db, structureSql})
21
+ await loader.load({db, structureSql})
21
22
  }
22
23
  })
23
24
  }
24
-
25
- /**
26
- * Runs load structure sql.
27
- * @param {object} args - Options object.
28
- * @param {import("../../../../../../database/drivers/base.js").default} args.db - Database connection.
29
- * @param {string} args.structureSql - Structure SQL to load.
30
- * @returns {Promise<void>} - Resolves when complete.
31
- */
32
- async loadStructureSql({db, structureSql}) {
33
- const statements = splitSqlStatements(structureSql)
34
-
35
- if (statements.length == 0) return
36
-
37
- const executableConnection = this.executableConnection(db)
38
-
39
- await db.disableForeignKeys()
40
-
41
- try {
42
- if (executableConnection) {
43
- await executableConnection.exec(structureSql)
44
- } else {
45
- for (const statement of statements) {
46
- await db.query(statement)
47
- }
48
- }
49
- } finally {
50
- await db.enableForeignKeys()
51
- }
52
- }
53
-
54
- /**
55
- * Runs executable connection.
56
- * @param {import("../../../../../../database/drivers/base.js").default} db - Database connection.
57
- * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
58
- */
59
- executableConnection(db) {
60
- const dbWithConnection = /** @type {import("../../../../../../database/drivers/base.js").default & {connection?: ?}} */ (db)
61
- const connection = dbWithConnection.connection
62
-
63
- if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
64
- return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection)
65
- }
66
- }
67
25
  }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Loads a database structure SQL dump into a connection in one pass. Foreign keys are
3
+ * disabled around the load so tables can be created in any order, and the driver's
4
+ * native multi-statement `exec` is used when available (a single round-trip) instead
5
+ * of issuing every statement separately. This is much faster than materializing a
6
+ * schema table by table (e.g. cloning), so it is the preferred way to provision a
7
+ * tenant/test database from a structure dump.
8
+ *
9
+ * Used by the `db:schema:load` CLI command and reusable by any caller that needs to
10
+ * apply a structure dump to a specific connection.
11
+ */
12
+ export default class StructureSqlLoader {
13
+ /**
14
+ * Loads `structureSql` into `db`.
15
+ * @param {object} args - Options object.
16
+ * @param {import("./drivers/base.js").default} args.db - Target database connection.
17
+ * @param {string} args.structureSql - Structure SQL to load.
18
+ * @returns {Promise<void>} - Resolves when the structure has been loaded.
19
+ */
20
+ load({ db, structureSql }: {
21
+ db: import("./drivers/base.js").default;
22
+ structureSql: string;
23
+ }): Promise<void>;
24
+ /**
25
+ * Returns the underlying connection when it exposes a native multi-statement
26
+ * `exec` (a single round-trip for the whole dump), otherwise undefined so the
27
+ * caller falls back to per-statement execution.
28
+ * @param {import("./drivers/base.js").default} db - Database connection.
29
+ * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
30
+ */
31
+ executableConnection(db: import("./drivers/base.js").default): {
32
+ exec: (sql: string) => Promise<unknown>;
33
+ } | undefined;
34
+ }
35
+ //# sourceMappingURL=structure-sql-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-sql-loader.d.ts","sourceRoot":"","sources":["../../../src/database/structure-sql-loader.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH;IACE;;;;;;OAMG;IACH,2BAJG;QAAkD,EAAE,EAA5C,OAAO,mBAAmB,EAAE,OAAO;QACtB,YAAY,EAAzB,MAAM;KACd,GAAU,OAAO,CAAC,IAAI,CAAC,CA6BzB;IAED;;;;;;OAMG;IACH,yBAHW,OAAO,mBAAmB,EAAE,OAAO,GACjC;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAC,CAAC,CAAA;KAAC,GAAG,SAAS,CAS3D;CACF"}
@@ -0,0 +1,63 @@
1
+ // @ts-check
2
+ import splitSqlStatements from "../utils/split-sql-statements.js";
3
+ /**
4
+ * Loads a database structure SQL dump into a connection in one pass. Foreign keys are
5
+ * disabled around the load so tables can be created in any order, and the driver's
6
+ * native multi-statement `exec` is used when available (a single round-trip) instead
7
+ * of issuing every statement separately. This is much faster than materializing a
8
+ * schema table by table (e.g. cloning), so it is the preferred way to provision a
9
+ * tenant/test database from a structure dump.
10
+ *
11
+ * Used by the `db:schema:load` CLI command and reusable by any caller that needs to
12
+ * apply a structure dump to a specific connection.
13
+ */
14
+ export default class StructureSqlLoader {
15
+ /**
16
+ * Loads `structureSql` into `db`.
17
+ * @param {object} args - Options object.
18
+ * @param {import("./drivers/base.js").default} args.db - Target database connection.
19
+ * @param {string} args.structureSql - Structure SQL to load.
20
+ * @returns {Promise<void>} - Resolves when the structure has been loaded.
21
+ */
22
+ async load({ db, structureSql }) {
23
+ const statements = splitSqlStatements(structureSql);
24
+ if (statements.length == 0)
25
+ return;
26
+ const executableConnection = this.executableConnection(db);
27
+ await db.disableForeignKeys();
28
+ try {
29
+ if (executableConnection) {
30
+ await executableConnection.exec(structureSql);
31
+ }
32
+ else {
33
+ for (const statement of statements) {
34
+ await db.query(statement);
35
+ }
36
+ }
37
+ }
38
+ finally {
39
+ await db.enableForeignKeys();
40
+ // The native `exec` path mutates the schema outside `Base#query`, so the
41
+ // usual post-DDL schema-cache invalidation never runs. Clear it here so a
42
+ // caller that read schema metadata before provisioning (e.g. an empty table
43
+ // list) does not keep seeing the pre-load schema afterwards. Harmless for the
44
+ // per-statement path, which already invalidates as each DDL statement runs.
45
+ db.clearSchemaCache();
46
+ }
47
+ }
48
+ /**
49
+ * Returns the underlying connection when it exposes a native multi-statement
50
+ * `exec` (a single round-trip for the whole dump), otherwise undefined so the
51
+ * caller falls back to per-statement execution.
52
+ * @param {import("./drivers/base.js").default} db - Database connection.
53
+ * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
54
+ */
55
+ executableConnection(db) {
56
+ const dbWithConnection = /** @type {import("./drivers/base.js").default & {connection?: ?}} */ (db);
57
+ const connection = dbWithConnection.connection;
58
+ if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
59
+ return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection);
60
+ }
61
+ }
62
+ }
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RydWN0dXJlLXNxbC1sb2FkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2Uvc3RydWN0dXJlLXNxbC1sb2FkZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sa0JBQWtCLE1BQU0sa0NBQWtDLENBQUE7QUFFakU7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sa0JBQWtCO0lBQ3JDOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBQyxFQUFFLEVBQUUsWUFBWSxFQUFDO1FBQzNCLE1BQU0sVUFBVSxHQUFHLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRW5ELElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQUUsT0FBTTtRQUVsQyxNQUFNLG9CQUFvQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUUxRCxNQUFNLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBRTdCLElBQUksQ0FBQztZQUNILElBQUksb0JBQW9CLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7WUFDL0MsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQ25DLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQTtnQkFDM0IsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO2dCQUFTLENBQUM7WUFDVCxNQUFNLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFBO1lBRTVCLHlFQUF5RTtZQUN6RSwwRUFBMEU7WUFDMUUsNEVBQTRFO1lBQzVFLDhFQUE4RTtZQUM5RSw0RUFBNEU7WUFDNUUsRUFBRSxDQUFDLGdCQUFnQixFQUFFLENBQUE7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxvQkFBb0IsQ0FBQyxFQUFFO1FBQ3JCLE1BQU0sZ0JBQWdCLEdBQUcscUVBQXFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUNuRyxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUE7UUFFOUMsSUFBSSxVQUFVLElBQUksT0FBTyxVQUFVLElBQUksUUFBUSxJQUFJLE1BQU0sSUFBSSxVQUFVLElBQUksT0FBTyxVQUFVLENBQUMsSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2hILE9BQU8sa0RBQWtELENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN4RSxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBzcGxpdFNxbFN0YXRlbWVudHMgZnJvbSBcIi4uL3V0aWxzL3NwbGl0LXNxbC1zdGF0ZW1lbnRzLmpzXCJcblxuLyoqXG4gKiBMb2FkcyBhIGRhdGFiYXNlIHN0cnVjdHVyZSBTUUwgZHVtcCBpbnRvIGEgY29ubmVjdGlvbiBpbiBvbmUgcGFzcy4gRm9yZWlnbiBrZXlzIGFyZVxuICogZGlzYWJsZWQgYXJvdW5kIHRoZSBsb2FkIHNvIHRhYmxlcyBjYW4gYmUgY3JlYXRlZCBpbiBhbnkgb3JkZXIsIGFuZCB0aGUgZHJpdmVyJ3NcbiAqIG5hdGl2ZSBtdWx0aS1zdGF0ZW1lbnQgYGV4ZWNgIGlzIHVzZWQgd2hlbiBhdmFpbGFibGUgKGEgc2luZ2xlIHJvdW5kLXRyaXApIGluc3RlYWRcbiAqIG9mIGlzc3VpbmcgZXZlcnkgc3RhdGVtZW50IHNlcGFyYXRlbHkuIFRoaXMgaXMgbXVjaCBmYXN0ZXIgdGhhbiBtYXRlcmlhbGl6aW5nIGFcbiAqIHNjaGVtYSB0YWJsZSBieSB0YWJsZSAoZS5nLiBjbG9uaW5nKSwgc28gaXQgaXMgdGhlIHByZWZlcnJlZCB3YXkgdG8gcHJvdmlzaW9uIGFcbiAqIHRlbmFudC90ZXN0IGRhdGFiYXNlIGZyb20gYSBzdHJ1Y3R1cmUgZHVtcC5cbiAqXG4gKiBVc2VkIGJ5IHRoZSBgZGI6c2NoZW1hOmxvYWRgIENMSSBjb21tYW5kIGFuZCByZXVzYWJsZSBieSBhbnkgY2FsbGVyIHRoYXQgbmVlZHMgdG9cbiAqIGFwcGx5IGEgc3RydWN0dXJlIGR1bXAgdG8gYSBzcGVjaWZpYyBjb25uZWN0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdHJ1Y3R1cmVTcWxMb2FkZXIge1xuICAvKipcbiAgICogTG9hZHMgYHN0cnVjdHVyZVNxbGAgaW50byBgZGJgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MuZGIgLSBUYXJnZXQgZGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3Muc3RydWN0dXJlU3FsIC0gU3RydWN0dXJlIFNRTCB0byBsb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBzdHJ1Y3R1cmUgaGFzIGJlZW4gbG9hZGVkLlxuICAgKi9cbiAgYXN5bmMgbG9hZCh7ZGIsIHN0cnVjdHVyZVNxbH0pIHtcbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gc3BsaXRTcWxTdGF0ZW1lbnRzKHN0cnVjdHVyZVNxbClcblxuICAgIGlmIChzdGF0ZW1lbnRzLmxlbmd0aCA9PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IGV4ZWN1dGFibGVDb25uZWN0aW9uID0gdGhpcy5leGVjdXRhYmxlQ29ubmVjdGlvbihkYilcblxuICAgIGF3YWl0IGRiLmRpc2FibGVGb3JlaWduS2V5cygpXG5cbiAgICB0cnkge1xuICAgICAgaWYgKGV4ZWN1dGFibGVDb25uZWN0aW9uKSB7XG4gICAgICAgIGF3YWl0IGV4ZWN1dGFibGVDb25uZWN0aW9uLmV4ZWMoc3RydWN0dXJlU3FsKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2Ygc3RhdGVtZW50cykge1xuICAgICAgICAgIGF3YWl0IGRiLnF1ZXJ5KHN0YXRlbWVudClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBkYi5lbmFibGVGb3JlaWduS2V5cygpXG5cbiAgICAgIC8vIFRoZSBuYXRpdmUgYGV4ZWNgIHBhdGggbXV0YXRlcyB0aGUgc2NoZW1hIG91dHNpZGUgYEJhc2UjcXVlcnlgLCBzbyB0aGVcbiAgICAgIC8vIHVzdWFsIHBvc3QtRERMIHNjaGVtYS1jYWNoZSBpbnZhbGlkYXRpb24gbmV2ZXIgcnVucy4gQ2xlYXIgaXQgaGVyZSBzbyBhXG4gICAgICAvLyBjYWxsZXIgdGhhdCByZWFkIHNjaGVtYSBtZXRhZGF0YSBiZWZvcmUgcHJvdmlzaW9uaW5nIChlLmcuIGFuIGVtcHR5IHRhYmxlXG4gICAgICAvLyBsaXN0KSBkb2VzIG5vdCBrZWVwIHNlZWluZyB0aGUgcHJlLWxvYWQgc2NoZW1hIGFmdGVyd2FyZHMuIEhhcm1sZXNzIGZvciB0aGVcbiAgICAgIC8vIHBlci1zdGF0ZW1lbnQgcGF0aCwgd2hpY2ggYWxyZWFkeSBpbnZhbGlkYXRlcyBhcyBlYWNoIERETCBzdGF0ZW1lbnQgcnVucy5cbiAgICAgIGRiLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gd2hlbiBpdCBleHBvc2VzIGEgbmF0aXZlIG11bHRpLXN0YXRlbWVudFxuICAgKiBgZXhlY2AgKGEgc2luZ2xlIHJvdW5kLXRyaXAgZm9yIHRoZSB3aG9sZSBkdW1wKSwgb3RoZXJ3aXNlIHVuZGVmaW5lZCBzbyB0aGVcbiAgICogY2FsbGVyIGZhbGxzIGJhY2sgdG8gcGVyLXN0YXRlbWVudCBleGVjdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7e2V4ZWM6IChzcWw6IHN0cmluZykgPT4gUHJvbWlzZTw/Pn0gfCB1bmRlZmluZWR9IC0gQ29ubmVjdGlvbiB3aXRoIGV4ZWMgc3VwcG9ydC5cbiAgICovXG4gIGV4ZWN1dGFibGVDb25uZWN0aW9uKGRiKSB7XG4gICAgY29uc3QgZGJXaXRoQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtjb25uZWN0aW9uPzogP319ICovIChkYilcbiAgICBjb25zdCBjb25uZWN0aW9uID0gZGJXaXRoQ29ubmVjdGlvbi5jb25uZWN0aW9uXG5cbiAgICBpZiAoY29ubmVjdGlvbiAmJiB0eXBlb2YgY29ubmVjdGlvbiA9PSBcIm9iamVjdFwiICYmIFwiZXhlY1wiIGluIGNvbm5lY3Rpb24gJiYgdHlwZW9mIGNvbm5lY3Rpb24uZXhlYyA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiAvKiogQHR5cGUge3tleGVjOiAoc3FsOiBzdHJpbmcpID0+IFByb21pc2U8Pz59fSAqLyAoY29ubmVjdGlvbilcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -4,25 +4,6 @@ export default class DbSchemaLoad extends BaseCommand {
4
4
  * Runs execute.
5
5
  * @returns {Promise<void>} */
6
6
  execute(): Promise<void>;
7
- /**
8
- * Runs load structure sql.
9
- * @param {object} args - Options object.
10
- * @param {import("../../../../../../database/drivers/base.js").default} args.db - Database connection.
11
- * @param {string} args.structureSql - Structure SQL to load.
12
- * @returns {Promise<void>} - Resolves when complete.
13
- */
14
- loadStructureSql({ db, structureSql }: {
15
- db: import("../../../../../../database/drivers/base.js").default;
16
- structureSql: string;
17
- }): Promise<void>;
18
- /**
19
- * Runs executable connection.
20
- * @param {import("../../../../../../database/drivers/base.js").default} db - Database connection.
21
- * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
22
- */
23
- executableConnection(db: import("../../../../../../database/drivers/base.js").default): {
24
- exec: (sql: string) => Promise<unknown>;
25
- } | undefined;
26
7
  }
27
8
  import BaseCommand from "../../../../../../cli/base-command.js";
28
9
  //# sourceMappingURL=load.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../../../../../src/environment-handlers/node/cli/commands/db/schema/load.js"],"names":[],"mappings":"AAKA,2DAA2D;AAC3D;IACE;;kCAE8B;IAC9B,WADa,OAAO,CAAC,IAAI,CAAC,CAazB;IAED;;;;;;OAMG;IACH,uCAJG;QAA2E,EAAE,EAArE,OAAO,4CAA4C,EAAE,OAAO;QAC/C,YAAY,EAAzB,MAAM;KACd,GAAU,OAAO,CAAC,IAAI,CAAC,CAsBzB;IAED;;;;OAIG;IACH,yBAHW,OAAO,4CAA4C,EAAE,OAAO,GAC1D;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAC,CAAC,CAAA;KAAC,GAAG,SAAS,CAS3D;CACF;wBAlEuB,uCAAuC"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../../../../../src/environment-handlers/node/cli/commands/db/schema/load.js"],"names":[],"mappings":"AAKA,2DAA2D;AAC3D;IACE;;kCAE8B;IAC9B,WADa,OAAO,CAAC,IAAI,CAAC,CAczB;CACF;wBAxBuB,uCAAuC"}
@@ -1,7 +1,7 @@
1
1
  import BaseCommand from "../../../../../../cli/base-command.js";
2
2
  import fs from "fs/promises";
3
3
  import path from "path";
4
- import splitSqlStatements from "../../../../../../utils/split-sql-statements.js";
4
+ import StructureSqlLoader from "../../../../../../database/structure-sql-loader.js";
5
5
  /** Node CLI command for loading DB structure SQL files. */
6
6
  export default class DbSchemaLoad extends BaseCommand {
7
7
  /**
@@ -10,52 +10,14 @@ export default class DbSchemaLoad extends BaseCommand {
10
10
  async execute() {
11
11
  await this.getConfiguration().ensureConnections({ name: "DB schema load" }, async (dbs) => {
12
12
  const dbDir = path.join(this.directory(), "db");
13
+ const loader = new StructureSqlLoader();
13
14
  for (const identifier of Object.keys(dbs)) {
14
15
  const db = dbs[identifier];
15
16
  const structureFilePath = path.join(dbDir, `structure-${identifier}.sql`);
16
17
  const structureSql = await fs.readFile(structureFilePath, "utf8");
17
- await this.loadStructureSql({ db, structureSql });
18
+ await loader.load({ db, structureSql });
18
19
  }
19
20
  });
20
21
  }
21
- /**
22
- * Runs load structure sql.
23
- * @param {object} args - Options object.
24
- * @param {import("../../../../../../database/drivers/base.js").default} args.db - Database connection.
25
- * @param {string} args.structureSql - Structure SQL to load.
26
- * @returns {Promise<void>} - Resolves when complete.
27
- */
28
- async loadStructureSql({ db, structureSql }) {
29
- const statements = splitSqlStatements(structureSql);
30
- if (statements.length == 0)
31
- return;
32
- const executableConnection = this.executableConnection(db);
33
- await db.disableForeignKeys();
34
- try {
35
- if (executableConnection) {
36
- await executableConnection.exec(structureSql);
37
- }
38
- else {
39
- for (const statement of statements) {
40
- await db.query(statement);
41
- }
42
- }
43
- }
44
- finally {
45
- await db.enableForeignKeys();
46
- }
47
- }
48
- /**
49
- * Runs executable connection.
50
- * @param {import("../../../../../../database/drivers/base.js").default} db - Database connection.
51
- * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
52
- */
53
- executableConnection(db) {
54
- const dbWithConnection = /** @type {import("../../../../../../database/drivers/base.js").default & {connection?: ?}} */ (db);
55
- const connection = dbWithConnection.connection;
56
- if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
57
- return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection);
58
- }
59
- }
60
22
  }
61
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9lbnZpcm9ubWVudC1oYW5kbGVycy9ub2RlL2NsaS9jb21tYW5kcy9kYi9zY2hlbWEvbG9hZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFdBQVcsTUFBTSx1Q0FBdUMsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDNUIsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sa0JBQWtCLE1BQU0saURBQWlELENBQUE7QUFFaEYsMkRBQTJEO0FBQzNELE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBYSxTQUFRLFdBQVc7SUFDbkQ7O2tDQUU4QjtJQUM5QixLQUFLLENBQUMsT0FBTztRQUNYLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDdEYsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFFL0MsS0FBSyxNQUFNLFVBQVUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQTtnQkFDMUIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxhQUFhLFVBQVUsTUFBTSxDQUFDLENBQUE7Z0JBQ3pFLE1BQU0sWUFBWSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUMsQ0FBQTtnQkFFakUsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBQyxFQUFFLEVBQUUsWUFBWSxFQUFDLENBQUMsQ0FBQTtZQUNqRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEVBQUMsRUFBRSxFQUFFLFlBQVksRUFBQztRQUN2QyxNQUFNLFVBQVUsR0FBRyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUVuRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQztZQUFFLE9BQU07UUFFbEMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUE7UUFFMUQsTUFBTSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQTtRQUU3QixJQUFJLENBQUM7WUFDSCxJQUFJLG9CQUFvQixFQUFFLENBQUM7Z0JBQ3pCLE1BQU0sb0JBQW9CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO1lBQy9DLENBQUM7aUJBQU0sQ0FBQztnQkFDTixLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO29CQUNuQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUE7Z0JBQzNCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsTUFBTSxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtRQUM5QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxvQkFBb0IsQ0FBQyxFQUFFO1FBQ3JCLE1BQU0sZ0JBQWdCLEdBQUcsOEZBQThGLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUM1SCxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUE7UUFFOUMsSUFBSSxVQUFVLElBQUksT0FBTyxVQUFVLElBQUksUUFBUSxJQUFJLE1BQU0sSUFBSSxVQUFVLElBQUksT0FBTyxVQUFVLENBQUMsSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2hILE9BQU8sa0RBQWtELENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN4RSxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJhc2VDb21tYW5kIGZyb20gXCIuLi8uLi8uLi8uLi8uLi8uLi9jbGkvYmFzZS1jb21tYW5kLmpzXCJcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIlxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIlxuaW1wb3J0IHNwbGl0U3FsU3RhdGVtZW50cyBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vdXRpbHMvc3BsaXQtc3FsLXN0YXRlbWVudHMuanNcIlxuXG4vKiogTm9kZSBDTEkgY29tbWFuZCBmb3IgbG9hZGluZyBEQiBzdHJ1Y3R1cmUgU1FMIGZpbGVzLiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGJTY2hlbWFMb2FkIGV4dGVuZHMgQmFzZUNvbW1hbmQge1xuICAvKipcbiAgICogUnVucyBleGVjdXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gKi9cbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJEQiBzY2hlbWEgbG9hZFwifSwgYXN5bmMgKGRicykgPT4ge1xuICAgICAgY29uc3QgZGJEaXIgPSBwYXRoLmpvaW4odGhpcy5kaXJlY3RvcnkoKSwgXCJkYlwiKVxuXG4gICAgICBmb3IgKGNvbnN0IGlkZW50aWZpZXIgb2YgT2JqZWN0LmtleXMoZGJzKSkge1xuICAgICAgICBjb25zdCBkYiA9IGRic1tpZGVudGlmaWVyXVxuICAgICAgICBjb25zdCBzdHJ1Y3R1cmVGaWxlUGF0aCA9IHBhdGguam9pbihkYkRpciwgYHN0cnVjdHVyZS0ke2lkZW50aWZpZXJ9LnNxbGApXG4gICAgICAgIGNvbnN0IHN0cnVjdHVyZVNxbCA9IGF3YWl0IGZzLnJlYWRGaWxlKHN0cnVjdHVyZUZpbGVQYXRoLCBcInV0ZjhcIilcblxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRTdHJ1Y3R1cmVTcWwoe2RiLCBzdHJ1Y3R1cmVTcWx9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2FkIHN0cnVjdHVyZSBzcWwuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vLi4vLi4vLi4vLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MuZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5zdHJ1Y3R1cmVTcWwgLSBTdHJ1Y3R1cmUgU1FMIHRvIGxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBsb2FkU3RydWN0dXJlU3FsKHtkYiwgc3RydWN0dXJlU3FsfSkge1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBzcGxpdFNxbFN0YXRlbWVudHMoc3RydWN0dXJlU3FsKVxuXG4gICAgaWYgKHN0YXRlbWVudHMubGVuZ3RoID09IDApIHJldHVyblxuXG4gICAgY29uc3QgZXhlY3V0YWJsZUNvbm5lY3Rpb24gPSB0aGlzLmV4ZWN1dGFibGVDb25uZWN0aW9uKGRiKVxuXG4gICAgYXdhaXQgZGIuZGlzYWJsZUZvcmVpZ25LZXlzKClcblxuICAgIHRyeSB7XG4gICAgICBpZiAoZXhlY3V0YWJsZUNvbm5lY3Rpb24pIHtcbiAgICAgICAgYXdhaXQgZXhlY3V0YWJsZUNvbm5lY3Rpb24uZXhlYyhzdHJ1Y3R1cmVTcWwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBzdGF0ZW1lbnRzKSB7XG4gICAgICAgICAgYXdhaXQgZGIucXVlcnkoc3RhdGVtZW50KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRiLmVuYWJsZUZvcmVpZ25LZXlzKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBleGVjdXRhYmxlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vLi4vLi4vLi4vLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3tleGVjOiAoc3FsOiBzdHJpbmcpID0+IFByb21pc2U8Pz59IHwgdW5kZWZpbmVkfSAtIENvbm5lY3Rpb24gd2l0aCBleGVjIHN1cHBvcnQuXG4gICAqL1xuICBleGVjdXRhYmxlQ29ubmVjdGlvbihkYikge1xuICAgIGNvbnN0IGRiV2l0aENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uLy4uLy4uLy4uLy4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge2Nvbm5lY3Rpb24/OiA/fX0gKi8gKGRiKVxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBkYldpdGhDb25uZWN0aW9uLmNvbm5lY3Rpb25cblxuICAgIGlmIChjb25uZWN0aW9uICYmIHR5cGVvZiBjb25uZWN0aW9uID09IFwib2JqZWN0XCIgJiYgXCJleGVjXCIgaW4gY29ubmVjdGlvbiAmJiB0eXBlb2YgY29ubmVjdGlvbi5leGVjID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7e2V4ZWM6IChzcWw6IHN0cmluZykgPT4gUHJvbWlzZTw/Pn19ICovIChjb25uZWN0aW9uKVxuICAgIH1cbiAgfVxufVxuIl19
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9lbnZpcm9ubWVudC1oYW5kbGVycy9ub2RlL2NsaS9jb21tYW5kcy9kYi9zY2hlbWEvbG9hZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFdBQVcsTUFBTSx1Q0FBdUMsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDNUIsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sa0JBQWtCLE1BQU0sb0RBQW9ELENBQUE7QUFFbkYsMkRBQTJEO0FBQzNELE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBYSxTQUFRLFdBQVc7SUFDbkQ7O2tDQUU4QjtJQUM5QixLQUFLLENBQUMsT0FBTztRQUNYLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDdEYsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDL0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxrQkFBa0IsRUFBRSxDQUFBO1lBRXZDLEtBQUssTUFBTSxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUE7Z0JBQzFCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsYUFBYSxVQUFVLE1BQU0sQ0FBQyxDQUFBO2dCQUN6RSxNQUFNLFlBQVksR0FBRyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLENBQUE7Z0JBRWpFLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUMsQ0FBQyxDQUFBO1lBQ3ZDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBCYXNlQ29tbWFuZCBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vLi4vY2xpL2Jhc2UtY29tbWFuZC5qc1wiXG5pbXBvcnQgZnMgZnJvbSBcImZzL3Byb21pc2VzXCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCBTdHJ1Y3R1cmVTcWxMb2FkZXIgZnJvbSBcIi4uLy4uLy4uLy4uLy4uLy4uL2RhdGFiYXNlL3N0cnVjdHVyZS1zcWwtbG9hZGVyLmpzXCJcblxuLyoqIE5vZGUgQ0xJIGNvbW1hbmQgZm9yIGxvYWRpbmcgREIgc3RydWN0dXJlIFNRTCBmaWxlcy4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERiU2NoZW1hTG9hZCBleHRlbmRzIEJhc2VDb21tYW5kIHtcbiAgLyoqXG4gICAqIFJ1bnMgZXhlY3V0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59ICovXG4gIGFzeW5jIGV4ZWN1dGUoKSB7XG4gICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiREIgc2NoZW1hIGxvYWRcIn0sIGFzeW5jIChkYnMpID0+IHtcbiAgICAgIGNvbnN0IGRiRGlyID0gcGF0aC5qb2luKHRoaXMuZGlyZWN0b3J5KCksIFwiZGJcIilcbiAgICAgIGNvbnN0IGxvYWRlciA9IG5ldyBTdHJ1Y3R1cmVTcWxMb2FkZXIoKVxuXG4gICAgICBmb3IgKGNvbnN0IGlkZW50aWZpZXIgb2YgT2JqZWN0LmtleXMoZGJzKSkge1xuICAgICAgICBjb25zdCBkYiA9IGRic1tpZGVudGlmaWVyXVxuICAgICAgICBjb25zdCBzdHJ1Y3R1cmVGaWxlUGF0aCA9IHBhdGguam9pbihkYkRpciwgYHN0cnVjdHVyZS0ke2lkZW50aWZpZXJ9LnNxbGApXG4gICAgICAgIGNvbnN0IHN0cnVjdHVyZVNxbCA9IGF3YWl0IGZzLnJlYWRGaWxlKHN0cnVjdHVyZUZpbGVQYXRoLCBcInV0ZjhcIilcblxuICAgICAgICBhd2FpdCBsb2FkZXIubG9hZCh7ZGIsIHN0cnVjdHVyZVNxbH0pXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuIl19
@@ -1 +1 @@
1
- {"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/record-changes.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
1
+ {"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/record-changes.js","../src/database/structure-sql-loader.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.548",
6
+ "version": "1.0.549",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -0,0 +1,68 @@
1
+ // @ts-check
2
+
3
+ import splitSqlStatements from "../utils/split-sql-statements.js"
4
+
5
+ /**
6
+ * Loads a database structure SQL dump into a connection in one pass. Foreign keys are
7
+ * disabled around the load so tables can be created in any order, and the driver's
8
+ * native multi-statement `exec` is used when available (a single round-trip) instead
9
+ * of issuing every statement separately. This is much faster than materializing a
10
+ * schema table by table (e.g. cloning), so it is the preferred way to provision a
11
+ * tenant/test database from a structure dump.
12
+ *
13
+ * Used by the `db:schema:load` CLI command and reusable by any caller that needs to
14
+ * apply a structure dump to a specific connection.
15
+ */
16
+ export default class StructureSqlLoader {
17
+ /**
18
+ * Loads `structureSql` into `db`.
19
+ * @param {object} args - Options object.
20
+ * @param {import("./drivers/base.js").default} args.db - Target database connection.
21
+ * @param {string} args.structureSql - Structure SQL to load.
22
+ * @returns {Promise<void>} - Resolves when the structure has been loaded.
23
+ */
24
+ async load({db, structureSql}) {
25
+ const statements = splitSqlStatements(structureSql)
26
+
27
+ if (statements.length == 0) return
28
+
29
+ const executableConnection = this.executableConnection(db)
30
+
31
+ await db.disableForeignKeys()
32
+
33
+ try {
34
+ if (executableConnection) {
35
+ await executableConnection.exec(structureSql)
36
+ } else {
37
+ for (const statement of statements) {
38
+ await db.query(statement)
39
+ }
40
+ }
41
+ } finally {
42
+ await db.enableForeignKeys()
43
+
44
+ // The native `exec` path mutates the schema outside `Base#query`, so the
45
+ // usual post-DDL schema-cache invalidation never runs. Clear it here so a
46
+ // caller that read schema metadata before provisioning (e.g. an empty table
47
+ // list) does not keep seeing the pre-load schema afterwards. Harmless for the
48
+ // per-statement path, which already invalidates as each DDL statement runs.
49
+ db.clearSchemaCache()
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Returns the underlying connection when it exposes a native multi-statement
55
+ * `exec` (a single round-trip for the whole dump), otherwise undefined so the
56
+ * caller falls back to per-statement execution.
57
+ * @param {import("./drivers/base.js").default} db - Database connection.
58
+ * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
59
+ */
60
+ executableConnection(db) {
61
+ const dbWithConnection = /** @type {import("./drivers/base.js").default & {connection?: ?}} */ (db)
62
+ const connection = dbWithConnection.connection
63
+
64
+ if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
65
+ return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection)
66
+ }
67
+ }
68
+ }
@@ -1,7 +1,7 @@
1
1
  import BaseCommand from "../../../../../../cli/base-command.js"
2
2
  import fs from "fs/promises"
3
3
  import path from "path"
4
- import splitSqlStatements from "../../../../../../utils/split-sql-statements.js"
4
+ import StructureSqlLoader from "../../../../../../database/structure-sql-loader.js"
5
5
 
6
6
  /** Node CLI command for loading DB structure SQL files. */
7
7
  export default class DbSchemaLoad extends BaseCommand {
@@ -11,57 +11,15 @@ export default class DbSchemaLoad extends BaseCommand {
11
11
  async execute() {
12
12
  await this.getConfiguration().ensureConnections({name: "DB schema load"}, async (dbs) => {
13
13
  const dbDir = path.join(this.directory(), "db")
14
+ const loader = new StructureSqlLoader()
14
15
 
15
16
  for (const identifier of Object.keys(dbs)) {
16
17
  const db = dbs[identifier]
17
18
  const structureFilePath = path.join(dbDir, `structure-${identifier}.sql`)
18
19
  const structureSql = await fs.readFile(structureFilePath, "utf8")
19
20
 
20
- await this.loadStructureSql({db, structureSql})
21
+ await loader.load({db, structureSql})
21
22
  }
22
23
  })
23
24
  }
24
-
25
- /**
26
- * Runs load structure sql.
27
- * @param {object} args - Options object.
28
- * @param {import("../../../../../../database/drivers/base.js").default} args.db - Database connection.
29
- * @param {string} args.structureSql - Structure SQL to load.
30
- * @returns {Promise<void>} - Resolves when complete.
31
- */
32
- async loadStructureSql({db, structureSql}) {
33
- const statements = splitSqlStatements(structureSql)
34
-
35
- if (statements.length == 0) return
36
-
37
- const executableConnection = this.executableConnection(db)
38
-
39
- await db.disableForeignKeys()
40
-
41
- try {
42
- if (executableConnection) {
43
- await executableConnection.exec(structureSql)
44
- } else {
45
- for (const statement of statements) {
46
- await db.query(statement)
47
- }
48
- }
49
- } finally {
50
- await db.enableForeignKeys()
51
- }
52
- }
53
-
54
- /**
55
- * Runs executable connection.
56
- * @param {import("../../../../../../database/drivers/base.js").default} db - Database connection.
57
- * @returns {{exec: (sql: string) => Promise<?>} | undefined} - Connection with exec support.
58
- */
59
- executableConnection(db) {
60
- const dbWithConnection = /** @type {import("../../../../../../database/drivers/base.js").default & {connection?: ?}} */ (db)
61
- const connection = dbWithConnection.connection
62
-
63
- if (connection && typeof connection == "object" && "exec" in connection && typeof connection.exec == "function") {
64
- return /** @type {{exec: (sql: string) => Promise<?>}} */ (connection)
65
- }
66
- }
67
25
  }