Skip to content

Commit

Permalink
Merge pull request #14743 from Budibase/chore/move-table-creation-to-sdk
Browse files Browse the repository at this point in the history
Move table creation to sdk
  • Loading branch information
adrinr authored Oct 9, 2024
2 parents 2443793 + 23022e3 commit d29de7c
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 31 deletions.
2 changes: 1 addition & 1 deletion packages/server/src/api/controllers/table/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function getDatasourceId(table: Table) {
return breakExternalTableId(table._id).datasourceId
}

export async function save(
export async function updateTable(
ctx: UserCtx<SaveTableRequest, SaveTableResponse>,
renaming?: RenameColumn
) {
Expand Down
14 changes: 9 additions & 5 deletions packages/server/src/api/controllers/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,22 @@ export async function find(ctx: UserCtx<void, TableResponse>) {

export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
const appId = ctx.appId
const table = ctx.request.body
const isImport = table.rows
const { rows, ...table } = ctx.request.body
const isImport = rows
const renaming = ctx.request.body._rename

const isCreate = !table._id

checkDefaultFields(table)

const api = pickApi({ table })
let savedTable = await api.save(ctx, renaming)
if (!table._id) {
let savedTable: Table
if (isCreate) {
savedTable = await sdk.tables.create(table, rows, ctx.user._id)
savedTable = await sdk.tables.enrichViewSchemas(savedTable)
await events.table.created(savedTable)
} else {
const api = pickApi({ table })
savedTable = await api.updateTable(ctx, renaming)
await events.table.updated(savedTable)
}
if (renaming) {
Expand Down
9 changes: 3 additions & 6 deletions packages/server/src/api/controllers/table/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "@budibase/types"
import sdk from "../../../sdk"

export async function save(
export async function updateTable(
ctx: UserCtx<SaveTableRequest, SaveTableResponse>,
renaming?: RenameColumn
) {
Expand All @@ -25,19 +25,16 @@ export async function save(
sourceType: rest.sourceType || TableSourceType.INTERNAL,
}

const isImport = !!rows

if (!tableToSave.views) {
tableToSave.views = {}
}

try {
const { table } = await sdk.tables.internal.save(tableToSave, {
user: ctx.user,
userId: ctx.user._id,
rowsToImport: rows,
tableId: ctx.request.body._id,
renaming,
isImport,
})

return table
Expand Down Expand Up @@ -72,7 +69,7 @@ export async function bulkImport(
await handleDataImport(table, {
importRows: rows,
identifierFields,
user: ctx.user,
userId: ctx.user._id,
})
return table
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("utils", () => {

const data = [{ name: "Alice" }, { name: "Bob" }, { name: "Claire" }]

const result = await importToRows(data, table, config.user)
const result = await importToRows(data, table, config.user?._id)
expect(result).toEqual([
expect.objectContaining({
autoId: 1,
Expand Down
20 changes: 9 additions & 11 deletions packages/server/src/api/controllers/table/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { quotas } from "@budibase/pro"
import { events, context, features } from "@budibase/backend-core"
import {
AutoFieldSubType,
ContextUser,
Datasource,
Row,
SourceName,
Expand Down Expand Up @@ -122,7 +121,7 @@ export function makeSureTableUpToDate(table: Table, tableToSave: Table) {
export async function importToRows(
data: Row[],
table: Table,
user?: ContextUser,
userId?: string,
opts?: { keepCouchId: boolean }
) {
const originalTable = table
Expand All @@ -136,7 +135,7 @@ export async function importToRows(

// We use a reference to table here and update it after input processing,
// so that we can auto increment auto IDs in imported data properly
const processed = await inputProcessing(user?._id, table, row, {
const processed = await inputProcessing(userId, table, row, {
noAutoRelationships: true,
})
row = processed
Expand Down Expand Up @@ -167,11 +166,10 @@ export async function importToRows(

export async function handleDataImport(
table: Table,
opts?: { identifierFields?: string[]; user?: ContextUser; importRows?: Row[] }
opts?: { identifierFields?: string[]; userId?: string; importRows?: Row[] }
) {
const schema = table.schema
const identifierFields = opts?.identifierFields || []
const user = opts?.user
const importRows = opts?.importRows

if (!importRows || !isRows(importRows) || !isSchema(schema)) {
Expand All @@ -181,7 +179,7 @@ export async function handleDataImport(
const db = context.getAppDB()
const data = parse(importRows, table)

const finalData = await importToRows(data, table, user, {
const finalData = await importToRows(data, table, opts?.userId, {
keepCouchId: identifierFields.includes("_id"),
})

Expand Down Expand Up @@ -282,22 +280,22 @@ export function checkStaticTables(table: Table) {

class TableSaveFunctions {
db: Database
user?: ContextUser
userId?: string
oldTable?: Table
importRows?: Row[]
rows: Row[]

constructor({
user,
userId,
oldTable,
importRows,
}: {
user?: ContextUser
userId?: string
oldTable?: Table
importRows?: Row[]
}) {
this.db = context.getAppDB()
this.user = user
this.userId = userId
this.oldTable = oldTable
this.importRows = importRows
// any rows that need updated
Expand Down Expand Up @@ -329,7 +327,7 @@ class TableSaveFunctions {
table = await handleSearchIndexes(table)
table = await handleDataImport(table, {
importRows: this.importRows,
user: this.user,
userId: this.userId,
})
if (await features.flags.isEnabled("SQS")) {
await sdk.tables.sqs.addTable(table)
Expand Down
19 changes: 19 additions & 0 deletions packages/server/src/sdk/app/tables/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Row, Table } from "@budibase/types"

import * as external from "./external"
import * as internal from "./internal"
import { isExternal } from "./utils"

export async function create(
table: Omit<Table, "_id" | "_rev">,
rows?: Row[],
userId?: string
): Promise<Table> {
let createdTable: Table
if (isExternal({ table })) {
createdTable = await external.create(table)
} else {
createdTable = await internal.create(table, rows, userId)
}
return createdTable
}
36 changes: 34 additions & 2 deletions packages/server/src/sdk/app/tables/external/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import {
ViewV2,
AutoFieldSubType,
} from "@budibase/types"
import { context } from "@budibase/backend-core"
import { buildExternalTableId } from "../../../../integrations/utils"
import { context, HTTPError } from "@budibase/backend-core"
import {
breakExternalTableId,
buildExternalTableId,
} from "../../../../integrations/utils"
import {
foreignKeyStructure,
hasTypeChanged,
Expand Down Expand Up @@ -86,6 +89,35 @@ function validate(table: Table, oldTable?: Table) {
}
}

function getDatasourceId(table: Table) {
if (!table) {
throw new Error("No table supplied")
}
if (table.sourceId) {
return table.sourceId
}
if (!table._id) {
throw new Error("No table ID supplied")
}
return breakExternalTableId(table._id).datasourceId
}

export async function create(table: Omit<Table, "_id" | "_rev">) {
const datasourceId = getDatasourceId(table)

const tableToCreate = { ...table, created: true }
try {
const result = await save(datasourceId!, tableToCreate)
return result.table
} catch (err: any) {
if (err instanceof Error) {
throw new HTTPError(err.message, 400)
} else {
throw new HTTPError(err?.message || err, err.status || 500)
}
}
}

export async function save(
datasourceId: string,
update: Table,
Expand Down
2 changes: 2 additions & 0 deletions packages/server/src/sdk/app/tables/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { populateExternalTableSchemas } from "./validation"
import * as getters from "./getters"
import * as create from "./create"
import * as updates from "./update"
import * as utils from "./utils"
import { migrate } from "./migration"
import * as sqs from "./internal/sqs"

export default {
populateExternalTableSchemas,
...create,
...updates,
...getters,
...utils,
Expand Down
48 changes: 43 additions & 5 deletions packages/server/src/sdk/app/tables/internal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ViewStatisticsSchema,
ViewV2,
Row,
ContextUser,
TableSourceType,
} from "@budibase/types"
import {
hasTypeChanged,
Expand All @@ -16,18 +16,56 @@ import { EventType, updateLinks } from "../../../../db/linkedRows"
import { cloneDeep } from "lodash/fp"
import isEqual from "lodash/isEqual"
import { runStaticFormulaChecks } from "../../../../api/controllers/table/bulkFormula"
import { context } from "@budibase/backend-core"
import { context, HTTPError } from "@budibase/backend-core"
import { findDuplicateInternalColumns } from "@budibase/shared-core"
import { getTable } from "../getters"
import { checkAutoColumns } from "./utils"
import * as viewsSdk from "../../views"
import { getRowParams } from "../../../../db/utils"
import { generateTableID, getRowParams } from "../../../../db/utils"
import { quotas } from "@budibase/pro"

export async function create(
table: Omit<Table, "_id" | "_rev">,
rows?: Row[],
userId?: string
) {
const tableId = generateTableID()

let tableToSave: Table = {
_id: tableId,
...table,
// Ensure these fields are populated, even if not sent in the request
type: table.type || "table",
sourceType: TableSourceType.INTERNAL,
}

const isImport = !!rows

if (!tableToSave.views) {
tableToSave.views = {}
}

try {
const { table } = await save(tableToSave, {
userId,
rowsToImport: rows,
isImport,
})

return table
} catch (err: any) {
if (err instanceof Error) {
throw new HTTPError(err.message, 400)
} else {
throw new HTTPError(err.message || err, err.status || 500)
}
}
}

export async function save(
table: Table,
opts?: {
user?: ContextUser
userId?: string
tableId?: string
rowsToImport?: Row[]
renaming?: RenameColumn
Expand Down Expand Up @@ -63,7 +101,7 @@ export async function save(
// saving a table is a complex operation, involving many different steps, this
// has been broken out into a utility to make it more obvious/easier to manipulate
const tableSaveFunctions = new TableSaveFunctions({
user: opts?.user,
userId: opts?.userId,
oldTable,
importRows: opts?.rowsToImport,
})
Expand Down

0 comments on commit d29de7c

Please sign in to comment.