@breeztech/breez-sdk-spark 0.14.0 → 0.15.0

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.
Files changed (37) hide show
  1. package/breez-sdk-spark.tgz +0 -0
  2. package/bundler/breez_sdk_spark_wasm.d.ts +114 -40
  3. package/bundler/breez_sdk_spark_wasm.js +1 -1
  4. package/bundler/breez_sdk_spark_wasm_bg.js +118 -104
  5. package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
  6. package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
  7. package/deno/breez_sdk_spark_wasm.d.ts +114 -40
  8. package/deno/breez_sdk_spark_wasm.js +118 -104
  9. package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
  10. package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
  11. package/nodejs/breez_sdk_spark_wasm.d.ts +114 -40
  12. package/nodejs/breez_sdk_spark_wasm.js +121 -106
  13. package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
  14. package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
  15. package/nodejs/index.mjs +3 -2
  16. package/nodejs/mysql-session-manager/index.cjs +26 -8
  17. package/nodejs/mysql-session-manager/migrations.cjs +40 -3
  18. package/nodejs/mysql-storage/index.cjs +67 -48
  19. package/nodejs/mysql-storage/migrations.cjs +220 -85
  20. package/nodejs/mysql-token-store/index.cjs +133 -68
  21. package/nodejs/mysql-token-store/migrations.cjs +309 -80
  22. package/nodejs/mysql-tree-store/index.cjs +76 -41
  23. package/nodejs/mysql-tree-store/migrations.cjs +254 -71
  24. package/nodejs/postgres-session-manager/index.cjs +27 -9
  25. package/nodejs/postgres-session-manager/migrations.cjs +45 -6
  26. package/nodejs/postgres-storage/index.cjs +81 -62
  27. package/nodejs/postgres-storage/migrations.cjs +207 -79
  28. package/nodejs/postgres-token-store/index.cjs +111 -67
  29. package/nodejs/postgres-token-store/migrations.cjs +153 -61
  30. package/nodejs/postgres-tree-store/index.cjs +60 -42
  31. package/nodejs/postgres-tree-store/migrations.cjs +130 -46
  32. package/package.json +1 -1
  33. package/ssr/index.js +14 -9
  34. package/web/breez_sdk_spark_wasm.d.ts +126 -51
  35. package/web/breez_sdk_spark_wasm.js +118 -104
  36. package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
  37. package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
@@ -11,7 +11,7 @@
11
11
  * - pg_advisory_xact_lock → GET_LOCK/RELEASE_LOCK
12
12
  * - reserved word `key` quoted with backticks
13
13
  *
14
- * Uses a schema_migrations table + GET_LOCK to safely run migrations from
14
+ * Uses a brz_schema_migrations table + GET_LOCK to safely run migrations from
15
15
  * concurrent processes. Unlike pg's transaction-scoped advisory locks, MySQL
16
16
  * named locks are session-scoped, so we explicitly RELEASE_LOCK after the
17
17
  * commit (or on error in finally).
@@ -82,17 +82,19 @@ class MysqlMigrationManager {
82
82
  }
83
83
 
84
84
  try {
85
+ await this._applySchemaRenames(conn);
86
+
85
87
  await conn.query("START TRANSACTION");
86
88
 
87
89
  await conn.query(`
88
- CREATE TABLE IF NOT EXISTS schema_migrations (
90
+ CREATE TABLE IF NOT EXISTS brz_schema_migrations (
89
91
  version INT PRIMARY KEY,
90
92
  applied_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
91
93
  )
92
94
  `);
93
95
 
94
96
  const [versionRows] = await conn.query(
95
- "SELECT COALESCE(MAX(version), 0) AS version FROM schema_migrations"
97
+ "SELECT COALESCE(MAX(version), 0) AS version FROM brz_schema_migrations"
96
98
  );
97
99
  const currentVersion = versionRows[0].version;
98
100
 
@@ -119,7 +121,7 @@ class MysqlMigrationManager {
119
121
  }
120
122
 
121
123
  await conn.query(
122
- "INSERT INTO schema_migrations (version) VALUES (?)",
124
+ "INSERT INTO brz_schema_migrations (version) VALUES (?)",
123
125
  [version]
124
126
  );
125
127
  }
@@ -152,6 +154,121 @@ class MysqlMigrationManager {
152
154
  }
153
155
  }
154
156
 
157
+ /**
158
+ * Pre-prefix rename. Canary-gated on the legacy `schema_migrations`
159
+ * table. MySQL PKs are always named `PRIMARY` and the core schema has
160
+ * no FKs, so only tables and indexes need renaming.
161
+ * @param {import('mysql2/promise').PoolConnection} conn
162
+ */
163
+ async _applySchemaRenames(conn) {
164
+ if (!(await _mysqlTableExists(conn, "schema_migrations"))) {
165
+ return;
166
+ }
167
+
168
+ const tableRenames = [
169
+ ["payments", "brz_payments"],
170
+ ["settings", "brz_settings"],
171
+ ["unclaimed_deposits", "brz_unclaimed_deposits"],
172
+ ["payment_metadata", "brz_payment_metadata"],
173
+ ["payment_details_lightning", "brz_payment_details_lightning"],
174
+ ["payment_details_token", "brz_payment_details_token"],
175
+ ["payment_details_spark", "brz_payment_details_spark"],
176
+ ["lnurl_receive_metadata", "brz_lnurl_receive_metadata"],
177
+ ["sync_revision", "brz_sync_revision"],
178
+ ["sync_outgoing", "brz_sync_outgoing"],
179
+ ["sync_state", "brz_sync_state"],
180
+ ["sync_incoming", "brz_sync_incoming"],
181
+ ["contacts", "brz_contacts"],
182
+ ];
183
+ for (const [oldName, newName] of tableRenames) {
184
+ if (
185
+ (await _mysqlTableExists(conn, oldName)) &&
186
+ !(await _mysqlTableExists(conn, newName))
187
+ ) {
188
+ await conn.query(`RENAME TABLE \`${oldName}\` TO \`${newName}\``);
189
+ }
190
+ }
191
+
192
+ const indexRenames = [
193
+ ["brz_payments", "idx_payments_user_timestamp", "brz_idx_payments_user_timestamp"],
194
+ ["brz_payments", "idx_payments_user_payment_type", "brz_idx_payments_user_payment_type"],
195
+ ["brz_payments", "idx_payments_user_status", "brz_idx_payments_user_status"],
196
+ [
197
+ "brz_payment_metadata",
198
+ "idx_payment_metadata_user_parent",
199
+ "brz_idx_payment_metadata_user_parent",
200
+ ],
201
+ [
202
+ "brz_payment_details_lightning",
203
+ "idx_payment_details_lightning_user_invoice",
204
+ "brz_idx_payment_details_lightning_user_invoice",
205
+ ],
206
+ [
207
+ "brz_payment_details_lightning",
208
+ "idx_payment_details_lightning_user_payment_hash",
209
+ "brz_idx_payment_details_lightning_user_payment_hash",
210
+ ],
211
+ [
212
+ "brz_sync_outgoing",
213
+ "idx_sync_outgoing_user_record_type_data_id",
214
+ "brz_idx_sync_outgoing_user_record_type_data_id",
215
+ ],
216
+ [
217
+ "brz_sync_incoming",
218
+ "idx_sync_incoming_user_revision",
219
+ "brz_idx_sync_incoming_user_revision",
220
+ ],
221
+ // Pre-multi-tenant indexes (still present on version < 16 DBs).
222
+ ["brz_payments", "idx_payments_timestamp", "brz_idx_payments_timestamp"],
223
+ ["brz_payments", "idx_payments_payment_type", "brz_idx_payments_payment_type"],
224
+ ["brz_payments", "idx_payments_status", "brz_idx_payments_status"],
225
+ [
226
+ "brz_payment_metadata",
227
+ "idx_payment_metadata_parent",
228
+ "brz_idx_payment_metadata_parent",
229
+ ],
230
+ [
231
+ "brz_payment_details_lightning",
232
+ "idx_payment_details_lightning_invoice",
233
+ "brz_idx_payment_details_lightning_invoice",
234
+ ],
235
+ [
236
+ "brz_payment_details_lightning",
237
+ "idx_payment_details_lightning_payment_hash",
238
+ "brz_idx_payment_details_lightning_payment_hash",
239
+ ],
240
+ [
241
+ "brz_sync_outgoing",
242
+ "idx_sync_outgoing_data_id_record_type",
243
+ "brz_idx_sync_outgoing_data_id_record_type",
244
+ ],
245
+ [
246
+ "brz_sync_incoming",
247
+ "idx_sync_incoming_revision",
248
+ "brz_idx_sync_incoming_revision",
249
+ ],
250
+ ];
251
+ for (const [table, oldName, newName] of indexRenames) {
252
+ if (
253
+ (await _mysqlIndexExists(conn, table, oldName)) &&
254
+ !(await _mysqlIndexExists(conn, table, newName))
255
+ ) {
256
+ await conn.query(
257
+ `ALTER TABLE \`${table}\` RENAME INDEX \`${oldName}\` TO \`${newName}\``
258
+ );
259
+ }
260
+ }
261
+
262
+ if (
263
+ (await _mysqlTableExists(conn, "schema_migrations")) &&
264
+ !(await _mysqlTableExists(conn, "brz_schema_migrations"))
265
+ ) {
266
+ await conn.query(
267
+ "RENAME TABLE `schema_migrations` TO `brz_schema_migrations`"
268
+ );
269
+ }
270
+ }
271
+
155
272
  /**
156
273
  * @param {Buffer|Uint8Array} identity - 33-byte tenant identity. Inlined as
157
274
  * an `UNHEX('...')` literal in the multi-tenant scoping migration. Safe
@@ -164,7 +281,7 @@ class MysqlMigrationManager {
164
281
 
165
282
  // Per-table backfill: ADD COLUMN nullable -> UPDATE -> SET NOT NULL +
166
283
  // drop/recreate PK. Returns an array of statements. Tables with backticked
167
- // names (e.g. `settings` uses `key`) need the caller to backtick `pkCols`.
284
+ // names (e.g. `brz_settings` uses `key`) need the caller to backtick `pkCols`.
168
285
  const scopeTable = (table, pkCols) => [
169
286
  `ALTER TABLE \`${table}\` ADD COLUMN user_id VARBINARY(33) NULL`,
170
287
  `UPDATE \`${table}\` SET user_id = ${idLit} WHERE user_id IS NULL`,
@@ -177,7 +294,7 @@ class MysqlMigrationManager {
177
294
  name: "Create all tables at final schema",
178
295
  sql: [
179
296
  // -- Core tables --
180
- `CREATE TABLE IF NOT EXISTS payments (
297
+ `CREATE TABLE IF NOT EXISTS brz_payments (
181
298
  id VARCHAR(255) NOT NULL PRIMARY KEY,
182
299
  payment_type VARCHAR(64) NOT NULL,
183
300
  status VARCHAR(64) NOT NULL,
@@ -190,12 +307,12 @@ class MysqlMigrationManager {
190
307
  spark TINYINT(1) NULL
191
308
  )`,
192
309
 
193
- `CREATE TABLE IF NOT EXISTS settings (
310
+ `CREATE TABLE IF NOT EXISTS brz_settings (
194
311
  \`key\` VARCHAR(255) NOT NULL PRIMARY KEY,
195
312
  value LONGTEXT NOT NULL
196
313
  )`,
197
314
 
198
- `CREATE TABLE IF NOT EXISTS unclaimed_deposits (
315
+ `CREATE TABLE IF NOT EXISTS brz_unclaimed_deposits (
199
316
  txid VARCHAR(255) NOT NULL,
200
317
  vout INT NOT NULL,
201
318
  amount_sats BIGINT NULL,
@@ -205,7 +322,7 @@ class MysqlMigrationManager {
205
322
  PRIMARY KEY (txid, vout)
206
323
  )`,
207
324
 
208
- `CREATE TABLE IF NOT EXISTS payment_metadata (
325
+ `CREATE TABLE IF NOT EXISTS brz_payment_metadata (
209
326
  payment_id VARCHAR(255) NOT NULL PRIMARY KEY,
210
327
  parent_payment_id VARCHAR(255) NULL,
211
328
  lnurl_pay_info JSON NULL,
@@ -214,7 +331,7 @@ class MysqlMigrationManager {
214
331
  conversion_info JSON NULL
215
332
  )`,
216
333
 
217
- `CREATE TABLE IF NOT EXISTS payment_details_lightning (
334
+ `CREATE TABLE IF NOT EXISTS brz_payment_details_lightning (
218
335
  payment_id VARCHAR(255) NOT NULL PRIMARY KEY,
219
336
  invoice LONGTEXT NOT NULL,
220
337
  payment_hash VARCHAR(255) NOT NULL,
@@ -225,7 +342,7 @@ class MysqlMigrationManager {
225
342
  htlc_expiry_time BIGINT NOT NULL
226
343
  )`,
227
344
 
228
- `CREATE TABLE IF NOT EXISTS payment_details_token (
345
+ `CREATE TABLE IF NOT EXISTS brz_payment_details_token (
229
346
  payment_id VARCHAR(255) NOT NULL PRIMARY KEY,
230
347
  metadata JSON NOT NULL,
231
348
  tx_hash VARCHAR(255) NOT NULL,
@@ -233,13 +350,13 @@ class MysqlMigrationManager {
233
350
  invoice_details JSON NULL
234
351
  )`,
235
352
 
236
- `CREATE TABLE IF NOT EXISTS payment_details_spark (
353
+ `CREATE TABLE IF NOT EXISTS brz_payment_details_spark (
237
354
  payment_id VARCHAR(255) NOT NULL PRIMARY KEY,
238
355
  invoice_details JSON NULL,
239
356
  htlc_details JSON NULL
240
357
  )`,
241
358
 
242
- `CREATE TABLE IF NOT EXISTS lnurl_receive_metadata (
359
+ `CREATE TABLE IF NOT EXISTS brz_lnurl_receive_metadata (
243
360
  payment_hash VARCHAR(255) NOT NULL PRIMARY KEY,
244
361
  nostr_zap_request LONGTEXT NULL,
245
362
  nostr_zap_receipt LONGTEXT NULL,
@@ -247,15 +364,15 @@ class MysqlMigrationManager {
247
364
  )`,
248
365
 
249
366
  // -- Sync tables --
250
- `CREATE TABLE IF NOT EXISTS sync_revision (
367
+ `CREATE TABLE IF NOT EXISTS brz_sync_revision (
251
368
  id INT NOT NULL PRIMARY KEY DEFAULT 1,
252
369
  revision BIGINT NOT NULL DEFAULT 0,
253
370
  CHECK (id = 1)
254
371
  )`,
255
- `INSERT INTO sync_revision (id, revision) VALUES (1, 0)
372
+ `INSERT INTO brz_sync_revision (id, revision) VALUES (1, 0)
256
373
  ON DUPLICATE KEY UPDATE id = id`,
257
374
 
258
- `CREATE TABLE IF NOT EXISTS sync_outgoing (
375
+ `CREATE TABLE IF NOT EXISTS brz_sync_outgoing (
259
376
  record_type VARCHAR(255) NOT NULL,
260
377
  data_id VARCHAR(255) NOT NULL,
261
378
  schema_version VARCHAR(64) NOT NULL,
@@ -264,7 +381,7 @@ class MysqlMigrationManager {
264
381
  revision BIGINT NOT NULL
265
382
  )`,
266
383
 
267
- `CREATE TABLE IF NOT EXISTS sync_state (
384
+ `CREATE TABLE IF NOT EXISTS brz_sync_state (
268
385
  record_type VARCHAR(255) NOT NULL,
269
386
  data_id VARCHAR(255) NOT NULL,
270
387
  schema_version VARCHAR(64) NOT NULL,
@@ -274,7 +391,7 @@ class MysqlMigrationManager {
274
391
  PRIMARY KEY (record_type, data_id)
275
392
  )`,
276
393
 
277
- `CREATE TABLE IF NOT EXISTS sync_incoming (
394
+ `CREATE TABLE IF NOT EXISTS brz_sync_incoming (
278
395
  record_type VARCHAR(255) NOT NULL,
279
396
  data_id VARCHAR(255) NOT NULL,
280
397
  schema_version VARCHAR(64) NOT NULL,
@@ -285,23 +402,23 @@ class MysqlMigrationManager {
285
402
  )`,
286
403
 
287
404
  // -- Indexes --
288
- `CREATE INDEX idx_payments_timestamp ON payments(timestamp)`,
289
- `CREATE INDEX idx_payments_payment_type ON payments(payment_type)`,
290
- `CREATE INDEX idx_payments_status ON payments(status)`,
291
- `CREATE INDEX idx_payment_details_lightning_invoice
292
- ON payment_details_lightning(invoice(255))`,
293
- `CREATE INDEX idx_payment_details_lightning_payment_hash
294
- ON payment_details_lightning(payment_hash)`,
295
- `CREATE INDEX idx_payment_metadata_parent ON payment_metadata(parent_payment_id)`,
296
- `CREATE INDEX idx_sync_outgoing_data_id_record_type
297
- ON sync_outgoing(record_type, data_id)`,
298
- `CREATE INDEX idx_sync_incoming_revision ON sync_incoming(revision)`,
405
+ `CREATE INDEX brz_idx_payments_timestamp ON brz_payments(timestamp)`,
406
+ `CREATE INDEX brz_idx_payments_payment_type ON brz_payments(payment_type)`,
407
+ `CREATE INDEX brz_idx_payments_status ON brz_payments(status)`,
408
+ `CREATE INDEX brz_idx_payment_details_lightning_invoice
409
+ ON brz_payment_details_lightning(invoice(255))`,
410
+ `CREATE INDEX brz_idx_payment_details_lightning_payment_hash
411
+ ON brz_payment_details_lightning(payment_hash)`,
412
+ `CREATE INDEX brz_idx_payment_metadata_parent ON brz_payment_metadata(parent_payment_id)`,
413
+ `CREATE INDEX brz_idx_sync_outgoing_data_id_record_type
414
+ ON brz_sync_outgoing(record_type, data_id)`,
415
+ `CREATE INDEX brz_idx_sync_incoming_revision ON brz_sync_incoming(revision)`,
299
416
  ],
300
417
  },
301
418
  {
302
- name: "Create contacts table",
419
+ name: "Create brz_contacts table",
303
420
  sql: [
304
- `CREATE TABLE IF NOT EXISTS contacts (
421
+ `CREATE TABLE IF NOT EXISTS brz_contacts (
305
422
  id VARCHAR(255) NOT NULL PRIMARY KEY,
306
423
  name VARCHAR(255) NOT NULL,
307
424
  payment_identifier VARCHAR(255) NOT NULL,
@@ -311,77 +428,95 @@ class MysqlMigrationManager {
311
428
  ],
312
429
  },
313
430
  {
314
- name: "Add is_mature to unclaimed_deposits",
431
+ name: "Add is_mature to brz_unclaimed_deposits",
315
432
  sql: [
316
- `ALTER TABLE unclaimed_deposits ADD COLUMN is_mature TINYINT(1) NOT NULL DEFAULT 1`,
433
+ `ALTER TABLE brz_unclaimed_deposits ADD COLUMN is_mature TINYINT(1) NOT NULL DEFAULT 1`,
317
434
  ],
318
435
  },
319
436
  {
320
- name: "Add conversion_status to payment_metadata",
437
+ name: "Add conversion_status to brz_payment_metadata",
321
438
  sql: [
322
- `ALTER TABLE payment_metadata ADD COLUMN conversion_status VARCHAR(64) NULL`,
439
+ `ALTER TABLE brz_payment_metadata ADD COLUMN conversion_status VARCHAR(64) NULL`,
323
440
  ],
324
441
  },
325
442
  {
326
443
  name: "Multi-tenant scoping: add user_id and rewrite primary keys",
327
444
  sql: [
328
445
  // Per-user tables.
329
- ...scopeTable("payments", "id"),
330
- `DROP INDEX idx_payments_timestamp ON payments`,
331
- `DROP INDEX idx_payments_payment_type ON payments`,
332
- `DROP INDEX idx_payments_status ON payments`,
333
- `CREATE INDEX idx_payments_user_timestamp ON payments(user_id, timestamp)`,
334
- `CREATE INDEX idx_payments_user_payment_type ON payments(user_id, payment_type)`,
335
- `CREATE INDEX idx_payments_user_status ON payments(user_id, status)`,
336
-
337
- ...scopeTable("payment_metadata", "payment_id"),
338
- `DROP INDEX idx_payment_metadata_parent ON payment_metadata`,
339
- `CREATE INDEX idx_payment_metadata_user_parent
340
- ON payment_metadata(user_id, parent_payment_id)`,
341
-
342
- ...scopeTable("payment_details_lightning", "payment_id"),
343
- `DROP INDEX idx_payment_details_lightning_invoice ON payment_details_lightning`,
344
- `DROP INDEX idx_payment_details_lightning_payment_hash ON payment_details_lightning`,
345
- `CREATE INDEX idx_payment_details_lightning_user_invoice
346
- ON payment_details_lightning(user_id, invoice(255))`,
347
- `CREATE INDEX idx_payment_details_lightning_user_payment_hash
348
- ON payment_details_lightning(user_id, payment_hash)`,
349
-
350
- ...scopeTable("payment_details_token", "payment_id"),
351
- ...scopeTable("payment_details_spark", "payment_id"),
352
- ...scopeTable("lnurl_receive_metadata", "payment_hash"),
353
- ...scopeTable("unclaimed_deposits", "txid, vout"),
354
- ...scopeTable("contacts", "id"),
355
- ...scopeTable("settings", "`key`"),
356
-
357
- // sync_revision was a singleton (PK id=1, CHECK id=1). Drop the PK
446
+ ...scopeTable("brz_payments", "id"),
447
+ `DROP INDEX brz_idx_payments_timestamp ON brz_payments`,
448
+ `DROP INDEX brz_idx_payments_payment_type ON brz_payments`,
449
+ `DROP INDEX brz_idx_payments_status ON brz_payments`,
450
+ `CREATE INDEX brz_idx_payments_user_timestamp ON brz_payments(user_id, timestamp)`,
451
+ `CREATE INDEX brz_idx_payments_user_payment_type ON brz_payments(user_id, payment_type)`,
452
+ `CREATE INDEX brz_idx_payments_user_status ON brz_payments(user_id, status)`,
453
+
454
+ ...scopeTable("brz_payment_metadata", "payment_id"),
455
+ `DROP INDEX brz_idx_payment_metadata_parent ON brz_payment_metadata`,
456
+ `CREATE INDEX brz_idx_payment_metadata_user_parent
457
+ ON brz_payment_metadata(user_id, parent_payment_id)`,
458
+
459
+ ...scopeTable("brz_payment_details_lightning", "payment_id"),
460
+ `DROP INDEX brz_idx_payment_details_lightning_invoice ON brz_payment_details_lightning`,
461
+ `DROP INDEX brz_idx_payment_details_lightning_payment_hash ON brz_payment_details_lightning`,
462
+ `CREATE INDEX brz_idx_payment_details_lightning_user_invoice
463
+ ON brz_payment_details_lightning(user_id, invoice(255))`,
464
+ `CREATE INDEX brz_idx_payment_details_lightning_user_payment_hash
465
+ ON brz_payment_details_lightning(user_id, payment_hash)`,
466
+
467
+ ...scopeTable("brz_payment_details_token", "payment_id"),
468
+ ...scopeTable("brz_payment_details_spark", "payment_id"),
469
+ ...scopeTable("brz_lnurl_receive_metadata", "payment_hash"),
470
+ ...scopeTable("brz_unclaimed_deposits", "txid, vout"),
471
+ ...scopeTable("brz_contacts", "id"),
472
+ ...scopeTable("brz_settings", "`key`"),
473
+
474
+ // brz_sync_revision was a singleton (PK id=1, CHECK id=1). Drop the PK
358
475
  // and the id column, then re-key by user_id.
359
- { op: "dropPrimaryKey", table: "sync_revision" },
360
- `ALTER TABLE sync_revision DROP COLUMN id`,
361
- `ALTER TABLE sync_revision ADD COLUMN user_id VARBINARY(33) NULL`,
362
- `UPDATE sync_revision SET user_id = ${idLit} WHERE user_id IS NULL`,
363
- `ALTER TABLE sync_revision MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
364
- `ALTER TABLE sync_revision ADD PRIMARY KEY (user_id)`,
365
-
366
- // sync_outgoing has no PK, only an index — just add user_id and
476
+ { op: "dropPrimaryKey", table: "brz_sync_revision" },
477
+ `ALTER TABLE brz_sync_revision DROP COLUMN id`,
478
+ `ALTER TABLE brz_sync_revision ADD COLUMN user_id VARBINARY(33) NULL`,
479
+ `UPDATE brz_sync_revision SET user_id = ${idLit} WHERE user_id IS NULL`,
480
+ `ALTER TABLE brz_sync_revision MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
481
+ `ALTER TABLE brz_sync_revision ADD PRIMARY KEY (user_id)`,
482
+
483
+ // brz_sync_outgoing has no PK, only an index — just add user_id and
367
484
  // rewrite the index.
368
- `ALTER TABLE sync_outgoing ADD COLUMN user_id VARBINARY(33) NULL`,
369
- `UPDATE sync_outgoing SET user_id = ${idLit} WHERE user_id IS NULL`,
370
- `ALTER TABLE sync_outgoing MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
371
- `DROP INDEX idx_sync_outgoing_data_id_record_type ON sync_outgoing`,
372
- `CREATE INDEX idx_sync_outgoing_user_record_type_data_id
373
- ON sync_outgoing(user_id, record_type, data_id)`,
374
-
375
- ...scopeTable("sync_state", "record_type, data_id"),
376
-
377
- ...scopeTable("sync_incoming", "record_type, data_id, revision"),
378
- `DROP INDEX idx_sync_incoming_revision ON sync_incoming`,
379
- `CREATE INDEX idx_sync_incoming_user_revision
380
- ON sync_incoming(user_id, revision)`,
485
+ `ALTER TABLE brz_sync_outgoing ADD COLUMN user_id VARBINARY(33) NULL`,
486
+ `UPDATE brz_sync_outgoing SET user_id = ${idLit} WHERE user_id IS NULL`,
487
+ `ALTER TABLE brz_sync_outgoing MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
488
+ `DROP INDEX brz_idx_sync_outgoing_data_id_record_type ON brz_sync_outgoing`,
489
+ `CREATE INDEX brz_idx_sync_outgoing_user_record_type_data_id
490
+ ON brz_sync_outgoing(user_id, record_type, data_id)`,
491
+
492
+ ...scopeTable("brz_sync_state", "record_type, data_id"),
493
+
494
+ ...scopeTable("brz_sync_incoming", "record_type, data_id, revision"),
495
+ `DROP INDEX brz_idx_sync_incoming_revision ON brz_sync_incoming`,
496
+ `CREATE INDEX brz_idx_sync_incoming_user_revision
497
+ ON brz_sync_incoming(user_id, revision)`,
381
498
  ],
382
499
  },
383
500
  ];
384
501
  }
385
502
  }
386
503
 
504
+ async function _mysqlTableExists(conn, tableName) {
505
+ const [rows] = await conn.query(
506
+ `SELECT COUNT(*) AS c FROM information_schema.tables
507
+ WHERE table_schema = DATABASE() AND table_name = ?`,
508
+ [tableName]
509
+ );
510
+ return Number(rows[0].c) > 0;
511
+ }
512
+
513
+ async function _mysqlIndexExists(conn, tableName, indexName) {
514
+ const [rows] = await conn.query(
515
+ `SELECT COUNT(*) AS c FROM information_schema.statistics
516
+ WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?`,
517
+ [tableName, indexName]
518
+ );
519
+ return Number(rows[0].c) > 0;
520
+ }
521
+
387
522
  module.exports = { MysqlMigrationManager };