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)
}
}