velocious 1.0.548 → 1.0.551
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 +23 -0
- package/build/database/advisory-lock-runner.js +17 -8
- package/build/database/structure-sql-loader.js +68 -0
- package/build/environment-handlers/node/cli/commands/db/schema/load.js +3 -45
- package/build/src/database/advisory-lock-runner.d.ts +25 -8
- package/build/src/database/advisory-lock-runner.d.ts.map +1 -1
- package/build/src/database/advisory-lock-runner.js +18 -9
- package/build/src/database/structure-sql-loader.d.ts +35 -0
- package/build/src/database/structure-sql-loader.d.ts.map +1 -0
- package/build/src/database/structure-sql-loader.js +63 -0
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +0 -19
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +4 -42
- package/build/src/testing/test.d.ts +2 -1
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +3 -2
- package/build/src/testing/wait-for-event.d.ts +46 -0
- package/build/src/testing/wait-for-event.d.ts.map +1 -0
- package/build/src/testing/wait-for-event.js +64 -0
- package/build/testing/test.js +2 -1
- package/build/testing/wait-for-event.js +72 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/database/advisory-lock-runner.js +17 -8
- package/src/database/structure-sql-loader.js +68 -0
- package/src/environment-handlers/node/cli/commands/db/schema/load.js +3 -45
- package/src/testing/test.js +2 -1
- package/src/testing/wait-for-event.js +72 -0
package/README.md
CHANGED
|
@@ -141,6 +141,19 @@ Slowest 10 tests:
|
|
|
141
141
|
|
|
142
142
|
The report is skipped for single-test runs. See [docs/testing-guidelines.md](docs/testing-guidelines.md).
|
|
143
143
|
|
|
144
|
+
Prefer waiting for a real signal or condition over sleeping a fixed duration. `waitForEvent(emitter, eventName, {timeoutMs, filter})` resolves the instant a matching event fires (a background job finishing, a model update, a websocket message) and rejects on timeout; for polling an arbitrary condition, use awaitery's `waitFor`.
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
import {waitForEvent} from "velocious/build/src/testing/test.js"
|
|
148
|
+
import waitFor from "awaitery/build/wait-for.js"
|
|
149
|
+
|
|
150
|
+
// Event-driven: resolves as soon as the matching event fires (no polling latency).
|
|
151
|
+
const {result} = await waitForEvent(jobRunner, "jobFinished", {filter: (event) => event.jobId === jobId})
|
|
152
|
+
|
|
153
|
+
// Condition polling: retries the callback until it stops throwing.
|
|
154
|
+
await waitFor(() => expect(await Message.count()).toEqual(1))
|
|
155
|
+
```
|
|
156
|
+
|
|
144
157
|
Velocious captures console output emitted while each test executes, but does not print passing-test output by default. When a test fails, Velocious prints a truncated `Console output:` block for that failed test and saves the full captured log under `tmp/screenshots` next to failure screenshots/browser logs/HTML. Each failed test summary prints the saved console log path.
|
|
145
158
|
|
|
146
159
|
Configure console output behavior in your testing config file.
|
|
@@ -1187,6 +1200,16 @@ npx velocious db:schema:load
|
|
|
1187
1200
|
|
|
1188
1201
|
`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
1202
|
|
|
1203
|
+
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:
|
|
1204
|
+
|
|
1205
|
+
```js
|
|
1206
|
+
import StructureSqlLoader from "velocious/build/src/database/structure-sql-loader.js"
|
|
1207
|
+
|
|
1208
|
+
await new StructureSqlLoader().load({db, structureSql})
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
`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).
|
|
1212
|
+
|
|
1190
1213
|
## Schema metadata cache
|
|
1191
1214
|
|
|
1192
1215
|
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.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import timeout from "awaitery/build/timeout.js"
|
|
3
|
+
import timeout, {TimeoutError} from "awaitery/build/timeout.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Thrown when an advisory lock could not be acquired before `timeoutMs` elapsed.
|
|
@@ -67,9 +67,12 @@ export default class AdvisoryLockRunner {
|
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* Runs a callback after acquiring the advisory lock, waiting up to `timeoutMs`.
|
|
70
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
71
|
+
* awaitery for cooperative cancellation (`control.check()`, `control.signal`,
|
|
72
|
+
* `control.timedOut`, `control.remaining()`).
|
|
70
73
|
* @template T
|
|
71
74
|
* @param {string} name - Lock name.
|
|
72
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
75
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
73
76
|
* @param {{timeoutMs?: number | null, holdTimeoutMs?: number | null}} [args] - Lock and hold timeout options.
|
|
74
77
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
75
78
|
*/
|
|
@@ -87,9 +90,11 @@ export default class AdvisoryLockRunner {
|
|
|
87
90
|
|
|
88
91
|
/**
|
|
89
92
|
* Runs a callback only if the advisory lock can be acquired immediately.
|
|
93
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
94
|
+
* awaitery for cooperative cancellation.
|
|
90
95
|
* @template T
|
|
91
96
|
* @param {string} name - Lock name.
|
|
92
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
97
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
93
98
|
* @param {{holdTimeoutMs?: number | null}} [args] - Hold timeout options.
|
|
94
99
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
95
100
|
*/
|
|
@@ -108,7 +113,7 @@ export default class AdvisoryLockRunner {
|
|
|
108
113
|
/**
|
|
109
114
|
* Runs the lock holder callback and releases the lock from its owning connection.
|
|
110
115
|
* @template T
|
|
111
|
-
* @param {{callback: () => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
116
|
+
* @param {{callback: (args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
112
117
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
113
118
|
*/
|
|
114
119
|
async runLockedCallback({callback, connection, holdTimeoutMs, name}) {
|
|
@@ -160,9 +165,13 @@ export default class AdvisoryLockRunner {
|
|
|
160
165
|
* Runs `callback`, rejecting with `AdvisoryLockHoldTimeoutError` if it has
|
|
161
166
|
* not settled within `holdTimeoutMs`. The callback is not cancelled; callers
|
|
162
167
|
* use a dedicated advisory-lock connection so the lock can still be released.
|
|
168
|
+
*
|
|
169
|
+
* The callback receives a `TimeoutControl` from awaitery, enabling cooperative
|
|
170
|
+
* cancellation via `control.check()`, `control.signal`, `control.timedOut`,
|
|
171
|
+
* and `control.remaining()`.
|
|
163
172
|
* @template T
|
|
164
173
|
* @param {string} name - Lock name (for the error message).
|
|
165
|
-
* @param {() => Promise<T>} callback - Callback holding the lock.
|
|
174
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback holding the lock.
|
|
166
175
|
* @param {number | null} [holdTimeoutMs] - Max hold time; falsy disables the timeout.
|
|
167
176
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
168
177
|
*/
|
|
@@ -174,15 +183,15 @@ export default class AdvisoryLockRunner {
|
|
|
174
183
|
let callbackSettled = false
|
|
175
184
|
|
|
176
185
|
try {
|
|
177
|
-
return await timeout({timeout: holdTimeoutMs}, async () => {
|
|
186
|
+
return await timeout({timeout: holdTimeoutMs}, async ({control}) => {
|
|
178
187
|
try {
|
|
179
|
-
return await callback()
|
|
188
|
+
return await callback({control})
|
|
180
189
|
} finally {
|
|
181
190
|
callbackSettled = true
|
|
182
191
|
}
|
|
183
192
|
})
|
|
184
193
|
} catch (error) {
|
|
185
|
-
if (!callbackSettled) {
|
|
194
|
+
if (!callbackSettled || error instanceof TimeoutError) {
|
|
186
195
|
throw new AdvisoryLockHoldTimeoutError(`Advisory lock ${JSON.stringify(name)} held longer than ${holdTimeoutMs}ms`, {name})
|
|
187
196
|
}
|
|
188
197
|
|
|
@@ -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
|
|
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
|
|
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
|
}
|
|
@@ -7,13 +7,19 @@ export default class AdvisoryLockRunner {
|
|
|
7
7
|
* Runs `callback`, rejecting with `AdvisoryLockHoldTimeoutError` if it has
|
|
8
8
|
* not settled within `holdTimeoutMs`. The callback is not cancelled; callers
|
|
9
9
|
* use a dedicated advisory-lock connection so the lock can still be released.
|
|
10
|
+
*
|
|
11
|
+
* The callback receives a `TimeoutControl` from awaitery, enabling cooperative
|
|
12
|
+
* cancellation via `control.check()`, `control.signal`, `control.timedOut`,
|
|
13
|
+
* and `control.remaining()`.
|
|
10
14
|
* @template T
|
|
11
15
|
* @param {string} name - Lock name (for the error message).
|
|
12
|
-
* @param {() => Promise<T>} callback - Callback holding the lock.
|
|
16
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback holding the lock.
|
|
13
17
|
* @param {number | null} [holdTimeoutMs] - Max hold time; falsy disables the timeout.
|
|
14
18
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
15
19
|
*/
|
|
16
|
-
static runWithAdvisoryLockHoldTimeout<T>(name: string, callback: (
|
|
20
|
+
static runWithAdvisoryLockHoldTimeout<T>(name: string, callback: (args?: {
|
|
21
|
+
control: import("awaitery/build/timeout.js").TimeoutControl;
|
|
22
|
+
}) => Promise<T>, holdTimeoutMs?: number | null): Promise<T>;
|
|
17
23
|
/**
|
|
18
24
|
* Creates an advisory-lock runner for one model database identifier.
|
|
19
25
|
* @param {{configuration: import("../configuration.js").default, connectionProvider: () => import("./drivers/base.js").default, databaseIdentifier: string}} args - Runner dependencies.
|
|
@@ -28,35 +34,46 @@ export default class AdvisoryLockRunner {
|
|
|
28
34
|
databaseIdentifier: string;
|
|
29
35
|
/**
|
|
30
36
|
* Runs a callback after acquiring the advisory lock, waiting up to `timeoutMs`.
|
|
37
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
38
|
+
* awaitery for cooperative cancellation (`control.check()`, `control.signal`,
|
|
39
|
+
* `control.timedOut`, `control.remaining()`).
|
|
31
40
|
* @template T
|
|
32
41
|
* @param {string} name - Lock name.
|
|
33
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
42
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
34
43
|
* @param {{timeoutMs?: number | null, holdTimeoutMs?: number | null}} [args] - Lock and hold timeout options.
|
|
35
44
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
36
45
|
*/
|
|
37
|
-
withAdvisoryLock<T>(name: string, callback: (
|
|
46
|
+
withAdvisoryLock<T>(name: string, callback: (args?: {
|
|
47
|
+
control: import("awaitery/build/timeout.js").TimeoutControl;
|
|
48
|
+
}) => Promise<T>, args?: {
|
|
38
49
|
timeoutMs?: number | null;
|
|
39
50
|
holdTimeoutMs?: number | null;
|
|
40
51
|
}): Promise<T>;
|
|
41
52
|
/**
|
|
42
53
|
* Runs a callback only if the advisory lock can be acquired immediately.
|
|
54
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
55
|
+
* awaitery for cooperative cancellation.
|
|
43
56
|
* @template T
|
|
44
57
|
* @param {string} name - Lock name.
|
|
45
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
58
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
46
59
|
* @param {{holdTimeoutMs?: number | null}} [args] - Hold timeout options.
|
|
47
60
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
48
61
|
*/
|
|
49
|
-
withAdvisoryLockOrFail<T>(name: string, callback: (
|
|
62
|
+
withAdvisoryLockOrFail<T>(name: string, callback: (args?: {
|
|
63
|
+
control: import("awaitery/build/timeout.js").TimeoutControl;
|
|
64
|
+
}) => Promise<T>, args?: {
|
|
50
65
|
holdTimeoutMs?: number | null;
|
|
51
66
|
}): Promise<T>;
|
|
52
67
|
/**
|
|
53
68
|
* Runs the lock holder callback and releases the lock from its owning connection.
|
|
54
69
|
* @template T
|
|
55
|
-
* @param {{callback: () => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
70
|
+
* @param {{callback: (args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
56
71
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
57
72
|
*/
|
|
58
73
|
runLockedCallback<T>({ callback, connection, holdTimeoutMs, name }: {
|
|
59
|
-
callback: (
|
|
74
|
+
callback: (args?: {
|
|
75
|
+
control: import("awaitery/build/timeout.js").TimeoutControl;
|
|
76
|
+
}) => Promise<T>;
|
|
60
77
|
connection: import("./drivers/base.js").default;
|
|
61
78
|
holdTimeoutMs?: number | null;
|
|
62
79
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"AAoDA;;;GAGG;AACH;
|
|
1
|
+
{"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"AAoDA;;;GAGG;AACH;IA2GE;;;;;;;;;;;;;OAaG;IACH,sCANa,CAAC,QACH,MAAM,YACN,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAAC,kBACpF,MAAM,GAAG,IAAI,GACX,OAAO,CAAC,CAAC,CAAC,CAwBtB;IA9ID;;;OAGG;IACH,uEAFW;QAAC,aAAa,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAC,EAM3J;IAHC,qDAAkC;IAClC,0BAJ0F,OAAO,mBAAmB,EAAE,OAAO,CAIjF;IAC5C,2BAA4C;IAG9C;;;;;;;;;;OAUG;IACH,iBANa,CAAC,QACH,MAAM,YACN,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAAC,SACpF;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,GACxD,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;;;;;OASG;IACH,uBANa,CAAC,QACH,MAAM,YACN,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAAC,SACpF;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,GAC7B,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;OAKG;IACH,kBAJa,CAAC,iDACH;QAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;YAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;SAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAC5L,OAAO,CAAC,CAAC,CAAC,CAQtB;IAED;;;;;;;OAOG;IACH,mBALa,CAAC,iBACH,MAAM,GAAG,IAAI,GAAG,SAAS,YACzB,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7D,OAAO,CAAC,CAAC,CAAC,CAQtB;IAED;;;;;;OAMG;IACH,wBAJa,CAAC,YACH,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7D,OAAO,CAAC,CAAC,CAAC,CActB;CAuCF;AApLD;;GAEG;AACH;IACE;;;;OAIG;IACH,qBAHW,MAAM,YACN;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,EAMxB;IADC,iBAAoB;CAEvB;AAED;;GAEG;AACH;IACE;;;;OAIG;IACH,qBAHW,MAAM,YACN;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,EAMxB;IADC,iBAAoB;CAEvB;AA9CD;;GAEG;AACH;IACE;;;;OAIG;IACH,qBAHW,MAAM,YACN;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,EAMxB;IADC,iBAAoB;CAEvB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
import timeout from "awaitery/build/timeout.js";
|
|
2
|
+
import timeout, { TimeoutError } from "awaitery/build/timeout.js";
|
|
3
3
|
/**
|
|
4
4
|
* Thrown when an advisory lock could not be acquired before `timeoutMs` elapsed.
|
|
5
5
|
*/
|
|
@@ -61,9 +61,12 @@ export default class AdvisoryLockRunner {
|
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
63
|
* Runs a callback after acquiring the advisory lock, waiting up to `timeoutMs`.
|
|
64
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
65
|
+
* awaitery for cooperative cancellation (`control.check()`, `control.signal`,
|
|
66
|
+
* `control.timedOut`, `control.remaining()`).
|
|
64
67
|
* @template T
|
|
65
68
|
* @param {string} name - Lock name.
|
|
66
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
69
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
67
70
|
* @param {{timeoutMs?: number | null, holdTimeoutMs?: number | null}} [args] - Lock and hold timeout options.
|
|
68
71
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
69
72
|
*/
|
|
@@ -78,9 +81,11 @@ export default class AdvisoryLockRunner {
|
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
80
83
|
* Runs a callback only if the advisory lock can be acquired immediately.
|
|
84
|
+
* When a `holdTimeoutMs` is set the callback receives a `TimeoutControl` from
|
|
85
|
+
* awaitery for cooperative cancellation.
|
|
81
86
|
* @template T
|
|
82
87
|
* @param {string} name - Lock name.
|
|
83
|
-
* @param {() => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
88
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
84
89
|
* @param {{holdTimeoutMs?: number | null}} [args] - Hold timeout options.
|
|
85
90
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
86
91
|
*/
|
|
@@ -96,7 +101,7 @@ export default class AdvisoryLockRunner {
|
|
|
96
101
|
/**
|
|
97
102
|
* Runs the lock holder callback and releases the lock from its owning connection.
|
|
98
103
|
* @template T
|
|
99
|
-
* @param {{callback: () => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
104
|
+
* @param {{callback: (args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>, connection: import("./drivers/base.js").default, holdTimeoutMs?: number | null, name: string}} args - Locked callback args.
|
|
100
105
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
101
106
|
*/
|
|
102
107
|
async runLockedCallback({ callback, connection, holdTimeoutMs, name }) {
|
|
@@ -146,9 +151,13 @@ export default class AdvisoryLockRunner {
|
|
|
146
151
|
* Runs `callback`, rejecting with `AdvisoryLockHoldTimeoutError` if it has
|
|
147
152
|
* not settled within `holdTimeoutMs`. The callback is not cancelled; callers
|
|
148
153
|
* use a dedicated advisory-lock connection so the lock can still be released.
|
|
154
|
+
*
|
|
155
|
+
* The callback receives a `TimeoutControl` from awaitery, enabling cooperative
|
|
156
|
+
* cancellation via `control.check()`, `control.signal`, `control.timedOut`,
|
|
157
|
+
* and `control.remaining()`.
|
|
149
158
|
* @template T
|
|
150
159
|
* @param {string} name - Lock name (for the error message).
|
|
151
|
-
* @param {() => Promise<T>} callback - Callback holding the lock.
|
|
160
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback holding the lock.
|
|
152
161
|
* @param {number | null} [holdTimeoutMs] - Max hold time; falsy disables the timeout.
|
|
153
162
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
154
163
|
*/
|
|
@@ -158,9 +167,9 @@ export default class AdvisoryLockRunner {
|
|
|
158
167
|
}
|
|
159
168
|
let callbackSettled = false;
|
|
160
169
|
try {
|
|
161
|
-
return await timeout({ timeout: holdTimeoutMs }, async () => {
|
|
170
|
+
return await timeout({ timeout: holdTimeoutMs }, async ({ control }) => {
|
|
162
171
|
try {
|
|
163
|
-
return await callback();
|
|
172
|
+
return await callback({ control });
|
|
164
173
|
}
|
|
165
174
|
finally {
|
|
166
175
|
callbackSettled = true;
|
|
@@ -168,7 +177,7 @@ export default class AdvisoryLockRunner {
|
|
|
168
177
|
});
|
|
169
178
|
}
|
|
170
179
|
catch (error) {
|
|
171
|
-
if (!callbackSettled) {
|
|
180
|
+
if (!callbackSettled || error instanceof TimeoutError) {
|
|
172
181
|
throw new AdvisoryLockHoldTimeoutError(`Advisory lock ${JSON.stringify(name)} held longer than ${holdTimeoutMs}ms`, { name });
|
|
173
182
|
}
|
|
174
183
|
throw error;
|
|
@@ -176,4 +185,4 @@ export default class AdvisoryLockRunner {
|
|
|
176
185
|
}
|
|
177
186
|
}
|
|
178
187
|
export { AdvisoryLockBusyError, AdvisoryLockHoldTimeoutError, AdvisoryLockTimeoutError };
|
|
179
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxNQUFNLDJCQUEyQixDQUFBO0FBRS9DOztHQUVHO0FBQ0gsTUFBTSx3QkFBeUIsU0FBUSxLQUFLO0lBQzFDOzs7O09BSUc7SUFDSCxZQUFZLE9BQU8sRUFBRSxFQUFDLElBQUksRUFBQztRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsSUFBSSxHQUFHLDBCQUEwQixDQUFBO1FBQ3RDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFBO0lBQ3RCLENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxxQkFBc0IsU0FBUSxLQUFLO0lBQ3ZDOzs7O09BSUc7SUFDSCxZQUFZLE9BQU8sRUFBRSxFQUFDLElBQUksRUFBQztRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsSUFBSSxHQUFHLHVCQUF1QixDQUFBO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFBO0lBQ3RCLENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSw0QkFBNkIsU0FBUSxLQUFLO0lBQzlDOzs7O09BSUc7SUFDSCxZQUFZLE9BQU8sRUFBRSxFQUFDLElBQUksRUFBQztRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsSUFBSSxHQUFHLDhCQUE4QixDQUFBO1FBQzFDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFBO0lBQ3RCLENBQUM7Q0FDRjtBQUVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sa0JBQWtCO0lBQ3JDOzs7T0FHRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUUsa0JBQWtCLEVB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QTtRQUNiLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsNEJBQTRCLEVBQUUsd0JBQXdCLEVBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgdGltZW91dCBmcm9tIFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiXG5cbi8qKlxuICogVGhyb3duIHdoZW4gYW4gYWR2aXNvcnkgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgYmVmb3JlIGB0aW1lb3V0TXNgIGVsYXBzZWQuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgdGhhdCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrVGltZW91dEVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZpbmRzIHRoZSBsb2NrIGFscmVhZHkgaGVsZC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrQnVzeUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB0aGF0IHdhcyBhbHJlYWR5IGhlbGQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrQnVzeUVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYSBjYWxsYmFjayBob2xkcyBhbiBhZHZpc29yeSBsb2NrIGxvbmdlciB0aGFuIGBob2xkVGltZW91dE1zYC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgd2hvc2UgaG9sZCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnMgYWR2aXNvcnkgbG9ja3Mgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIGJ5IGRlZmF1bHQsIHVzaW5nIGEgZGVkaWNhdGVkXG4gKiBsb2NrIGNvbm5lY3Rpb24gb25seSB3aGVuIGEgcG9zaXRpdmUgaG9sZCB0aW1lb3V0IG5lZWRzIHNlcGFyYXRlIG93bmVyc2hpcC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWR2aXNvcnlMb2NrUnVubmVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWR2aXNvcnktbG9jayBydW5uZXIgZm9yIG9uZSBtb2RlbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3tjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIGNvbm5lY3Rpb25Qcm92aWRlcjogKCkgPT4gaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmd9fSBhcmdzIC0gUnVubmVyIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBjb25uZWN0aW9uUHJvdmlkZXIsIGRhdGFiYXNlSWRlbnRpZmllcn0pIHtcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5jb25uZWN0aW9uUHJvdmlkZXIgPSBjb25uZWN0aW9uUHJvdmlkZXJcbiAgICB0aGlzLmRhdGFiYXNlSWRlbnRpZmllciA9IGRhdGFiYXNlSWRlbnRpZmllclxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBhZnRlciBhY3F1aXJpbmcgdGhlIGFkdmlzb3J5IGxvY2ssIHdhaXRpbmcgdXAgdG8gYHRpbWVvdXRNc2AuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e3RpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfX0gW2FyZ3NdIC0gTG9jayBhbmQgaG9sZCB0aW1lb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhBZHZpc29yeUxvY2sobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLmhvbGRUaW1lb3V0TXMsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGNvbm5lY3Rpb24uYWNxdWlyZUFkdmlzb3J5TG9jayhuYW1lLCBhcmdzKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3IoYFRpbWVkIG91dCB3YWl0aW5nIGZvciBhZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9YCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGNvbm5lY3Rpb24sIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbmFtZX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgb25seSBpZiB0aGUgYWR2aXNvcnkgbG9jayBjYW4gYmUgYWNxdWlyZWQgaW1tZWRpYXRlbHkuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e2hvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfX0gW2FyZ3NdIC0gSG9sZCB0aW1lb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhBZHZpc29yeUxvY2tPckZhaWwobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLmhvbGRUaW1lb3V0TXMsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGNvbm5lY3Rpb24udHJ5QWNxdWlyZUFkdmlzb3J5TG9jayhuYW1lKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tCdXN5RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaXMgYWxyZWFkeSBoZWxkYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGNvbm5lY3Rpb24sIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbmFtZX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRoZSBsb2NrIGhvbGRlciBjYWxsYmFjayBhbmQgcmVsZWFzZXMgdGhlIGxvY2sgZnJvbSBpdHMgb3duaW5nIGNvbm5lY3Rpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7e2NhbGxiYWNrOiAoKSA9PiBQcm9taXNlPFQ+LCBjb25uZWN0aW9uOiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgbmFtZTogc3RyaW5nfX0gYXJncyAtIExvY2tlZCBjYWxsYmFjayBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyBydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGNvbm5lY3Rpb24sIGhvbGRUaW1lb3V0TXMsIG5hbWV9KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBBZHZpc29yeUxvY2tSdW5uZXIucnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0KG5hbWUsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zKVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnJlbGVhc2VBZHZpc29yeUxvY2sobmFtZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2NrIHdvcmsgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIHVubGVzcyBhIHBvc2l0aXZlIGhvbGQgdGltZW91dCBuZWVkc1xuICAgKiBpdHMgb3duIGxvY2sgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkfSBob2xkVGltZW91dE1zIC0gTWF4IGhvbGQgdGltZTsgcG9zaXRpdmUgdmFsdWVzIHVzZSBhIGRlZGljYXRlZCBsb2NrIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgcmVjZWl2aW5nIHRoZSBjb25uZWN0aW9uIHRoYXQgb3ducyB0aGUgYWR2aXNvcnkgbG9jay5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aExvY2tDb25uZWN0aW9uKGhvbGRUaW1lb3V0TXMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGhvbGRUaW1lb3V0TXMgJiYgaG9sZFRpbWVvdXRNcyA+IDApIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhEZWRpY2F0ZWRDb25uZWN0aW9uKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh0aGlzLmNvbm5lY3Rpb25Qcm92aWRlcigpKVxuICB9XG5cbiAgLyoqXG4gICAqIFNwYXducyBhIGhvbGQtdGltZW91dCBsb2NrIGNvbm5lY3Rpb24gYW5kIGNsb3NlcyBpdCBhZnRlciBsb2NrIHdvcmsgY29tcGxldGVzIHdoZW5cbiAgICogdGhlIHNwYXduZWQgZHJpdmVyIG93bnMgdGhlIHVuZGVybHlpbmcgcGh5c2ljYWwgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0aGF0IHJlY2VpdmVzIHRoZSBkZWRpY2F0ZWQgbG9jayBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoRGVkaWNhdGVkQ29ubmVjdGlvbihjYWxsYmFjaykge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VQb29sKHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyKS5zcGF3bkNvbm5lY3Rpb24oKVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayhjb25uZWN0aW9uKVxuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoY29ubmVjdGlvbi5nZXRBcmdzKCkuZ2V0Q29ubmVjdGlvbikge1xuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLnJlbGVhc2VIZWxkQWR2aXNvcnlMb2NrcygpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLmNsb3NlKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBgY2FsbGJhY2tgLCByZWplY3Rpbmcgd2l0aCBgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvcmAgaWYgaXQgaGFzXG4gICAqIG5vdCBzZXR0bGVkIHdpdGhpbiBgaG9sZFRpbWVvdXRNc2AuIFRoZSBjYWxsYmFjayBpcyBub3QgY2FuY2VsbGVkOyBjYWxsZXJzXG4gICAqIHVzZSBhIGRlZGljYXRlZCBhZHZpc29yeS1sb2NrIGNvbm5lY3Rpb24gc28gdGhlIGxvY2sgY2FuIHN0aWxsIGJlIHJlbGVhc2VkLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZSAoZm9yIHRoZSBlcnJvciBtZXNzYWdlKS5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIGhvbGRpbmcgdGhlIGxvY2suXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgbnVsbH0gW2hvbGRUaW1lb3V0TXNdIC0gTWF4IGhvbGQgdGltZTsgZmFsc3kgZGlzYWJsZXMgdGhlIHRpbWVvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBydW5XaXRoQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXQobmFtZSwgY2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMpIHtcbiAgICBpZiAoIWhvbGRUaW1lb3V0TXMgfHwgaG9sZFRpbWVvdXRNcyA8PSAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soKVxuICAgIH1cblxuICAgIGxldCBjYWxsYmFja1NldHRsZWQgPSBmYWxzZVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aW1lb3V0KHt0aW1lb3V0OiBob2xkVGltZW91dE1zfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjaygpXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY2FsbGJhY2tTZXR0bGVkID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoIWNhbGxiYWNrU2V0dGxlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvcihgQWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBoZWxkIGxvbmdlciB0aGFuICR7aG9sZFRpbWVvdXRNc31tc2AsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHtBZHZpc29yeUxvY2tCdXN5RXJyb3IsIEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3IsIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvcn1cbiJdfQ==
|
|
188
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFFL0Q7O0dBRUc7QUFDSCxNQUFNLHdCQUF5QixTQUFRLEtBQUs7SUFDMUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsMEJBQTBCLENBQUE7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLHFCQUFzQixTQUFRLEtBQUs7SUFDdkM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsdUJBQXVCLENBQUE7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLDRCQUE2QixTQUFRLEtBQUs7SUFDOUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsOEJBQThCLENBQUE7UUFDMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxrQkFBa0I7SUFDckM7OztPQUdHO0lBQ0gsWUFBWSxFQUFD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QUMsSUFBSSxDQUFDLHFCQUFxQixhQUFhLElBQUksRUFBRSxFQUFDLElBQUksRUFBQyxDQUFDLENBQUE7WUFDN0gsQ0FBQztZQUVELE1BQU0sS0FBSyxDQUFBO1FBQ2IsQ0FBQztJQUNILENBQUM7Q0FDRjtBQUVELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSw0QkFBNEIsRUFBRSx3QkFBd0IsRUFBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB0aW1lb3V0LCB7VGltZW91dEVycm9yfSBmcm9tIFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiXG5cbi8qKlxuICogVGhyb3duIHdoZW4gYW4gYWR2aXNvcnkgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgYmVmb3JlIGB0aW1lb3V0TXNgIGVsYXBzZWQuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgdGhhdCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrVGltZW91dEVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZpbmRzIHRoZSBsb2NrIGFscmVhZHkgaGVsZC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrQnVzeUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB0aGF0IHdhcyBhbHJlYWR5IGhlbGQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrQnVzeUVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYSBjYWxsYmFjayBob2xkcyBhbiBhZHZpc29yeSBsb2NrIGxvbmdlciB0aGFuIGBob2xkVGltZW91dE1zYC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgd2hvc2UgaG9sZCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnMgYWR2aXNvcnkgbG9ja3Mgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIGJ5IGRlZmF1bHQsIHVzaW5nIGEgZGVkaWNhdGVkXG4gKiBsb2NrIGNvbm5lY3Rpb24gb25seSB3aGVuIGEgcG9zaXRpdmUgaG9sZCB0aW1lb3V0IG5lZWRzIHNlcGFyYXRlIG93bmVyc2hpcC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWR2aXNvcnlMb2NrUnVubmVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWR2aXNvcnktbG9jayBydW5uZXIgZm9yIG9uZSBtb2RlbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3tjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIGNvbm5lY3Rpb25Qcm92aWRlcjogKCkgPT4gaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmd9fSBhcmdzIC0gUnVubmVyIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBjb25uZWN0aW9uUHJvdmlkZXIsIGRhdGFiYXNlSWRlbnRpZmllcn0pIHtcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5jb25uZWN0aW9uUHJvdmlkZXIgPSBjb25uZWN0aW9uUHJvdmlkZXJcbiAgICB0aGlzLmRhdGFiYXNlSWRlbnRpZmllciA9IGRhdGFiYXNlSWRlbnRpZmllclxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBhZnRlciBhY3F1aXJpbmcgdGhlIGFkdmlzb3J5IGxvY2ssIHdhaXRpbmcgdXAgdG8gYHRpbWVvdXRNc2AuXG4gICAqIFdoZW4gYSBgaG9sZFRpbWVvdXRNc2AgaXMgc2V0IHRoZSBjYWxsYmFjayByZWNlaXZlcyBhIGBUaW1lb3V0Q29udHJvbGAgZnJvbVxuICAgKiBhd2FpdGVyeSBmb3IgY29vcGVyYXRpdmUgY2FuY2VsbGF0aW9uIChgY29udHJvbC5jaGVjaygpYCwgYGNvbnRyb2wuc2lnbmFsYCxcbiAgICogYGNvbnRyb2wudGltZWRPdXRgLCBgY29udHJvbC5yZW1haW5pbmcoKWApLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHBhcmFtIHsoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBpbnZva2Ugd2hpbGUgdGhlIGxvY2sgaXMgaGVsZC5cbiAgICogQHBhcmFtIHt7dGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGx9fSBbYXJnc10gLSBMb2NrIGFuZCBob2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9jayhuYW1lLCBjYWxsYmFjaywgYXJncyA9IHt9KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MuaG9sZFRpbWVvdXRNcywgYXN5bmMgKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgY29ubmVjdGlvbi5hY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUsIGFyZ3MpXG5cbiAgICAgIGlmICghYWNxdWlyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvcihgVGltZWQgb3V0IHdhaXRpbmcgZm9yIGFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX1gLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgY29ubmVjdGlvbiwgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBuYW1lfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBvbmx5IGlmIHRoZSBhZHZpc29yeSBsb2NrIGNhbiBiZSBhY3F1aXJlZCBpbW1lZGlhdGVseS5cbiAgICogV2hlbiBhIGBob2xkVGltZW91dE1zYCBpcyBzZXQgdGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tXG4gICAqIGF3YWl0ZXJ5IGZvciBjb29wZXJhdGl2ZSBjYW5jZWxsYXRpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w6IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2x9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3tob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbH19IFthcmdzXSAtIEhvbGQgdGltZW91dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQWR2aXNvcnlMb2NrT3JGYWlsKG5hbWUsIGNhbGxiYWNrLCBhcmdzID0ge30pIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy53aXRoTG9ja0Nvbm5lY3Rpb24oYXJncy5ob2xkVGltZW91dE1zLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLnRyeUFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrQnVzeUVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGlzIGFscmVhZHkgaGVsZGAsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBjb25uZWN0aW9uLCBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsIG5hbWV9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgbG9jayBob2xkZXIgY2FsbGJhY2sgYW5kIHJlbGVhc2VzIHRoZSBsb2NrIGZyb20gaXRzIG93bmluZyBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tjYWxsYmFjazogKGFyZ3M/OiB7Y29udHJvbDogaW1wb3J0KFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiKS5UaW1lb3V0Q29udHJvbH0pID0+IFByb21pc2U8VD4sIGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBuYW1lOiBzdHJpbmd9fSBhcmdzIC0gTG9ja2VkIGNhbGxiYWNrIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgY29ubmVjdGlvbiwgaG9sZFRpbWVvdXRNcywgbmFtZX0pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IEFkdmlzb3J5TG9ja1J1bm5lci5ydW5XaXRoQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXQobmFtZSwgY2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUFkdmlzb3J5TG9jayhuYW1lKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGxvY2sgd29yayBvbiB0aGUgY2FsbGVyIGNvbm5lY3Rpb24gdW5sZXNzIGEgcG9zaXRpdmUgaG9sZCB0aW1lb3V0IG5lZWRzXG4gICAqIGl0cyBvd24gbG9jayBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge251bWJlciB8IG51bGwgfCB1bmRlZmluZWR9IGhvbGRUaW1lb3V0TXMgLSBNYXggaG9sZCB0aW1lOyBwb3NpdGl2ZSB2YWx1ZXMgdXNlIGEgZGVkaWNhdGVkIGxvY2sgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayByZWNlaXZpbmcgdGhlIGNvbm5lY3Rpb24gdGhhdCBvd25zIHRoZSBhZHZpc29yeSBsb2NrLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoTG9ja0Nvbm5lY3Rpb24oaG9sZFRpbWVvdXRNcywgY2FsbGJhY2spIHtcbiAgICBpZiAoaG9sZFRpbWVvdXRNcyAmJiBob2xkVGltZW91dE1zID4gMCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aERlZGljYXRlZENvbm5lY3Rpb24oY2FsbGJhY2spXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKHRoaXMuY29ubmVjdGlvblByb3ZpZGVyKCkpXG4gIH1cblxuICAvKipcbiAgICogU3Bhd25zIGEgaG9sZC10aW1lb3V0IGxvY2sgY29ubmVjdGlvbiBhbmQgY2xvc2VzIGl0IGFmdGVyIGxvY2sgd29yayBjb21wbGV0ZXMgd2hlblxuICAgKiB0aGUgc3Bhd25lZCBkcml2ZXIgb3ducyB0aGUgdW5kZXJseWluZyBwaHlzaWNhbCBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0geyhjb25uZWN0aW9uOiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGRlZGljYXRlZCBsb2NrIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhEZWRpY2F0ZWRDb25uZWN0aW9uKGNhbGxiYWNrKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2wodGhpcy5kYXRhYmFzZUlkZW50aWZpZXIpLnNwYXduQ29ubmVjdGlvbigpXG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKGNvbm5lY3Rpb24pXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChjb25uZWN0aW9uLmdldEFyZ3MoKS5nZXRDb25uZWN0aW9uKSB7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUhlbGRBZHZpc29yeUxvY2tzKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24uY2xvc2UoKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBjYWxsYmFja2AsIHJlamVjdGluZyB3aXRoIGBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yYCBpZiBpdCBoYXNcbiAgICogbm90IHNldHRsZWQgd2l0aGluIGBob2xkVGltZW91dE1zYC4gVGhlIGNhbGxiYWNrIGlzIG5vdCBjYW5jZWxsZWQ7IGNhbGxlcnNcbiAgICogdXNlIGEgZGVkaWNhdGVkIGFkdmlzb3J5LWxvY2sgY29ubmVjdGlvbiBzbyB0aGUgbG9jayBjYW4gc3RpbGwgYmUgcmVsZWFzZWQuXG4gICAqXG4gICAqIFRoZSBjYWxsYmFjayByZWNlaXZlcyBhIGBUaW1lb3V0Q29udHJvbGAgZnJvbSBhd2FpdGVyeSwgZW5hYmxpbmcgY29vcGVyYXRpdmVcbiAgICogY2FuY2VsbGF0aW9uIHZpYSBgY29udHJvbC5jaGVjaygpYCwgYGNvbnRyb2wuc2lnbmFsYCwgYGNvbnRyb2wudGltZWRPdXRgLFxuICAgKiBhbmQgYGNvbnRyb2wucmVtYWluaW5nKClgLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZSAoZm9yIHRoZSBlcnJvciBtZXNzYWdlKS5cbiAgICogQHBhcmFtIHsoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayBob2xkaW5nIHRoZSBsb2NrLlxuICAgKiBAcGFyYW0ge251bWJlciB8IG51bGx9IFtob2xkVGltZW91dE1zXSAtIE1heCBob2xkIHRpbWU7IGZhbHN5IGRpc2FibGVzIHRoZSB0aW1lb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0KG5hbWUsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zKSB7XG4gICAgaWYgKCFob2xkVGltZW91dE1zIHx8IGhvbGRUaW1lb3V0TXMgPD0gMCkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICBsZXQgY2FsbGJhY2tTZXR0bGVkID0gZmFsc2VcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGltZW91dCh7dGltZW91dDogaG9sZFRpbWVvdXRNc30sIGFzeW5jICh7Y29udHJvbH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soe2NvbnRyb2x9KVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGNhbGxiYWNrU2V0dGxlZCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKCFjYWxsYmFja1NldHRsZWQgfHwgZXJyb3IgaW5zdGFuY2VvZiBUaW1lb3V0RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaGVsZCBsb25nZXIgdGhhbiAke2hvbGRUaW1lb3V0TXN9bXNgLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB7QWR2aXNvcnlMb2NrQnVzeUVycm9yLCBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yLCBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3J9XG4iXX0=
|
|
@@ -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
|