Action Michael's feedback about the structure of this feature.
This commit is contained in:
parent
5747f30b5f
commit
c25de74e17
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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!)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue