Adding missing files.

This commit is contained in:
mike12345567 2024-03-04 15:47:27 +00:00
parent 7b7d10d1ff
commit 02e3b36cd8
5 changed files with 172 additions and 50 deletions

View File

@ -107,57 +107,62 @@ export default class AliasTables {
} }
async queryWithAliasing(json: QueryJson): DatasourcePlusQueryResponse { async queryWithAliasing(json: QueryJson): DatasourcePlusQueryResponse {
json = cloneDeep(json) const fieldLength = json.resource?.fields?.length
const aliasTable = (table: Table) => ({ const aliasingEnabled = fieldLength && fieldLength > 0
...table, if (aliasingEnabled) {
name: this.getAlias(table.name), json = cloneDeep(json)
}) const aliasTable = (table: Table) => ({
// run through the query json to update anywhere a table may be used ...table,
if (json.resource?.fields) { name: this.getAlias(table.name),
json.resource.fields = json.resource.fields.map(field => originalName: table.name,
this.aliasField(field) })
) // run through the query json to update anywhere a table may be used
} if (json.resource?.fields) {
if (json.filters) { json.resource.fields = json.resource.fields.map(field =>
for (let [filterKey, filter] of Object.entries(json.filters)) { this.aliasField(field)
if (typeof filter !== "object") { )
continue
}
const aliasedFilters: typeof filter = {}
for (let key of Object.keys(filter)) {
aliasedFilters[this.aliasField(key)] = filter[key]
}
json.filters[filterKey as keyof SearchFilters] = aliasedFilters
} }
} if (json.filters) {
if (json.relationships) { for (let [filterKey, filter] of Object.entries(json.filters)) {
json.relationships = json.relationships.map(relationship => ({ if (typeof filter !== "object") {
...relationship, continue
aliases: this.aliasMap([ }
relationship.through, const aliasedFilters: typeof filter = {}
relationship.tableName, for (let key of Object.keys(filter)) {
json.endpoint.entityId, aliasedFilters[this.aliasField(key)] = filter[key]
]), }
})) json.filters[filterKey as keyof SearchFilters] = aliasedFilters
} }
if (json.meta?.table) {
json.meta.table = aliasTable(json.meta.table)
}
if (json.meta?.tables) {
const aliasedTables: Record<string, Table> = {}
for (let [tableName, table] of Object.entries(json.meta.tables)) {
aliasedTables[this.getAlias(tableName)] = aliasTable(table)
} }
json.meta.tables = aliasedTables if (json.relationships) {
json.relationships = json.relationships.map(relationship => ({
...relationship,
aliases: this.aliasMap([
relationship.through,
relationship.tableName,
json.endpoint.entityId,
]),
}))
}
if (json.meta?.table) {
json.meta.table = aliasTable(json.meta.table)
}
if (json.meta?.tables) {
const aliasedTables: Record<string, Table> = {}
for (let [tableName, table] of Object.entries(json.meta.tables)) {
aliasedTables[this.getAlias(tableName)] = aliasTable(table)
}
json.meta.tables = aliasedTables
}
// invert and return
const invertedTableAliases: Record<string, string> = {}
for (let [key, value] of Object.entries(this.tableAliases)) {
invertedTableAliases[value] = key
}
json.tableAliases = invertedTableAliases
} }
// invert and return
const invertedTableAliases: Record<string, string> = {}
for (let [key, value] of Object.entries(this.tableAliases)) {
invertedTableAliases[value] = key
}
json.tableAliases = invertedTableAliases
const response = await getDatasourceAndQuery(json) const response = await getDatasourceAndQuery(json)
if (Array.isArray(response)) { if (Array.isArray(response) && aliasingEnabled) {
return this.reverse(response) return this.reverse(response)
} else { } else {
return response return response

View File

@ -9,9 +9,12 @@ import {
RelationshipsJson, RelationshipsJson,
SearchFilters, SearchFilters,
SortDirection, SortDirection,
Table,
} from "@budibase/types" } from "@budibase/types"
import environment from "../../environment" import environment from "../../environment"
type QueryFunction = (query: Knex.SqlNative, operation: Operation) => any
const envLimit = environment.SQL_MAX_ROWS const envLimit = environment.SQL_MAX_ROWS
? parseInt(environment.SQL_MAX_ROWS) ? parseInt(environment.SQL_MAX_ROWS)
: null : null
@ -117,6 +120,29 @@ function generateSelectStatement(
}) })
} }
function disableAliasing(json: QueryJson) {
if (json.tableAliases) {
json.tableAliases = undefined
}
const removeTableAlias = (table: Table) => {
if (table.originalName) {
table.name = table.originalName
}
return table
}
if (json.meta?.table) {
json.meta.table = removeTableAlias(json.meta.table)
}
if (json.meta?.tables) {
for (let tableName of Object.keys(json.meta.tables)) {
json.meta.tables[tableName] = removeTableAlias(
json.meta.tables[tableName]
)
}
}
return json
}
class InternalBuilder { class InternalBuilder {
private readonly client: string private readonly client: string
@ -605,10 +631,12 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
return query.toSQL().toNative() return query.toSQL().toNative()
} }
async getReturningRow(queryFn: Function, json: QueryJson) { async getReturningRow(queryFn: QueryFunction, json: QueryJson) {
if (!json.extra || !json.extra.idFilter) { if (!json.extra || !json.extra.idFilter) {
return {} return {}
} }
// disable aliasing if it is enabled
json = disableAliasing(json)
const input = this._query({ const input = this._query({
endpoint: { endpoint: {
...json.endpoint, ...json.endpoint,
@ -617,7 +645,7 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
resource: { resource: {
fields: [], fields: [],
}, },
filters: json.extra.idFilter, filters: json.extra?.idFilter,
paginate: { paginate: {
limit: 1, limit: 1,
}, },
@ -646,7 +674,7 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
// this function recreates the returning functionality of postgres // this function recreates the returning functionality of postgres
async queryWithReturning( async queryWithReturning(
json: QueryJson, json: QueryJson,
queryFn: Function, queryFn: QueryFunction,
processFn: Function = (result: any) => result processFn: Function = (result: any) => result
) { ) {
const sqlClient = this.getSqlClient() const sqlClient = this.getSqlClient()

View File

@ -4,6 +4,7 @@ import Sql from "../base/sql"
import { SqlClient } from "../utils" import { SqlClient } from "../utils"
import AliasTables from "../../api/controllers/row/alias" import AliasTables from "../../api/controllers/row/alias"
import { generator } from "@budibase/backend-core/tests" import { generator } from "@budibase/backend-core/tests"
import { Knex } from "knex"
function multiline(sql: string) { function multiline(sql: string) {
return sql.replace(/\n/g, "").replace(/ +/g, " ") return sql.replace(/\n/g, "").replace(/ +/g, " ")
@ -160,6 +161,28 @@ describe("Captures of real examples", () => {
}) })
}) })
describe("returning (everything bar Postgres)", () => {
it("should be able to handle row returning", () => {
const queryJson = getJson("createSimple.json")
const SQL = new Sql(SqlClient.MS_SQL, limit)
let query = SQL._query(queryJson, { disableReturning: true })
expect(query).toEqual({
sql: "insert into [people] ([age], [name]) values (@p0, @p1)",
bindings: [222, "awfawf"],
})
// now check returning
let returningQuery: Knex.SqlNative = { sql: "", bindings: [] }
SQL.getReturningRow((input: Knex.SqlNative) => {
returningQuery = input
}, queryJson)
expect(returningQuery).toEqual({
sql: "select * from (select top (@p0) * from [people] where [people].[name] = @p1 and [people].[age] = @p2 order by [people].[name] asc) as [people]",
bindings: [1, "awfawf", 222],
})
})
})
describe("check max character aliasing", () => { describe("check max character aliasing", () => {
it("should handle over 'z' max character alias", () => { it("should handle over 'z' max character alias", () => {
const tableNames = [] const tableNames = []

View File

@ -0,0 +1,65 @@
{
"endpoint": {
"datasourceId": "datasource_plus_0ed5835e5552496285df546030f7c4ae",
"entityId": "people",
"operation": "CREATE"
},
"resource": {
"fields": [
"a.name",
"a.age"
]
},
"filters": {},
"relationships": [],
"body": {
"name": "awfawf",
"age": 222
},
"extra": {
"idFilter": {
"equal": {
"name": "awfawf",
"age": 222
}
}
},
"meta": {
"table": {
"_id": "datasource_plus_0ed5835e5552496285df546030f7c4ae__people",
"type": "table",
"sourceId": "datasource_plus_0ed5835e5552496285df546030f7c4ae",
"sourceType": "external",
"primary": [
"name",
"age"
],
"name": "a",
"schema": {
"name": {
"type": "string",
"externalType": "varchar",
"autocolumn": false,
"name": "name",
"constraints": {
"presence": true
}
},
"age": {
"type": "number",
"externalType": "int",
"autocolumn": false,
"name": "age",
"constraints": {
"presence": false
}
}
},
"primaryDisplay": "name",
"originalName": "people"
}
},
"tableAliases": {
"people": "a"
}
}

View File

@ -15,6 +15,7 @@ export interface Table extends Document {
sourceType: TableSourceType sourceType: TableSourceType
views?: { [key: string]: View | ViewV2 } views?: { [key: string]: View | ViewV2 }
name: string name: string
originalName?: string
sourceId: string sourceId: string
primary?: string[] primary?: string[]
schema: TableSchema schema: TableSchema