diff --git a/packages/server/src/api/controllers/table/external.ts b/packages/server/src/api/controllers/table/external.ts index 2128e12c9c..967176c2e4 100644 --- a/packages/server/src/api/controllers/table/external.ts +++ b/packages/server/src/api/controllers/table/external.ts @@ -16,7 +16,9 @@ import { context, events } from "@budibase/backend-core" import { isRows, isSchema, parse } from "../../../utilities/schema" import { BulkImportRequest, + BulkImportResponse, Datasource, + FieldSchema, ManyToManyRelationshipFieldMetadata, ManyToOneRelationshipFieldMetadata, OneToManyRelationshipFieldMetadata, @@ -385,7 +387,9 @@ export async function destroy(ctx: UserCtx) { return tableToDelete } -export async function bulkImport(ctx: UserCtx) { +export async function bulkImport( + ctx: UserCtx +) { const table = await sdk.tables.getTable(ctx.params.tableId) const { rows } = ctx.request.body const schema = table.schema diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index e1956e33c0..44f673f284 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -9,6 +9,7 @@ import { isExternalTable, isSQL } from "../../../integrations/utils" import { events } from "@budibase/backend-core" import { BulkImportRequest, + BulkImportResponse, FetchTablesResponse, SaveTableRequest, SaveTableResponse, @@ -19,7 +20,7 @@ import { import sdk from "../../../sdk" import { jsonFromCsvString } from "../../../utilities/csv" import { builderSocket } from "../../../websockets" -import { cloneDeep } from "lodash" +import { cloneDeep, isEqual } from "lodash" function pickApi({ tableId, table }: { tableId?: string; table?: Table }) { if (table && !tableId) { @@ -98,9 +99,17 @@ export async function destroy(ctx: UserCtx) { builderSocket?.emitTableDeletion(ctx, deletedTable) } -export async function bulkImport(ctx: UserCtx) { +export async function bulkImport( + ctx: UserCtx +) { const tableId = ctx.params.tableId - await pickApi({ tableId }).bulkImport(ctx) + let tableBefore = await sdk.tables.getTable(tableId) + let tableAfter = await pickApi({ tableId }).bulkImport(ctx) + + if (!isEqual(tableBefore, tableAfter)) { + await sdk.tables.saveTable(tableAfter) + } + // right now we don't trigger anything for bulk import because it // can only be done in the builder, but in the future we may need to // think about events for bulk items diff --git a/packages/server/src/api/controllers/table/internal.ts b/packages/server/src/api/controllers/table/internal.ts index 11be19a8a7..eeb4a9eb5f 100644 --- a/packages/server/src/api/controllers/table/internal.ts +++ b/packages/server/src/api/controllers/table/internal.ts @@ -11,6 +11,7 @@ import { import { runStaticFormulaChecks } from "./bulkFormula" import { BulkImportRequest, + BulkImportResponse, RenameColumn, SaveTableRequest, SaveTableResponse, @@ -207,7 +208,9 @@ export async function destroy(ctx: any) { return tableToDelete } -export async function bulkImport(ctx: UserCtx) { +export async function bulkImport( + ctx: UserCtx +) { const table = await sdk.tables.getTable(ctx.params.tableId) const { rows, identifierFields } = ctx.request.body await handleDataImport(ctx.user, table, rows, identifierFields) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 061e7a7217..ded54729b9 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -1,4 +1,3 @@ -import { generator } from "@budibase/backend-core/tests" import { events, context } from "@budibase/backend-core" import { FieldType, @@ -6,6 +5,7 @@ import { RelationshipType, Table, ViewCalculation, + AutoFieldSubTypes, } from "@budibase/types" import { checkBuilderEndpoint } from "./utilities/TestFunctions" import * as setup from "./utilities" @@ -188,6 +188,36 @@ describe("/tables", () => { 1 ) }) + + it("should update Auto ID field after bulk import", async () => { + const table = await config.createTable({ + name: "TestTable", + type: "table", + schema: { + autoId: { + name: "id", + type: FieldType.NUMBER, + subtype: AutoFieldSubTypes.AUTO_ID, + autocolumn: true, + constraints: { + type: "number", + presence: false, + }, + }, + }, + }) + + let row = await config.api.row.save(table._id!, {}) + expect(row.autoId).toEqual(1) + + await config.api.row.bulkImport(table._id!, { + rows: [{ autoId: 2 }], + identifierFields: [], + }) + + row = await config.api.row.save(table._id!, {}) + expect(row.autoId).toEqual(3) + }) }) describe("fetch", () => { diff --git a/packages/server/src/tests/utilities/api/row.ts b/packages/server/src/tests/utilities/api/row.ts index adeb96a593..bb880bb7da 100644 --- a/packages/server/src/tests/utilities/api/row.ts +++ b/packages/server/src/tests/utilities/api/row.ts @@ -4,6 +4,8 @@ import { Row, ValidateResponse, ExportRowsRequest, + BulkImportRequest, + BulkImportResponse, } from "@budibase/types" import TestConfiguration from "../TestConfiguration" import { TestAPI } from "./base" @@ -123,6 +125,19 @@ export class RowAPI extends TestAPI { return request } + bulkImport = async ( + tableId: string, + body: BulkImportRequest, + { expectStatus } = { expectStatus: 200 } + ): Promise => { + let request = this.request + .post(`/api/tables/${tableId}/import`) + .send(body) + .set(this.config.defaultHeaders()) + .expect(expectStatus) + return (await request).body + } + search = async ( sourceId: string, { expectStatus } = { expectStatus: 200 } diff --git a/packages/types/src/api/web/app/table.ts b/packages/types/src/api/web/app/table.ts index 8fb0297a9e..cb5faaa9ea 100644 --- a/packages/types/src/api/web/app/table.ts +++ b/packages/types/src/api/web/app/table.ts @@ -29,3 +29,7 @@ export interface BulkImportRequest { rows: Row[] identifierFields?: Array } + +export interface BulkImportResponse { + message: string +}