Move responsability to sql utils

This commit is contained in:
Adria Navarro 2024-12-17 13:02:34 +01:00
parent 95f7eeacce
commit 8765a28f04
3 changed files with 31 additions and 70 deletions

View File

@ -272,20 +272,6 @@ class InternalBuilder {
return parts.join(".") return parts.join(".")
} }
private isFullSelectStatementRequired(includedFields: string[]): boolean {
for (const column of Object.values(this.table.schema)) {
if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(column)) {
return true
} else if (
column.type === FieldType.FORMULA &&
includedFields.includes(column.name)
) {
return true
}
}
return false
}
private generateSelectStatement(): (string | Knex.Raw)[] | "*" { private generateSelectStatement(): (string | Knex.Raw)[] | "*" {
const { table, resource } = this.query const { table, resource } = this.query
@ -313,13 +299,6 @@ class InternalBuilder {
}) })
.filter(({ table }) => !table || table === alias) .filter(({ table }) => !table || table === alias)
const requestedTableColumns = tableFields.map(({ column }) =>
column.replace(new RegExp(`^${this.query.meta?.columnPrefix}`), "")
)
if (this.isFullSelectStatementRequired(requestedTableColumns)) {
return [this.knex.raw("??", [`${alias}.*`])]
}
return tableFields.map(({ table, column, field }) => { return tableFields.map(({ table, column, field }) => {
const columnSchema = schema[column] const columnSchema = schema[column]

View File

@ -14,7 +14,7 @@ import {
import { breakExternalTableId } from "../../../../integrations/utils" import { breakExternalTableId } from "../../../../integrations/utils"
import { generateJunctionTableID } from "../../../../db/utils" import { generateJunctionTableID } from "../../../../db/utils"
import sdk from "../../../../sdk" import sdk from "../../../../sdk"
import { helpers } from "@budibase/shared-core" import { helpers, PROTECTED_INTERNAL_COLUMNS } from "@budibase/shared-core"
import { sql } from "@budibase/backend-core" import { sql } from "@budibase/backend-core"
type TableMap = Record<string, Table> type TableMap = Record<string, Table>
@ -126,11 +126,9 @@ export async function buildSqlFieldList(
column.type !== FieldType.LINK && column.type !== FieldType.LINK &&
column.type !== FieldType.FORMULA && column.type !== FieldType.FORMULA &&
column.type !== FieldType.AI && column.type !== FieldType.AI &&
!existing.find( !existing.find((field: string) => field === columnName)
(field: string) => field === `${table.name}.${columnName}`
)
) )
.map(([columnName]) => `${table.name}.${columnName}`) .map(([columnName]) => columnName)
} }
function getRequiredFields(table: Table, existing: string[] = []) { function getRequiredFields(table: Table, existing: string[] = []) {
@ -143,15 +141,12 @@ export async function buildSqlFieldList(
} }
if (!sql.utils.isExternalTable(table)) { if (!sql.utils.isExternalTable(table)) {
requiredFields.push(...["_id", "_rev", "_tableId"]) requiredFields.push(...PROTECTED_INTERNAL_COLUMNS)
} }
return requiredFields return requiredFields.filter(
.filter( column => !existing.find((field: string) => field === column)
column => )
!existing.find((field: string) => field === `${table.name}.${column}`)
)
.map(column => `${table.name}.${column}`)
} }
let fields: string[] = [] let fields: string[] = []
@ -161,30 +156,34 @@ export async function buildSqlFieldList(
let table: Table let table: Table
if (isView) { if (isView) {
table = await sdk.views.getTable(source.id) table = await sdk.views.getTable(source.id)
fields = Object.keys(helpers.views.basicFields(source)).filter(
f => table.schema[f].type !== FieldType.LINK
)
} else { } else {
table = source table = source
}
if (isView) {
fields = Object.keys(helpers.views.basicFields(source))
.filter(f => table.schema[f].type !== FieldType.LINK)
.map(c => `${table.name}.${c}`)
if (!helpers.views.isCalculationView(source)) {
fields.push(
...getRequiredFields(
{
...table,
primaryDisplay: source.primaryDisplay || table.primaryDisplay,
},
fields
)
)
}
} else {
fields = extractRealFields(source) fields = extractRealFields(source)
} }
// If are requesting for a formula field, we need to retrieve all fields
if (fields.find(f => table.schema[f]?.type === FieldType.FORMULA)) {
fields = extractRealFields(table)
}
if (!isView || !helpers.views.isCalculationView(source)) {
fields.push(
...getRequiredFields(
{
...table,
primaryDisplay: source.primaryDisplay || table.primaryDisplay,
},
fields
)
)
}
fields = fields.map(c => `${table.name}.${c}`)
for (const field of Object.values(table.schema)) { for (const field of Object.values(table.schema)) {
if (field.type !== FieldType.LINK || !relationships || !field.tableId) { if (field.type !== FieldType.LINK || !relationships || !field.tableId) {
continue continue
@ -227,7 +226,7 @@ export async function buildSqlFieldList(
} }
} }
return fields return [...new Set(fields)]
} }
export function isKnexEmptyReadResponse(resp: DatasourcePlusQueryResponse) { export function isKnexEmptyReadResponse(resp: DatasourcePlusQueryResponse) {

View File

@ -8,7 +8,6 @@ import {
TableSchema, TableSchema,
Table, Table,
TableSourceType, TableSourceType,
FieldType,
} from "@budibase/types" } from "@budibase/types"
import { sql } from "@budibase/backend-core" import { sql } from "@budibase/backend-core"
import { join } from "path" import { join } from "path"
@ -95,22 +94,6 @@ describe("Captures of real examples", () => {
}) })
}) })
it("should retrieve all fields if a formula column is requested", () => {
const queryJson = getJson("basicFetch.json")
queryJson.table.schema["formula"] = {
name: "formula",
type: FieldType.FORMULA,
formula: "any",
}
queryJson.resource!.fields.push("formula")
let query = new Sql(SqlClient.POSTGRES)._query(queryJson)
expect(query).toEqual({
bindings: [primaryLimit],
sql: `select "a".* from "persons" as "a" order by "a"."firstname" asc nulls first, "a"."personid" asc limit $1`,
})
})
it("should handle basic retrieval with relationships", () => { it("should handle basic retrieval with relationships", () => {
const queryJson = getJson("basicFetchWithRelationships.json") const queryJson = getJson("basicFetchWithRelationships.json")
let query = new Sql(SqlClient.POSTGRES, relationshipLimit)._query( let query = new Sql(SqlClient.POSTGRES, relationshipLimit)._query(