@breeztech/breez-sdk-spark 0.14.0 → 0.15.1
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/breez-sdk-spark.tgz +0 -0
- package/bundler/breez_sdk_spark_wasm.d.ts +114 -40
- package/bundler/breez_sdk_spark_wasm.js +1 -1
- package/bundler/breez_sdk_spark_wasm_bg.js +118 -104
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/deno/breez_sdk_spark_wasm.d.ts +114 -40
- package/deno/breez_sdk_spark_wasm.js +118 -104
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/nodejs/breez_sdk_spark_wasm.d.ts +114 -40
- package/nodejs/breez_sdk_spark_wasm.js +121 -106
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/nodejs/index.mjs +3 -2
- package/nodejs/mysql-session-manager/index.cjs +26 -8
- package/nodejs/mysql-session-manager/migrations.cjs +40 -3
- package/nodejs/mysql-storage/index.cjs +67 -48
- package/nodejs/mysql-storage/migrations.cjs +220 -85
- package/nodejs/mysql-token-store/index.cjs +133 -68
- package/nodejs/mysql-token-store/migrations.cjs +309 -80
- package/nodejs/mysql-tree-store/index.cjs +76 -41
- package/nodejs/mysql-tree-store/migrations.cjs +254 -71
- package/nodejs/postgres-session-manager/index.cjs +27 -9
- package/nodejs/postgres-session-manager/migrations.cjs +45 -6
- package/nodejs/postgres-storage/index.cjs +81 -62
- package/nodejs/postgres-storage/migrations.cjs +207 -79
- package/nodejs/postgres-token-store/index.cjs +111 -67
- package/nodejs/postgres-token-store/migrations.cjs +153 -61
- package/nodejs/postgres-tree-store/index.cjs +60 -42
- package/nodejs/postgres-tree-store/migrations.cjs +130 -46
- package/package.json +1 -1
- package/ssr/index.js +14 -9
- package/web/breez_sdk_spark_wasm.d.ts +126 -51
- package/web/breez_sdk_spark_wasm.js +118 -104
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
const { TokenStoreError } = require("./errors.cjs");
|
|
6
6
|
|
|
7
|
-
const TOKEN_MIGRATIONS_TABLE = "
|
|
7
|
+
const TOKEN_MIGRATIONS_TABLE = "brz_token_schema_migrations";
|
|
8
8
|
const MIGRATION_LOCK_NAME = "breez_mysql_token_store_migration_lock";
|
|
9
9
|
const MIGRATION_LOCK_TIMEOUT = 60;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Runs a single migration step. Plain strings are run as-is; tagged objects
|
|
13
|
-
* (`{ op: 'dropPrimaryKey', table }`
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* (`{ op: 'dropPrimaryKey', table }`, `{ op: 'dropForeignKey', table, name }`)
|
|
14
|
+
* are guarded against partial-apply replay (and against the `Disabled`
|
|
15
|
+
* foreign-key mode where the FK was never created) by checking
|
|
16
|
+
* `information_schema` first. MySQL DDL implicitly commits, so if the
|
|
17
|
+
* migration crashes between two DDL statements the version row never gets
|
|
18
|
+
* recorded — and on retry, an unguarded DROP would fail because the
|
|
19
|
+
* constraint is already gone.
|
|
18
20
|
*/
|
|
19
21
|
async function runMigrationStep(conn, step) {
|
|
20
22
|
if (typeof step === "string") {
|
|
@@ -34,12 +36,45 @@ async function runMigrationStep(conn, step) {
|
|
|
34
36
|
}
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
39
|
+
if (step.op === "dropForeignKey") {
|
|
40
|
+
const [rows] = await conn.query(
|
|
41
|
+
`SELECT COUNT(*) AS c FROM information_schema.table_constraints
|
|
42
|
+
WHERE table_schema = DATABASE()
|
|
43
|
+
AND table_name = ?
|
|
44
|
+
AND constraint_type = 'FOREIGN KEY'
|
|
45
|
+
AND constraint_name = ?`,
|
|
46
|
+
[step.table, step.name]
|
|
47
|
+
);
|
|
48
|
+
if (rows[0].c > 0) {
|
|
49
|
+
await conn.query(
|
|
50
|
+
`ALTER TABLE \`${step.table}\` DROP FOREIGN KEY \`${step.name}\``
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (step.op === "addForeignKey") {
|
|
56
|
+
const [rows] = await conn.query(
|
|
57
|
+
`SELECT COUNT(*) AS c FROM information_schema.table_constraints
|
|
58
|
+
WHERE table_schema = DATABASE()
|
|
59
|
+
AND table_name = ?
|
|
60
|
+
AND constraint_type = 'FOREIGN KEY'
|
|
61
|
+
AND constraint_name = ?`,
|
|
62
|
+
[step.table, step.name]
|
|
63
|
+
);
|
|
64
|
+
if (rows[0].c === 0) {
|
|
65
|
+
await conn.query(
|
|
66
|
+
`ALTER TABLE \`${step.table}\` ADD CONSTRAINT \`${step.name}\` ${step.definition}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
37
71
|
throw new Error(`Unknown migration step op: ${JSON.stringify(step)}`);
|
|
38
72
|
}
|
|
39
73
|
|
|
40
74
|
class MysqlTokenStoreMigrationManager {
|
|
41
|
-
constructor(logger = null) {
|
|
75
|
+
constructor(logger = null, foreignKeyMode = "Enforced") {
|
|
42
76
|
this.logger = logger;
|
|
77
|
+
this.foreignKeyMode = foreignKeyMode;
|
|
43
78
|
}
|
|
44
79
|
|
|
45
80
|
/**
|
|
@@ -67,6 +102,8 @@ class MysqlTokenStoreMigrationManager {
|
|
|
67
102
|
}
|
|
68
103
|
|
|
69
104
|
try {
|
|
105
|
+
await this._applySchemaRenames(conn);
|
|
106
|
+
|
|
70
107
|
await conn.query("START TRANSACTION");
|
|
71
108
|
|
|
72
109
|
await conn.query(`
|
|
@@ -123,15 +160,139 @@ class MysqlTokenStoreMigrationManager {
|
|
|
123
160
|
* the bytes come from a typed secp256k1 pubkey (`[0-9a-f]{66}` after hex
|
|
124
161
|
* encoding) — not user-controlled input.
|
|
125
162
|
*/
|
|
163
|
+
/**
|
|
164
|
+
* Pre-prefix rename. Canary-gated on the legacy `token_schema_migrations`
|
|
165
|
+
* table.
|
|
166
|
+
* @param {import('mysql2/promise').PoolConnection} conn
|
|
167
|
+
*/
|
|
168
|
+
async _applySchemaRenames(conn) {
|
|
169
|
+
if (!(await _mysqlTableExists(conn, "token_schema_migrations"))) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const tableRenames = [
|
|
174
|
+
["token_metadata", "brz_token_metadata"],
|
|
175
|
+
["token_reservations", "brz_token_reservations"],
|
|
176
|
+
["token_outputs", "brz_token_outputs"],
|
|
177
|
+
["token_spent_outputs", "brz_token_spent_outputs"],
|
|
178
|
+
["token_swap_status", "brz_token_swap_status"],
|
|
179
|
+
];
|
|
180
|
+
for (const [oldName, newName] of tableRenames) {
|
|
181
|
+
if (
|
|
182
|
+
(await _mysqlTableExists(conn, oldName)) &&
|
|
183
|
+
!(await _mysqlTableExists(conn, newName))
|
|
184
|
+
) {
|
|
185
|
+
await conn.query(`RENAME TABLE \`${oldName}\` TO \`${newName}\``);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const indexRenames = [
|
|
190
|
+
[
|
|
191
|
+
"brz_token_metadata",
|
|
192
|
+
"idx_token_metadata_user_issuer_pk",
|
|
193
|
+
"brz_idx_token_metadata_user_issuer_pk",
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"brz_token_outputs",
|
|
197
|
+
"idx_token_outputs_user_identifier",
|
|
198
|
+
"brz_idx_token_outputs_user_identifier",
|
|
199
|
+
],
|
|
200
|
+
[
|
|
201
|
+
"brz_token_outputs",
|
|
202
|
+
"idx_token_outputs_user_reservation",
|
|
203
|
+
"brz_idx_token_outputs_user_reservation",
|
|
204
|
+
],
|
|
205
|
+
// Pre-multi-tenant indexes (dropped by the multi-tenant migration).
|
|
206
|
+
[
|
|
207
|
+
"brz_token_metadata",
|
|
208
|
+
"idx_token_metadata_issuer_pk",
|
|
209
|
+
"brz_idx_token_metadata_issuer_pk",
|
|
210
|
+
],
|
|
211
|
+
[
|
|
212
|
+
"brz_token_outputs",
|
|
213
|
+
"idx_token_outputs_identifier",
|
|
214
|
+
"brz_idx_token_outputs_identifier",
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
"brz_token_outputs",
|
|
218
|
+
"idx_token_outputs_reservation",
|
|
219
|
+
"brz_idx_token_outputs_reservation",
|
|
220
|
+
],
|
|
221
|
+
];
|
|
222
|
+
for (const [table, oldName, newName] of indexRenames) {
|
|
223
|
+
if (
|
|
224
|
+
(await _mysqlIndexExists(conn, table, oldName)) &&
|
|
225
|
+
!(await _mysqlIndexExists(conn, table, newName))
|
|
226
|
+
) {
|
|
227
|
+
await conn.query(
|
|
228
|
+
`ALTER TABLE \`${table}\` RENAME INDEX \`${oldName}\` TO \`${newName}\``
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const fkRenames = [
|
|
234
|
+
{
|
|
235
|
+
table: "brz_token_outputs",
|
|
236
|
+
oldName: "fk_token_outputs_metadata_user",
|
|
237
|
+
newName: "brz_fk_token_outputs_metadata_user",
|
|
238
|
+
definition:
|
|
239
|
+
"FOREIGN KEY (user_id, token_identifier) REFERENCES `brz_token_metadata`(user_id, identifier)",
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
table: "brz_token_outputs",
|
|
243
|
+
oldName: "fk_token_outputs_reservation_user",
|
|
244
|
+
newName: "brz_fk_token_outputs_reservation_user",
|
|
245
|
+
definition:
|
|
246
|
+
"FOREIGN KEY (user_id, reservation_id) REFERENCES `brz_token_reservations`(user_id, id)",
|
|
247
|
+
},
|
|
248
|
+
// Pre-multi-tenant FKs (single-column). Rename so the post-tenant
|
|
249
|
+
// migration's drop-foreign-key steps find them.
|
|
250
|
+
{
|
|
251
|
+
table: "brz_token_outputs",
|
|
252
|
+
oldName: "fk_token_outputs_metadata",
|
|
253
|
+
newName: "brz_fk_token_outputs_metadata",
|
|
254
|
+
definition:
|
|
255
|
+
"FOREIGN KEY (token_identifier) REFERENCES `brz_token_metadata`(identifier)",
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
table: "brz_token_outputs",
|
|
259
|
+
oldName: "fk_token_outputs_reservation",
|
|
260
|
+
newName: "brz_fk_token_outputs_reservation",
|
|
261
|
+
definition:
|
|
262
|
+
"FOREIGN KEY (reservation_id) REFERENCES `brz_token_reservations`(id) ON DELETE SET NULL",
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
for (const fk of fkRenames) {
|
|
266
|
+
if (await _mysqlForeignKeyExists(conn, fk.table, fk.newName)) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (!(await _mysqlForeignKeyExists(conn, fk.table, fk.oldName))) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
await conn.query(
|
|
273
|
+
`ALTER TABLE \`${fk.table}\`` +
|
|
274
|
+
` DROP FOREIGN KEY \`${fk.oldName}\`,` +
|
|
275
|
+
` ADD CONSTRAINT \`${fk.newName}\` ${fk.definition}`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (
|
|
280
|
+
(await _mysqlTableExists(conn, "token_schema_migrations")) &&
|
|
281
|
+
!(await _mysqlTableExists(conn, TOKEN_MIGRATIONS_TABLE))
|
|
282
|
+
) {
|
|
283
|
+
await conn.query(
|
|
284
|
+
`RENAME TABLE \`token_schema_migrations\` TO \`${TOKEN_MIGRATIONS_TABLE}\``
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
126
289
|
_getMigrations(identity) {
|
|
127
290
|
const idHex = Buffer.from(identity).toString("hex");
|
|
128
291
|
const idLit = `UNHEX('${idHex}')`;
|
|
292
|
+
const foreignKeyModeEnforced = this.foreignKeyMode === "Enforced";
|
|
129
293
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
name: "Create token store tables",
|
|
133
|
-
sql: [
|
|
134
|
-
`CREATE TABLE IF NOT EXISTS token_metadata (
|
|
294
|
+
const initialSql = [
|
|
295
|
+
`CREATE TABLE IF NOT EXISTS brz_token_metadata (
|
|
135
296
|
identifier VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
136
297
|
issuer_public_key VARCHAR(255) NOT NULL,
|
|
137
298
|
name VARCHAR(255) NOT NULL,
|
|
@@ -141,14 +302,14 @@ class MysqlTokenStoreMigrationManager {
|
|
|
141
302
|
is_freezable TINYINT(1) NOT NULL,
|
|
142
303
|
creation_entity_public_key VARCHAR(255) NULL
|
|
143
304
|
)`,
|
|
144
|
-
`CREATE INDEX
|
|
145
|
-
ON
|
|
146
|
-
`CREATE TABLE IF NOT EXISTS
|
|
305
|
+
`CREATE INDEX brz_idx_token_metadata_issuer_pk
|
|
306
|
+
ON brz_token_metadata (issuer_public_key)`,
|
|
307
|
+
`CREATE TABLE IF NOT EXISTS brz_token_reservations (
|
|
147
308
|
id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
148
309
|
purpose VARCHAR(64) NOT NULL,
|
|
149
310
|
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
150
311
|
)`,
|
|
151
|
-
`CREATE TABLE IF NOT EXISTS
|
|
312
|
+
`CREATE TABLE IF NOT EXISTS brz_token_outputs (
|
|
152
313
|
id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
153
314
|
token_identifier VARCHAR(255) NOT NULL,
|
|
154
315
|
owner_public_key VARCHAR(255) NOT NULL,
|
|
@@ -160,33 +321,52 @@ class MysqlTokenStoreMigrationManager {
|
|
|
160
321
|
prev_tx_hash VARCHAR(255) NOT NULL,
|
|
161
322
|
prev_tx_vout INT NOT NULL,
|
|
162
323
|
reservation_id VARCHAR(255) NULL,
|
|
163
|
-
added_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
164
|
-
CONSTRAINT fk_token_outputs_metadata FOREIGN KEY (token_identifier)
|
|
165
|
-
REFERENCES token_metadata(identifier),
|
|
166
|
-
CONSTRAINT fk_token_outputs_reservation FOREIGN KEY (reservation_id)
|
|
167
|
-
REFERENCES token_reservations(id) ON DELETE SET NULL
|
|
324
|
+
added_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
168
325
|
)`,
|
|
169
|
-
`CREATE INDEX
|
|
170
|
-
ON
|
|
171
|
-
`CREATE INDEX
|
|
172
|
-
ON
|
|
173
|
-
`CREATE TABLE IF NOT EXISTS
|
|
326
|
+
`CREATE INDEX brz_idx_token_outputs_identifier
|
|
327
|
+
ON brz_token_outputs (token_identifier)`,
|
|
328
|
+
`CREATE INDEX brz_idx_token_outputs_reservation
|
|
329
|
+
ON brz_token_outputs (reservation_id)`,
|
|
330
|
+
`CREATE TABLE IF NOT EXISTS brz_token_spent_outputs (
|
|
174
331
|
output_id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
175
332
|
spent_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
176
333
|
)`,
|
|
177
|
-
`CREATE TABLE IF NOT EXISTS
|
|
334
|
+
`CREATE TABLE IF NOT EXISTS brz_token_swap_status (
|
|
178
335
|
id INT NOT NULL PRIMARY KEY DEFAULT 1,
|
|
179
336
|
last_completed_at DATETIME(6) NULL,
|
|
180
337
|
CHECK (id = 1)
|
|
181
338
|
)`,
|
|
182
|
-
|
|
339
|
+
];
|
|
340
|
+
if (foreignKeyModeEnforced) {
|
|
341
|
+
initialSql.push(
|
|
342
|
+
{
|
|
343
|
+
op: "addForeignKey",
|
|
344
|
+
table: "brz_token_outputs",
|
|
345
|
+
name: "brz_fk_token_outputs_metadata",
|
|
346
|
+
definition: `FOREIGN KEY (token_identifier) REFERENCES brz_token_metadata(identifier)`,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
op: "addForeignKey",
|
|
350
|
+
table: "brz_token_outputs",
|
|
351
|
+
name: "brz_fk_token_outputs_reservation",
|
|
352
|
+
definition: `FOREIGN KEY (reservation_id) REFERENCES brz_token_reservations(id) ON DELETE SET NULL`,
|
|
353
|
+
}
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return [
|
|
358
|
+
{
|
|
359
|
+
name: "Create token store tables",
|
|
360
|
+
sql: [
|
|
361
|
+
...initialSql,
|
|
362
|
+
`INSERT INTO brz_token_swap_status (id) VALUES (1)
|
|
183
363
|
ON DUPLICATE KEY UPDATE id = id`,
|
|
184
364
|
],
|
|
185
365
|
},
|
|
186
366
|
{
|
|
187
367
|
// Mirrors Rust migration 2 in spark-mysql/src/token_store.rs and the
|
|
188
368
|
// postgres equivalent. Adds user_id to every token-store table
|
|
189
|
-
// (including
|
|
369
|
+
// (including brz_token_metadata — per-tenant to avoid 0-balance leakage
|
|
190
370
|
// for tokens a tenant never owned), backfills with the connecting
|
|
191
371
|
// tenant, and rewrites primary keys / FKs / indexes to lead with
|
|
192
372
|
// user_id. Composite FKs use NO ACTION because column-list SET NULL
|
|
@@ -194,62 +374,111 @@ class MysqlTokenStoreMigrationManager {
|
|
|
194
374
|
name: "Multi-tenant scoping: add user_id and rewrite primary keys / FKs",
|
|
195
375
|
sql: [
|
|
196
376
|
// Drop dependent FKs FIRST so we can rewrite the parent PKs.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
`ALTER TABLE
|
|
213
|
-
`
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
`
|
|
217
|
-
`
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
`ALTER TABLE
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
`
|
|
229
|
-
`
|
|
230
|
-
`
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
377
|
+
// Guarded so that databases created with `Disabled` foreign-key mode
|
|
378
|
+
// (where the FKs were never created) skip the DROP rather than
|
|
379
|
+
// erroring.
|
|
380
|
+
{
|
|
381
|
+
op: "dropForeignKey",
|
|
382
|
+
table: "brz_token_outputs",
|
|
383
|
+
name: "brz_fk_token_outputs_metadata",
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
op: "dropForeignKey",
|
|
387
|
+
table: "brz_token_outputs",
|
|
388
|
+
name: "brz_fk_token_outputs_reservation",
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
// brz_token_metadata: per-tenant scoping (privacy — see header).
|
|
392
|
+
`ALTER TABLE brz_token_metadata ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
393
|
+
`UPDATE brz_token_metadata SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
394
|
+
`ALTER TABLE brz_token_metadata MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
395
|
+
`ALTER TABLE brz_token_metadata DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, identifier)`,
|
|
396
|
+
`DROP INDEX brz_idx_token_metadata_issuer_pk ON brz_token_metadata`,
|
|
397
|
+
`CREATE INDEX brz_idx_token_metadata_user_issuer_pk
|
|
398
|
+
ON brz_token_metadata (user_id, issuer_public_key)`,
|
|
399
|
+
|
|
400
|
+
// brz_token_reservations: scope by user_id.
|
|
401
|
+
`ALTER TABLE brz_token_reservations ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
402
|
+
`UPDATE brz_token_reservations SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
403
|
+
`ALTER TABLE brz_token_reservations MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
404
|
+
`ALTER TABLE brz_token_reservations DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, id)`,
|
|
405
|
+
|
|
406
|
+
// brz_token_outputs: scope by user_id, rekey, optionally re-add composite FKs.
|
|
407
|
+
`ALTER TABLE brz_token_outputs ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
408
|
+
`UPDATE brz_token_outputs SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
409
|
+
`ALTER TABLE brz_token_outputs MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
410
|
+
`ALTER TABLE brz_token_outputs DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, id)`,
|
|
411
|
+
...(foreignKeyModeEnforced
|
|
412
|
+
? [
|
|
413
|
+
{
|
|
414
|
+
op: "addForeignKey",
|
|
415
|
+
table: "brz_token_outputs",
|
|
416
|
+
name: "brz_fk_token_outputs_metadata_user",
|
|
417
|
+
definition: `FOREIGN KEY (user_id, token_identifier) REFERENCES brz_token_metadata(user_id, identifier)`,
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
op: "addForeignKey",
|
|
421
|
+
table: "brz_token_outputs",
|
|
422
|
+
name: "brz_fk_token_outputs_reservation_user",
|
|
423
|
+
definition: `FOREIGN KEY (user_id, reservation_id) REFERENCES brz_token_reservations(user_id, id)`,
|
|
424
|
+
},
|
|
425
|
+
]
|
|
426
|
+
: []),
|
|
427
|
+
`DROP INDEX brz_idx_token_outputs_identifier ON brz_token_outputs`,
|
|
428
|
+
`DROP INDEX brz_idx_token_outputs_reservation ON brz_token_outputs`,
|
|
429
|
+
`CREATE INDEX brz_idx_token_outputs_user_identifier
|
|
430
|
+
ON brz_token_outputs (user_id, token_identifier)`,
|
|
431
|
+
`CREATE INDEX brz_idx_token_outputs_user_reservation
|
|
432
|
+
ON brz_token_outputs (user_id, reservation_id)`,
|
|
433
|
+
|
|
434
|
+
// brz_token_spent_outputs: scope by user_id.
|
|
435
|
+
`ALTER TABLE brz_token_spent_outputs ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
436
|
+
`UPDATE brz_token_spent_outputs SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
437
|
+
`ALTER TABLE brz_token_spent_outputs MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
438
|
+
`ALTER TABLE brz_token_spent_outputs DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, output_id)`,
|
|
439
|
+
|
|
440
|
+
// brz_token_swap_status was a singleton (PK id=1, CHECK id=1). Drop the
|
|
242
441
|
// PK and the id column, then re-key by user_id.
|
|
243
|
-
{ op: "dropPrimaryKey", table: "
|
|
244
|
-
`ALTER TABLE
|
|
245
|
-
`ALTER TABLE
|
|
246
|
-
`UPDATE
|
|
247
|
-
`ALTER TABLE
|
|
248
|
-
`ALTER TABLE
|
|
442
|
+
{ op: "dropPrimaryKey", table: "brz_token_swap_status" },
|
|
443
|
+
`ALTER TABLE brz_token_swap_status DROP COLUMN id`,
|
|
444
|
+
`ALTER TABLE brz_token_swap_status ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
445
|
+
`UPDATE brz_token_swap_status SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
446
|
+
`ALTER TABLE brz_token_swap_status MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
447
|
+
`ALTER TABLE brz_token_swap_status ADD PRIMARY KEY (user_id)`,
|
|
249
448
|
],
|
|
250
449
|
},
|
|
251
450
|
];
|
|
252
451
|
}
|
|
253
452
|
}
|
|
254
453
|
|
|
454
|
+
async function _mysqlTableExists(conn, tableName) {
|
|
455
|
+
const [rows] = await conn.query(
|
|
456
|
+
`SELECT COUNT(*) AS c FROM information_schema.tables
|
|
457
|
+
WHERE table_schema = DATABASE() AND table_name = ?`,
|
|
458
|
+
[tableName]
|
|
459
|
+
);
|
|
460
|
+
return Number(rows[0].c) > 0;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function _mysqlIndexExists(conn, tableName, indexName) {
|
|
464
|
+
const [rows] = await conn.query(
|
|
465
|
+
`SELECT COUNT(*) AS c FROM information_schema.statistics
|
|
466
|
+
WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?`,
|
|
467
|
+
[tableName, indexName]
|
|
468
|
+
);
|
|
469
|
+
return Number(rows[0].c) > 0;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async function _mysqlForeignKeyExists(conn, tableName, constraintName) {
|
|
473
|
+
const [rows] = await conn.query(
|
|
474
|
+
`SELECT COUNT(*) AS c FROM information_schema.table_constraints
|
|
475
|
+
WHERE table_schema = DATABASE()
|
|
476
|
+
AND table_name = ?
|
|
477
|
+
AND constraint_type = 'FOREIGN KEY'
|
|
478
|
+
AND constraint_name = ?`,
|
|
479
|
+
[tableName, constraintName]
|
|
480
|
+
);
|
|
481
|
+
return Number(rows[0].c) > 0;
|
|
482
|
+
}
|
|
483
|
+
|
|
255
484
|
module.exports = { MysqlTokenStoreMigrationManager };
|