Skip to content

Commit

Permalink
Getting composite keys working, fixing p2 issue and adding test case …
Browse files Browse the repository at this point in the history
…for it.
  • Loading branch information
mike12345567 committed Aug 8, 2024
1 parent 9733ba5 commit efafb3e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
21 changes: 15 additions & 6 deletions packages/backend-core/src/sql/sqlTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/server/src/api/controllers/row/ExternalRequest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dayjs from "dayjs"
import {
ArrayOperator,
AutoFieldSubType,
AutoReason,
Datasource,
Expand Down Expand Up @@ -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],
Expand Down
37 changes: 37 additions & 0 deletions packages/server/src/api/routes/tests/search.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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[] = []
Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/utilities/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit efafb3e

Please sign in to comment.