From 3222617b8177314cb417ca01049317c40870ac0a Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 23 Jan 2023 13:56:22 +0100 Subject: wallet-core: make DB migration logic more tolerant --- packages/taler-wallet-core/src/db.ts | 60 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 72e9aff04..bde386766 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -2468,8 +2468,14 @@ export async function applyFixups( }); } +/** + * Upgrade an IndexedDB in an upgrade transaction. + * + * The upgrade is made based on a store map, i.e. the metadata + * structure that describes all the object stores and indexes. + */ function upgradeFromStoreMap( - storeMap: any, + storeMap: any, // FIXME: nail down type db: IDBDatabase, oldVersion: number, newVersion: number, @@ -2511,16 +2517,23 @@ function upgradeFromStoreMap( continue; } let s: IDBObjectStore; - try { - s = db.createObjectStore(swi.storeName, { - autoIncrement: storeDesc.autoIncrement, - keyPath: storeDesc.keyPath, - }); - } catch (e) { - const moreInfo = e instanceof Error ? ` Reason: ${e.message}` : ""; - throw Error( - `Migration failed. Could not create store ${swi.storeName}.${moreInfo}`, - ); + // Be tolerant if object store already exists. + // Probably means somebody deployed without + // adding the "addedInVersion" attribute. + if (!upgradeTransaction.objectStoreNames.contains(swi.storeName)) { + try { + s = db.createObjectStore(swi.storeName, { + autoIncrement: storeDesc.autoIncrement, + keyPath: storeDesc.keyPath, + }); + } catch (e) { + const moreInfo = e instanceof Error ? ` Reason: ${e.message}` : ""; + throw Error( + `Migration failed. Could not create store ${swi.storeName}.${moreInfo}`, + ); + } + } else { + s = upgradeTransaction.objectStore(swi.storeName); } for (const indexName in swi.indexMap as any) { const indexDesc: IndexDescriptor = swi.indexMap[indexName]; @@ -2528,16 +2541,21 @@ function upgradeFromStoreMap( if (indexAddedVersion <= oldVersion) { continue; } - try { - s.createIndex(indexDesc.name, indexDesc.keyPath, { - multiEntry: indexDesc.multiEntry, - unique: indexDesc.unique, - }); - } catch (e) { - const moreInfo = e instanceof Error ? ` Reason: ${e.message}` : ""; - throw Error( - `Migration failed. Could not create index ${indexDesc.name}/${indexDesc.keyPath}.${moreInfo}`, - ); + // Be tolerant if index already exists. + // Probably means somebody deployed without + // adding the "addedInVersion" attribute. + if (!s.indexNames.contains(indexDesc.name)) { + try { + s.createIndex(indexDesc.name, indexDesc.keyPath, { + multiEntry: indexDesc.multiEntry, + unique: indexDesc.unique, + }); + } catch (e) { + const moreInfo = e instanceof Error ? ` Reason: ${e.message}` : ""; + throw Error( + `Migration failed. Could not create index ${indexDesc.name}/${indexDesc.keyPath}.${moreInfo}`, + ); + } } } } -- cgit v1.2.3