Getting composite keys working, fixing p2 issue and adding test case for it.
This commit is contained in:
parent
9733ba5f95
commit
efafb3e3c2
|
@ -28,16 +28,25 @@ function generateSchema(
|
|||
oldTable: null | Table = null,
|
||||
renamed?: RenameColumn
|
||||
) {
|
||||
let primaryKey = table && table.primary ? table.primary[0] : null
|
||||
let primaryKeys = table && table.primary ? table.primary : []
|
||||
const columns = Object.values(table.schema)
|
||||
// all columns in a junction table will be meta
|
||||
let metaCols = columns.filter(col => (col as NumberFieldMetadata).meta)
|
||||
let isJunction = metaCols.length === columns.length
|
||||
let columnTypeSet: string[] = []
|
||||
|
||||
// can't change primary once its set for now
|
||||
if (primaryKey && !oldTable && !isJunction) {
|
||||
schema.increments(primaryKey).primary()
|
||||
} else if (!oldTable && isJunction) {
|
||||
schema.primary(metaCols.map(col => col.name))
|
||||
if (!oldTable) {
|
||||
// junction tables are special - we have an expected format
|
||||
if (isJunction) {
|
||||
schema.primary(metaCols.map(col => col.name))
|
||||
} else if (primaryKeys.length === 1) {
|
||||
schema.increments(primaryKeys[0]).primary()
|
||||
// note that we've set its type
|
||||
columnTypeSet.push(primaryKeys[0])
|
||||
} else {
|
||||
schema.primary(primaryKeys)
|
||||
}
|
||||
}
|
||||
|
||||
// check if any columns need added
|
||||
|
@ -49,7 +58,7 @@ function generateSchema(
|
|||
const oldColumn = oldTable ? oldTable.schema[key] : null
|
||||
if (
|
||||
(oldColumn && oldColumn.type) ||
|
||||
(primaryKey === key && !isJunction) ||
|
||||
columnTypeSet.includes(key) ||
|
||||
renamed?.updated === key
|
||||
) {
|
||||
continue
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import dayjs from "dayjs"
|
||||
import {
|
||||
ArrayOperator,
|
||||
AutoFieldSubType,
|
||||
AutoReason,
|
||||
Datasource,
|
||||
|
@ -196,11 +197,12 @@ export class ExternalRequest<T extends Operation> {
|
|||
// need to map over the filters and make sure the _id field isn't present
|
||||
let prefix = 1
|
||||
for (const operator of Object.values(filters)) {
|
||||
const isArrayOperator = Object.values(ArrayOperator).includes(operator)
|
||||
for (const field of Object.keys(operator || {})) {
|
||||
if (dbCore.removeKeyNumbering(field) === "_id") {
|
||||
if (primary) {
|
||||
const parts = breakRowIdField(operator[field])
|
||||
if (primary.length > 1) {
|
||||
if (primary.length > 1 && isArrayOperator) {
|
||||
operator[InternalSearchFilterOperator.COMPLEX_ID_OPERATOR] = {
|
||||
id: primary,
|
||||
values: parts[0],
|
||||
|
|
|
@ -39,6 +39,7 @@ import { dataFilters } from "@budibase/shared-core"
|
|||
import { Knex } from "knex"
|
||||
import { structures } from "@budibase/backend-core/tests"
|
||||
import { DEFAULT_EMPLOYEE_TABLE_SCHEMA } from "../../../db/defaultData/datasource_bb_default"
|
||||
import { generateRowIdField } from "../../../integrations/utils"
|
||||
|
||||
describe.each([
|
||||
["in-memory", undefined],
|
||||
|
@ -2648,6 +2649,42 @@ describe.each([
|
|||
})
|
||||
})
|
||||
|
||||
!isInternal &&
|
||||
describe("search by composite key", () => {
|
||||
beforeAll(async () => {
|
||||
table = await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
schema: {
|
||||
idColumn1: {
|
||||
name: "idColumn1",
|
||||
type: FieldType.NUMBER,
|
||||
},
|
||||
idColumn2: {
|
||||
name: "idColumn2",
|
||||
type: FieldType.NUMBER,
|
||||
},
|
||||
},
|
||||
primary: ["idColumn1", "idColumn2"],
|
||||
})
|
||||
)
|
||||
await createRows([{ idColumn1: 1, idColumn2: 2 }])
|
||||
})
|
||||
|
||||
it("can filter by the row ID with limit 1", async () => {
|
||||
await expectSearch({
|
||||
query: {
|
||||
equal: { _id: generateRowIdField([1, 2]) },
|
||||
},
|
||||
limit: 1,
|
||||
}).toContain([
|
||||
{
|
||||
idColumn1: 1,
|
||||
idColumn2: 2,
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
isSql &&
|
||||
describe("pagination edge case with relationships", () => {
|
||||
let mainRows: Row[] = []
|
||||
|
|
|
@ -146,7 +146,8 @@ export function parse(rows: Rows, table: Table): Rows {
|
|||
return rows.map(row => {
|
||||
const parsedRow: Row = {}
|
||||
|
||||
Object.entries(row).forEach(([columnName, columnData]) => {
|
||||
Object.keys(row).forEach(columnName => {
|
||||
const columnData = row[columnName]
|
||||
const schema = table.schema
|
||||
if (!(columnName in schema)) {
|
||||
// Objects can be present in the row data but not in the schema, so make sure we don't proceed in such a case
|
||||
|
|
Loading…
Reference in New Issue