1
0
Fork 0
mirror of synced 2024-07-14 18:55:45 +12:00

Action Michael's feedback about the structure of this feature.

This commit is contained in:
Sam Rose 2023-10-18 15:14:34 +01:00
parent 5747f30b5f
commit c25de74e17
No known key found for this signature in database
3 changed files with 97 additions and 49 deletions

View file

@ -11,7 +11,6 @@ import {
BulkImportRequest,
BulkImportResponse,
FetchTablesResponse,
InternalTable,
MigrateRequest,
MigrateResponse,
SaveTableRequest,
@ -19,8 +18,6 @@ import {
Table,
TableResponse,
UserCtx,
isBBReferenceField,
isRelationshipField,
} from "@budibase/types"
import sdk from "../../../sdk"
import { jsonFromCsvString } from "../../../utilities/csv"
@ -164,53 +161,8 @@ export async function validateExistingTableImport(ctx: UserCtx) {
}
}
function error(ctx: UserCtx, message: string, status = 400) {
ctx.status = status
ctx.body = { message }
}
export async function migrate(ctx: UserCtx<MigrateRequest, MigrateResponse>) {
const { tableId, oldColumn, newColumn } = ctx.request.body
// For now we're only supporting migrations of user relationships to user
// columns in internal tables. In future we may want to support other
// migrations but for now return an error if we aren't migrating a user
// relationship.
if (isExternalTable(tableId)) {
return error(ctx, "External tables cannot be migrated")
}
const table = await sdk.tables.getTable(tableId)
if (!(oldColumn.name in table.schema)) {
return error(
ctx,
`Column "${oldColumn.name}" does not exist on table "${table.name}"`
)
}
if (newColumn.name in table.schema) {
return error(
ctx,
`Column "${newColumn.name}" already exists on table "${table.name}"`
)
}
if (!isBBReferenceField(newColumn)) {
return error(ctx, `Column "${newColumn.name}" is not a user column`)
}
if (newColumn.subtype !== "user" && newColumn.subtype !== "users") {
return error(ctx, `Column "${newColumn.name}" is not a user column`)
}
if (!isRelationshipField(oldColumn)) {
return error(ctx, `Column "${oldColumn.name}" is not a user relationship`)
}
if (oldColumn.tableId !== InternalTable.USER_METADATA) {
return error(ctx, `Column "${oldColumn.name}" is not a user relationship`)
}
let rows = await sdk.rows.fetch(tableId)
await sdk.tables.migrate(table, oldColumn, newColumn)
}

View file

@ -7,6 +7,7 @@ import {
} from "../../../integrations/utils"
import {
Database,
FieldSchema,
Table,
TableResponse,
TableViewsResponse,
@ -14,6 +15,7 @@ import {
import datasources from "../datasources"
import { populateExternalTableSchemas } from "./validation"
import sdk from "../../../sdk"
import { migrate } from "./migration"
async function getAllInternalTables(db?: Database): Promise<Table[]> {
if (!db) {
@ -84,6 +86,14 @@ async function saveTable(table: Table) {
}
}
async function addColumn(table: Table, newColumn: FieldSchema) {
if (newColumn.name in table.schema) {
throw `Column "${newColumn.name}" already exists on table "${table.name}"`
}
table.schema[newColumn.name] = newColumn
await saveTable(table)
}
export default {
getAllInternalTables,
getAllExternalTables,
@ -92,4 +102,6 @@ export default {
populateExternalTableSchemas,
enrichViewSchemas,
saveTable,
addColumn,
migrate,
}

View file

@ -0,0 +1,84 @@
import { BadRequestError } from "@budibase/backend-core"
import {
BBReferenceFieldMetadata,
FieldSchema,
InternalTable,
RelationshipFieldMetadata,
Table,
isBBReferenceField,
isRelationshipField,
} from "@budibase/types"
import { isExternalTable } from "src/integrations/utils"
import sdk from "../../../sdk"
export async function migrate(
table: Table,
oldColumn: FieldSchema,
newColumn: FieldSchema
) {
let migrator = getColumnMigrator(table, oldColumn, newColumn)
await sdk.tables.addColumn(table, newColumn)
migrator.doMigration()
}
interface ColumnMigrator {
doMigration(): Promise<void>
}
function getColumnMigrator(
table: Table,
oldColumn: FieldSchema,
newColumn: FieldSchema
): ColumnMigrator {
// For now we're only supporting migrations of user relationships to user
// columns in internal tables. In future we may want to support other
// migrations but for now return an error if we aren't migrating a user
// relationship.
if (isExternalTable(table._id!)) {
throw new BadRequestError("External tables cannot be migrated")
}
if (!(oldColumn.name in table.schema)) {
throw new BadRequestError(`Column "${oldColumn.name}" does not exist`)
}
if (newColumn.name in table.schema) {
throw new BadRequestError(`Column "${newColumn.name}" already exists`)
}
if (!isBBReferenceField(newColumn)) {
throw new BadRequestError(`Column "${newColumn.name}" is not a user column`)
}
if (newColumn.subtype !== "user" && newColumn.subtype !== "users") {
throw new BadRequestError(`Column "${newColumn.name}" is not a user column`)
}
if (!isRelationshipField(oldColumn)) {
throw new BadRequestError(
`Column "${oldColumn.name}" is not a user relationship`
)
}
if (oldColumn.tableId !== InternalTable.USER_METADATA) {
throw new BadRequestError(
`Column "${oldColumn.name}" is not a user relationship`
)
}
return new UserColumnMigrator(table, oldColumn, newColumn)
}
class UserColumnMigrator implements ColumnMigrator {
constructor(
private table: Table,
private oldColumn: RelationshipFieldMetadata,
private newColumn: BBReferenceFieldMetadata
) {}
async doMigration() {
let rows = await sdk.rows.fetch(this.table._id!)
}
}