Merge branch 'master' of github.com:Budibase/budibase into frontend-core-ts-2
This commit is contained in:
commit
cb8f05291a
|
@ -4,8 +4,8 @@ import {
|
|||
getContainerRuntimeClient,
|
||||
} from "testcontainers"
|
||||
import { ContainerInfo } from "dockerode"
|
||||
import path from "path"
|
||||
import lockfile from "proper-lockfile"
|
||||
import * as path from "path"
|
||||
import * as lockfile from "proper-lockfile"
|
||||
import { execSync } from "child_process"
|
||||
|
||||
interface DockerContext {
|
||||
|
@ -29,8 +29,8 @@ function getCurrentDockerContext(): DockerContext {
|
|||
|
||||
async function getBudibaseContainers() {
|
||||
const client = await getContainerRuntimeClient()
|
||||
const conatiners = await client.container.list()
|
||||
return conatiners.filter(
|
||||
const containers = await client.container.list()
|
||||
return containers.filter(
|
||||
container =>
|
||||
container.Labels["com.budibase"] === "true" &&
|
||||
container.Labels["org.testcontainers"] === "true"
|
||||
|
|
|
@ -59,11 +59,15 @@ export function isExternalTable(table: Table) {
|
|||
}
|
||||
|
||||
export function buildExternalTableId(datasourceId: string, tableName: string) {
|
||||
// encode spaces
|
||||
if (tableName.includes(" ")) {
|
||||
tableName = encodeURIComponent(tableName)
|
||||
return `${datasourceId}${DOUBLE_SEPARATOR}${encodeURIComponent(tableName)}`
|
||||
}
|
||||
|
||||
export function encodeTableId(tableId: string) {
|
||||
if (isExternalTableID(tableId)) {
|
||||
return encodeURIComponent(tableId)
|
||||
} else {
|
||||
return tableId
|
||||
}
|
||||
return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`
|
||||
}
|
||||
|
||||
export function breakExternalTableId(tableId: string) {
|
||||
|
|
|
@ -288,19 +288,21 @@ function replaceTableNamesInFilters(
|
|||
for (const key of Object.keys(filter)) {
|
||||
const matches = key.match(`^(?<relation>.+)\\.(?<field>.+)`)
|
||||
|
||||
const relation = matches?.groups?.["relation"]
|
||||
// this is the possible table name which we need to check if it needs to be converted
|
||||
const relatedTableName = matches?.groups?.["relation"]
|
||||
const field = matches?.groups?.["field"]
|
||||
|
||||
if (!relation || !field) {
|
||||
if (!relatedTableName || !field) {
|
||||
continue
|
||||
}
|
||||
|
||||
const table = allTables.find(r => r._id === tableId)!
|
||||
if (Object.values(table.schema).some(f => f.name === relation)) {
|
||||
const table = allTables.find(r => r._id === tableId)
|
||||
const isColumnName = !!table?.schema[relatedTableName]
|
||||
if (!table || isColumnName) {
|
||||
continue
|
||||
}
|
||||
|
||||
const matchedTable = allTables.find(t => t.name === relation)
|
||||
const matchedTable = allTables.find(t => t.name === relatedTableName)
|
||||
const relationship = Object.values(table.schema).find(
|
||||
f => isRelationshipField(f) && f.tableId === matchedTable?._id
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as utils from "../../../../db/utils"
|
||||
|
||||
import { docIds } from "@budibase/backend-core"
|
||||
import { docIds, sql } from "@budibase/backend-core"
|
||||
import {
|
||||
Ctx,
|
||||
DatasourcePlusQueryResponse,
|
||||
|
@ -69,15 +69,15 @@ export function getSourceId(ctx: Ctx): { tableId: string; viewId?: string } {
|
|||
viewId: sourceId,
|
||||
}
|
||||
}
|
||||
return { tableId: ctx.params.sourceId }
|
||||
return { tableId: sql.utils.encodeTableId(ctx.params.sourceId) }
|
||||
}
|
||||
// now check for old way of specifying table ID
|
||||
if (ctx.params?.tableId) {
|
||||
return { tableId: ctx.params.tableId }
|
||||
return { tableId: sql.utils.encodeTableId(ctx.params.tableId) }
|
||||
}
|
||||
// check body for a table ID
|
||||
if (ctx.request.body?.tableId) {
|
||||
return { tableId: ctx.request.body.tableId }
|
||||
return { tableId: sql.utils.encodeTableId(ctx.request.body.tableId) }
|
||||
}
|
||||
throw new Error("Unable to find table ID in request")
|
||||
}
|
||||
|
|
|
@ -71,18 +71,27 @@ if (descriptions.length) {
|
|||
let tableOrViewId: string
|
||||
let rows: Row[]
|
||||
|
||||
async function basicRelationshipTables(type: RelationshipType) {
|
||||
async function basicRelationshipTables(
|
||||
type: RelationshipType,
|
||||
opts?: {
|
||||
tableName?: string
|
||||
primaryColumn?: string
|
||||
otherColumn?: string
|
||||
}
|
||||
) {
|
||||
const relatedTable = await createTable({
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
name: { name: opts?.tableName || "name", type: FieldType.STRING },
|
||||
})
|
||||
|
||||
const columnName = opts?.primaryColumn || "productCat"
|
||||
//@ts-ignore - API accepts this structure, will build out rest of definition
|
||||
const tableId = await createTable({
|
||||
name: { name: "name", type: FieldType.STRING },
|
||||
//@ts-ignore - API accepts this structure, will build out rest of definition
|
||||
productCat: {
|
||||
name: { name: opts?.tableName || "name", type: FieldType.STRING },
|
||||
[columnName]: {
|
||||
type: FieldType.LINK,
|
||||
relationshipType: type,
|
||||
name: "productCat",
|
||||
fieldName: "product",
|
||||
name: columnName,
|
||||
fieldName: opts?.otherColumn || "product",
|
||||
tableId: relatedTable,
|
||||
constraints: {
|
||||
type: "array",
|
||||
|
@ -2776,6 +2785,42 @@ if (descriptions.length) {
|
|||
})
|
||||
})
|
||||
|
||||
isSql &&
|
||||
describe("relationship - table with spaces", () => {
|
||||
let primaryTable: Table, row: Row
|
||||
|
||||
beforeAll(async () => {
|
||||
const { relatedTable, tableId } =
|
||||
await basicRelationshipTables(
|
||||
RelationshipType.ONE_TO_MANY,
|
||||
{
|
||||
tableName: "table with spaces",
|
||||
primaryColumn: "related",
|
||||
otherColumn: "related",
|
||||
}
|
||||
)
|
||||
tableOrViewId = tableId
|
||||
primaryTable = relatedTable
|
||||
|
||||
row = await config.api.row.save(primaryTable._id!, {
|
||||
name: "foo",
|
||||
})
|
||||
|
||||
await config.api.row.save(tableOrViewId, {
|
||||
name: "foo",
|
||||
related: [row._id],
|
||||
})
|
||||
})
|
||||
|
||||
it("should be able to search by table name with spaces", async () => {
|
||||
await expectQuery({
|
||||
equal: {
|
||||
["table with spaces.name"]: "foo",
|
||||
},
|
||||
}).toContain([{ name: "foo" }])
|
||||
})
|
||||
})
|
||||
|
||||
isSql &&
|
||||
describe.each([
|
||||
RelationshipType.MANY_TO_ONE,
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { context, db as dbCore, docIds, utils } from "@budibase/backend-core"
|
||||
import {
|
||||
context,
|
||||
db as dbCore,
|
||||
docIds,
|
||||
utils,
|
||||
sql,
|
||||
} from "@budibase/backend-core"
|
||||
import {
|
||||
DatabaseQueryOpts,
|
||||
Datasource,
|
||||
|
@ -328,7 +334,7 @@ export function extractViewInfoFromID(viewId: string) {
|
|||
const regex = new RegExp(`^(?<tableId>.+)${SEPARATOR}([^${SEPARATOR}]+)$`)
|
||||
const res = regex.exec(viewId)
|
||||
return {
|
||||
tableId: res!.groups!["tableId"],
|
||||
tableId: sql.utils.encodeTableId(res!.groups!["tableId"]),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue