1
0
Fork 0
mirror of synced 2024-09-20 11:27:56 +12:00

Getting composite keys working, fixing p2 issue and adding test case for it.

This commit is contained in:
mike12345567 2024-08-08 18:55:41 +01:00
parent 9733ba5f95
commit efafb3e3c2
4 changed files with 57 additions and 8 deletions

View file

@ -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

View file

@ -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],

View file

@ -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[] = []

View file

@ -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