From 84d145026ba7c89d873c608467aa0c53787a6cb6 Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Thu, 2 Apr 2020 06:21:52 +0100 Subject: [PATCH] bugfix: database upgrade broken when field added --- packages/core/src/transactions/execute.js | 12 +++++-- .../core/test/templateApi.upgradeData.spec.js | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/core/src/transactions/execute.js b/packages/core/src/transactions/execute.js index 54bf019463..9b90a66041 100644 --- a/packages/core/src/transactions/execute.js +++ b/packages/core/src/transactions/execute.js @@ -44,18 +44,22 @@ import { } from "../templateApi/hierarchy" import { getRecordInfo } from "../recordApi/recordInfo" import { getIndexDir } from "../indexApi/getIndexDir" +import { _deleteIndex } from "../indexApi/delete" import { initialiseIndex } from "../indexing/initialiseIndex" export const executeTransactions = app => async transactions => { const recordsByShard = mappedRecordsByIndexShard(app.hierarchy, transactions) for (const shard of keys(recordsByShard)) { - if (recordsByShard[shard].isRebuild) + if (recordsByShard[shard].isRebuild) { + if (await app.datastore.exists(shard)) + await app.datastore.deleteFile(shard) await initialiseIndex( app.datastore, getParentKey(recordsByShard[shard].indexDir), recordsByShard[shard].indexNode ) + } await applyToShard( app.hierarchy, app.datastore, @@ -76,7 +80,11 @@ const mappedRecordsByIndexShard = (hierarchy, transactions) => { const indexBuild = getBuildIndexTransactionsByShard(hierarchy, transactions) - const toRemove = [...deletes, ...updates.toRemove, ...indexBuild.toRemove] + const toRemove = [ + ...deletes, + ...updates.toRemove, + ...indexBuild.toRemove, + ] const toWrite = [...created, ...updates.toWrite, ...indexBuild.toWrite] diff --git a/packages/core/test/templateApi.upgradeData.spec.js b/packages/core/test/templateApi.upgradeData.spec.js index 945c5e0f43..8118180121 100644 --- a/packages/core/test/templateApi.upgradeData.spec.js +++ b/packages/core/test/templateApi.upgradeData.spec.js @@ -240,6 +240,40 @@ describe("upgradeData", () => { }) +it("should rebuild affected index when field is removed", async () => { + const { oldSetup, newSetup, records } = await configure() + newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "status") + + let itemsInIndex = await _listItems(oldSetup.app, "/contact_index") + expect(itemsInIndex.length).toBe(2) + expect(itemsInIndex[0].status).toBeDefined() + expect(itemsInIndex[0].status).toBe(records.contact1.status) + + await upgradeData(oldSetup.app)(newSetup.root) + + itemsInIndex = await _listItems(newSetup.app, "/contact_index") + expect(itemsInIndex.length).toBe(2) + expect(itemsInIndex[0].status).toBeUndefined() +}) + +it("should rebuild affected index when field is added", async () => { + const { oldSetup, newSetup, records } = await configure() + + const aliveField = newSetup.templateApi.getNewField("string") + aliveField.name = "isalive" + newSetup.templateApi.addField(newSetup.contact, aliveField) + + let itemsInIndex = await _listItems(oldSetup.app, "/contact_index") + expect(itemsInIndex.length).toBe(2) + expect(itemsInIndex[0].isalive).toBeUndefined() + + await upgradeData(oldSetup.app)(newSetup.root) + + itemsInIndex = await _listItems(newSetup.app, "/contact_index") + expect(itemsInIndex.length).toBe(2) + expect(itemsInIndex[0].isalive).toBe(null) +}) + const configure = async () => { const oldSetup = await setup() @@ -256,8 +290,10 @@ const configure = async () => { const createSomeRecords = async recordApi => { const contact1 = recordApi.getNew("/contacts", "contact") contact1.name = "bobby" + contact1.status = "New" const contact2 = recordApi.getNew("/contacts", "contact") contact2.name = "poppy" + contact2.status = "Complete" await recordApi.save(contact1) await recordApi.save(contact2)