From 1771b5905a37e544261a2fb8b2deca58786aeabc Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 18 Oct 2023 18:02:10 +0100 Subject: [PATCH] Most of the way to getting my first test passing. --- .../server/src/api/routes/tests/table.spec.ts | 2 + packages/server/src/sdk/app/tables/index.ts | 17 ++++++--- .../server/src/sdk/app/tables/migration.ts | 38 +++++++++++++++++-- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index eaf3757ea8..dcf1704ed0 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -456,9 +456,11 @@ describe("/tables", () => { const migratedTable = await config.api.table.get(table._id!) expect(migratedTable.schema["user column"]).toBeDefined() + expect(migratedTable.schema["user relationship"]).not.toBeDefined() const rows = await config.api.row.fetch(table._id!) expect(rows[0]["user column"]).toBeDefined() + expect(rows[0]["user relationship"]).not.toBeDefined() }) }) }) diff --git a/packages/server/src/sdk/app/tables/index.ts b/packages/server/src/sdk/app/tables/index.ts index e4884b2ec4..fab8c7d198 100644 --- a/packages/server/src/sdk/app/tables/index.ts +++ b/packages/server/src/sdk/app/tables/index.ts @@ -16,6 +16,8 @@ import datasources from "../datasources" import { populateExternalTableSchemas } from "./validation" import sdk from "../../../sdk" import { migrate } from "./migration" +import { DocumentInsertResponse } from "@budibase/nano" +import { cloneDeep } from "lodash" async function getAllInternalTables(db?: Database): Promise { if (!db) { @@ -75,23 +77,28 @@ function enrichViewSchemas(table: Table): TableResponse { } } -async function saveTable(table: Table) { +async function saveTable(table: Table): Promise { const db = context.getAppDB() + let resp: DocumentInsertResponse if (isExternalTable(table._id!)) { const datasource = await sdk.datasources.get(table.sourceId!) datasource.entities![table.name] = table - await db.put(datasource) + resp = await db.put(datasource) } else { - await db.put(table) + resp = await db.put(table) } + + let tableClone = cloneDeep(table) + tableClone._rev = resp.rev + return tableClone } -async function addColumn(table: Table, newColumn: FieldSchema) { +async function addColumn(table: Table, newColumn: FieldSchema): Promise
{ if (newColumn.name in table.schema) { throw `Column "${newColumn.name}" already exists on table "${table.name}"` } table.schema[newColumn.name] = newColumn - await saveTable(table) + return await saveTable(table) } export default { diff --git a/packages/server/src/sdk/app/tables/migration.ts b/packages/server/src/sdk/app/tables/migration.ts index ac7f3a3765..a08b56826d 100644 --- a/packages/server/src/sdk/app/tables/migration.ts +++ b/packages/server/src/sdk/app/tables/migration.ts @@ -1,15 +1,19 @@ -import { BadRequestError } from "@budibase/backend-core" +import { BadRequestError, context } from "@budibase/backend-core" import { BBReferenceFieldMetadata, FieldSchema, InternalTable, RelationshipFieldMetadata, + Row, Table, isBBReferenceField, isRelationshipField, } from "@budibase/types" import sdk from "../../../sdk" import { isExternalTable } from "../../../../src/integrations/utils" +import { db as dbCore } from "@budibase/backend-core" +import { EventType, updateLinks } from "../../../../src/db/linkedRows" +import { cloneDeep } from "lodash" export async function migrate( table: Table, @@ -17,10 +21,15 @@ export async function migrate( newColumn: FieldSchema ) { let migrator = getColumnMigrator(table, oldColumn, newColumn) + let oldTable = cloneDeep(table) - await sdk.tables.addColumn(table, newColumn) + table = await sdk.tables.addColumn(table, newColumn) - migrator.doMigration() + await migrator.doMigration() + + delete table.schema[oldColumn.name] + await sdk.tables.saveTable(table) + await updateLinks({ eventType: EventType.TABLE_UPDATED, table, oldTable }) } interface ColumnMigrator { @@ -80,6 +89,29 @@ class UserColumnMigrator implements ColumnMigrator { async doMigration() { let rows = await sdk.rows.fetch(this.table._id!) + let rowsById = rows.reduce((acc, row) => { + acc[row._id!] = row + return acc + }, {} as Record) + let links = await sdk.links.fetchWithDocument(this.table._id!) + for (let link of links) { + if (link.doc1.tableId !== this.table._id) { + continue + } + if (link.doc1.fieldName !== this.oldColumn.name) { + continue + } + if (link.doc2.tableId !== InternalTable.USER_METADATA) { + continue + } + + let userId = dbCore.getGlobalIDFromUserMetadataID(link.doc2.rowId) + let row = rowsById[link.doc1.rowId] + row[this.newColumn.name] = userId + } + + let db = context.getAppDB() + await db.bulkDocs(rows) } }