Handle composite keys on exports
This commit is contained in:
parent
85827bbf93
commit
5be8882122
|
@ -172,6 +172,8 @@ function convertBooleans(query: SqlQuery | SqlQuery[]): SqlQuery | SqlQuery[] {
|
|||
return query
|
||||
}
|
||||
|
||||
const COMPLEX_ID_OPERATOR = "_complexIdOperator"
|
||||
|
||||
class InternalBuilder {
|
||||
private readonly client: string
|
||||
|
||||
|
@ -214,7 +216,14 @@ class InternalBuilder {
|
|||
for (let [key, value] of Object.entries(structure)) {
|
||||
const updatedKey = dbCore.removeKeyNumbering(key)
|
||||
const isRelationshipField = updatedKey.includes(".")
|
||||
if (!opts.relationship && !isRelationshipField) {
|
||||
|
||||
if (updatedKey === COMPLEX_ID_OPERATOR) {
|
||||
const alias = getTableAlias(tableName)
|
||||
fn(
|
||||
value.id.map((x: string) => (alias ? `${alias}.${x}` : x)),
|
||||
value.values
|
||||
)
|
||||
} else if (!opts.relationship && !isRelationshipField) {
|
||||
const alias = getTableAlias(tableName)
|
||||
fn(alias ? `${alias}.${updatedKey}` : updatedKey, value)
|
||||
} else if (opts.relationship && isRelationshipField) {
|
||||
|
@ -745,6 +754,9 @@ class InternalBuilder {
|
|||
|
||||
class SqlQueryBuilder extends SqlTableQueryBuilder {
|
||||
private readonly limit: number
|
||||
|
||||
public static COMPLEX_ID_OPERATOR = COMPLEX_ID_OPERATOR
|
||||
|
||||
// pass through client to get flavour of SQL
|
||||
constructor(client: string, limit: number = BASE_LIMIT) {
|
||||
super(client)
|
||||
|
|
|
@ -40,7 +40,7 @@ import {
|
|||
} from "../../../sdk/app/rows/utils"
|
||||
import { processObjectSync } from "@budibase/string-templates"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import { db as dbCore } from "@budibase/backend-core"
|
||||
import { db as dbCore, sql } from "@budibase/backend-core"
|
||||
import sdk from "../../../sdk"
|
||||
import env from "../../../environment"
|
||||
import { makeExternalQuery } from "../../../integrations/base/query"
|
||||
|
@ -193,11 +193,26 @@ export class ExternalRequest<T extends Operation> {
|
|||
for (let field of Object.keys(operator || {})) {
|
||||
if (dbCore.removeKeyNumbering(field) === "_id") {
|
||||
if (primary) {
|
||||
const parts = breakRowIdField(operator[field])
|
||||
for (let field of primary) {
|
||||
operator[`${prefix}:${field}`] = parts.shift()
|
||||
let idField = operator[field]
|
||||
try {
|
||||
// Make sure _id queries decode the Row IDs
|
||||
idField = JSON.parse(idField)
|
||||
} catch {
|
||||
// It is not a JSON value
|
||||
}
|
||||
|
||||
const parts = breakRowIdField(idField)
|
||||
if (primary.length > 1) {
|
||||
operator[sql.Sql.COMPLEX_ID_OPERATOR] = {
|
||||
id: primary,
|
||||
values: parts,
|
||||
}
|
||||
} else {
|
||||
for (let field of primary) {
|
||||
operator[`${prefix}:${field}`] = parts.shift()
|
||||
}
|
||||
prefix++
|
||||
}
|
||||
prefix++
|
||||
}
|
||||
// make sure this field doesn't exist on any filter
|
||||
delete operator[field]
|
||||
|
|
|
@ -1428,22 +1428,6 @@ describe.each([
|
|||
expect(row._id).toEqual(existing._id)
|
||||
})
|
||||
|
||||
it("should return an error on composite keys", async () => {
|
||||
const existing = await config.api.row.save(table._id!, {})
|
||||
await config.api.row.exportRows(
|
||||
table._id!,
|
||||
{
|
||||
rows: [`['${existing._id!}']`, "['d001', '10111']"],
|
||||
},
|
||||
{
|
||||
status: 400,
|
||||
body: {
|
||||
message: "Export data does not support composite keys.",
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("should return an error if no table is found", async () => {
|
||||
const existing = await config.api.row.save(table._id!, {})
|
||||
await config.api.row.exportRows(
|
||||
|
@ -1453,7 +1437,7 @@ describe.each([
|
|||
)
|
||||
})
|
||||
|
||||
it("can export rows with composite primary keys", async () => {
|
||||
it("should handle filtering by composite primary keys", async () => {
|
||||
const tableRequest = saveTableRequest({
|
||||
primary: ["number", "string"],
|
||||
schema: {
|
||||
|
|
|
@ -158,10 +158,7 @@ export async function exportRows(
|
|||
_id: rowIds.map((row: string) => {
|
||||
const ids = breakRowIdField(row)
|
||||
if (ids.length > 1) {
|
||||
throw new HTTPError(
|
||||
"Export data does not support composite keys.",
|
||||
400
|
||||
)
|
||||
return ids
|
||||
}
|
||||
return ids[0]
|
||||
}),
|
||||
|
|
Loading…
Reference in New Issue