Merge pull request #12034 from Budibase/fix/budi-7552-csv-import-messes-up-auto-generated-auto-id-column

Fix bulk import messing up auto ID columns
This commit is contained in:
Michael Drury 2023-10-11 17:23:14 +01:00 committed by GitHub
commit 0e090ade2e
6 changed files with 71 additions and 6 deletions

View File

@ -16,7 +16,9 @@ import { context, events } from "@budibase/backend-core"
import { isRows, isSchema, parse } from "../../../utilities/schema" import { isRows, isSchema, parse } from "../../../utilities/schema"
import { import {
BulkImportRequest, BulkImportRequest,
BulkImportResponse,
Datasource, Datasource,
FieldSchema,
ManyToManyRelationshipFieldMetadata, ManyToManyRelationshipFieldMetadata,
ManyToOneRelationshipFieldMetadata, ManyToOneRelationshipFieldMetadata,
OneToManyRelationshipFieldMetadata, OneToManyRelationshipFieldMetadata,
@ -385,7 +387,9 @@ export async function destroy(ctx: UserCtx) {
return tableToDelete return tableToDelete
} }
export async function bulkImport(ctx: UserCtx<BulkImportRequest>) { export async function bulkImport(
ctx: UserCtx<BulkImportRequest, BulkImportResponse>
) {
const table = await sdk.tables.getTable(ctx.params.tableId) const table = await sdk.tables.getTable(ctx.params.tableId)
const { rows } = ctx.request.body const { rows } = ctx.request.body
const schema = table.schema const schema = table.schema

View File

@ -9,6 +9,7 @@ import { isExternalTable, isSQL } from "../../../integrations/utils"
import { events } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { import {
BulkImportRequest, BulkImportRequest,
BulkImportResponse,
FetchTablesResponse, FetchTablesResponse,
SaveTableRequest, SaveTableRequest,
SaveTableResponse, SaveTableResponse,
@ -19,7 +20,7 @@ import {
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { jsonFromCsvString } from "../../../utilities/csv" import { jsonFromCsvString } from "../../../utilities/csv"
import { builderSocket } from "../../../websockets" import { builderSocket } from "../../../websockets"
import { cloneDeep } from "lodash" import { cloneDeep, isEqual } from "lodash"
function pickApi({ tableId, table }: { tableId?: string; table?: Table }) { function pickApi({ tableId, table }: { tableId?: string; table?: Table }) {
if (table && !tableId) { if (table && !tableId) {
@ -98,9 +99,17 @@ export async function destroy(ctx: UserCtx) {
builderSocket?.emitTableDeletion(ctx, deletedTable) builderSocket?.emitTableDeletion(ctx, deletedTable)
} }
export async function bulkImport(ctx: UserCtx<BulkImportRequest>) { export async function bulkImport(
ctx: UserCtx<BulkImportRequest, BulkImportResponse>
) {
const tableId = ctx.params.tableId 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 // 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 // can only be done in the builder, but in the future we may need to
// think about events for bulk items // think about events for bulk items

View File

@ -11,6 +11,7 @@ import {
import { runStaticFormulaChecks } from "./bulkFormula" import { runStaticFormulaChecks } from "./bulkFormula"
import { import {
BulkImportRequest, BulkImportRequest,
BulkImportResponse,
RenameColumn, RenameColumn,
SaveTableRequest, SaveTableRequest,
SaveTableResponse, SaveTableResponse,
@ -207,7 +208,9 @@ export async function destroy(ctx: any) {
return tableToDelete return tableToDelete
} }
export async function bulkImport(ctx: UserCtx<BulkImportRequest>) { export async function bulkImport(
ctx: UserCtx<BulkImportRequest, BulkImportResponse>
) {
const table = await sdk.tables.getTable(ctx.params.tableId) const table = await sdk.tables.getTable(ctx.params.tableId)
const { rows, identifierFields } = ctx.request.body const { rows, identifierFields } = ctx.request.body
await handleDataImport(ctx.user, table, rows, identifierFields) await handleDataImport(ctx.user, table, rows, identifierFields)

View File

@ -1,4 +1,3 @@
import { generator } from "@budibase/backend-core/tests"
import { events, context } from "@budibase/backend-core" import { events, context } from "@budibase/backend-core"
import { import {
FieldType, FieldType,
@ -6,6 +5,7 @@ import {
RelationshipType, RelationshipType,
Table, Table,
ViewCalculation, ViewCalculation,
AutoFieldSubTypes,
} from "@budibase/types" } from "@budibase/types"
import { checkBuilderEndpoint } from "./utilities/TestFunctions" import { checkBuilderEndpoint } from "./utilities/TestFunctions"
import * as setup from "./utilities" import * as setup from "./utilities"
@ -188,6 +188,36 @@ describe("/tables", () => {
1 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", () => { describe("fetch", () => {

View File

@ -4,6 +4,8 @@ import {
Row, Row,
ValidateResponse, ValidateResponse,
ExportRowsRequest, ExportRowsRequest,
BulkImportRequest,
BulkImportResponse,
} from "@budibase/types" } from "@budibase/types"
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base" import { TestAPI } from "./base"
@ -123,6 +125,19 @@ export class RowAPI extends TestAPI {
return request return request
} }
bulkImport = async (
tableId: string,
body: BulkImportRequest,
{ expectStatus } = { expectStatus: 200 }
): Promise<BulkImportResponse> => {
let request = this.request
.post(`/api/tables/${tableId}/import`)
.send(body)
.set(this.config.defaultHeaders())
.expect(expectStatus)
return (await request).body
}
search = async ( search = async (
sourceId: string, sourceId: string,
{ expectStatus } = { expectStatus: 200 } { expectStatus } = { expectStatus: 200 }

View File

@ -29,3 +29,7 @@ export interface BulkImportRequest {
rows: Row[] rows: Row[]
identifierFields?: Array<string> identifierFields?: Array<string>
} }
export interface BulkImportResponse {
message: string
}