From 0a96bb968404f66dd514d64f51e9522bfda98cbd Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 9 May 2024 12:44:30 +0100 Subject: [PATCH] Disabling auto-column fieldtype and subtypes. This is not something that is currently supported through the UI, so this is not a breaking change, just making sure these type of scenarios don't actually occur as they don't work particularly well. --- .../server/src/api/routes/tests/table.spec.ts | 53 ++++++++++++++++++- .../src/sdk/app/tables/external/index.ts | 50 ++++++++++++----- 2 files changed, 89 insertions(+), 14 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 9aabffd8b9..100ace610b 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -1,8 +1,8 @@ import { context, events } from "@budibase/backend-core" import { AutoFieldSubType, - Datasource, BBReferenceFieldSubType, + Datasource, FieldType, INTERNAL_TABLE_SOURCE_ID, InternalTable, @@ -214,6 +214,57 @@ describe.each([ }) }) + describe("external table validation", () => { + !isInternal && + it("should error if column is of type auto", async () => { + const table = basicTable(datasource) + await config.api.table.save( + { + ...table, + schema: { + ...table.schema, + auto: { + name: "auto", + autocolumn: true, + type: FieldType.AUTO, + }, + }, + }, + { + status: 400, + body: { + message: `Column "auto" has type "${FieldType.AUTO}" - this is not supported.`, + }, + } + ) + }) + + !isInternal && + it("should error if column has auto subtype", async () => { + const table = basicTable(datasource) + await config.api.table.save( + { + ...table, + schema: { + ...table.schema, + auto: { + name: "auto", + autocolumn: true, + type: FieldType.NUMBER, + subtype: AutoFieldSubType.AUTO_ID, + }, + }, + }, + { + status: 400, + body: { + message: `Column "auto" has subtype "${AutoFieldSubType.AUTO_ID}" - this is not supported.`, + }, + } + ) + }) + }) + it("should add a new column for an internal DB table", async () => { const saveTableRequest: SaveTableRequest = { ...basicTable(), diff --git a/packages/server/src/sdk/app/tables/external/index.ts b/packages/server/src/sdk/app/tables/external/index.ts index 2a78600cfc..5ae58597d5 100644 --- a/packages/server/src/sdk/app/tables/external/index.ts +++ b/packages/server/src/sdk/app/tables/external/index.ts @@ -6,6 +6,7 @@ import { Table, TableRequest, ViewV2, + AutoFieldSubType, } from "@budibase/types" import { context } from "@budibase/backend-core" import { buildExternalTableId } from "../../../../integrations/utils" @@ -29,6 +30,39 @@ import { populateExternalTableSchemas } from "../validation" import datasourceSdk from "../../datasources" import * as viewSdk from "../../views" +function noPrimaryKey(table: Table) { + return table.primary == null || table.primary.length === 0 +} + +function validate(table: Table, oldTable?: Table) { + if (!oldTable && table.schema.id && noPrimaryKey(table)) { + throw new Error( + "External tables with no `primary` column set will define an `id` column, but we found an `id` column in the supplied schema. Either set a `primary` column or remove the `id` column." + ) + } + + if (hasTypeChanged(table, oldTable)) { + throw new Error("A column type has changed.") + } + + const autoSubTypes = Object.values(AutoFieldSubType) + // check for auto columns, they are not allowed + for (let [key, column] of Object.entries(table.schema)) { + // the auto-column type should never be used + if (column.type === FieldType.AUTO) { + throw new Error( + `Column "${key}" has type "${FieldType.AUTO}" - this is not supported.` + ) + } + + if (column.subtype && autoSubTypes.includes(column.subtype)) { + throw new Error( + `Column "${key}" has subtype "${column.subtype}" - this is not supported.` + ) + } + } +} + export async function save( datasourceId: string, update: Table, @@ -47,16 +81,10 @@ export async function save( oldTable = await getTable(tableId) } - if ( - !oldTable && - (tableToSave.primary == null || tableToSave.primary.length === 0) - ) { - if (tableToSave.schema.id) { - throw new Error( - "External tables with no `primary` column set will define an `id` column, but we found an `id` column in the supplied schema. Either set a `primary` column or remove the `id` column." - ) - } + // this will throw an error if something is wrong + validate(tableToSave, oldTable) + if (!oldTable && noPrimaryKey(tableToSave)) { tableToSave.primary = ["id"] tableToSave.schema.id = { type: FieldType.NUMBER, @@ -65,10 +93,6 @@ export async function save( } } - if (hasTypeChanged(tableToSave, oldTable)) { - throw new Error("A column type has changed.") - } - for (let view in tableToSave.views) { const tableView = tableToSave.views[view] if (!tableView || !viewSdk.isV2(tableView)) continue