Merge branch 'master' into fix/sql-table-update-aliasing

This commit is contained in:
Michael Drury 2024-03-19 17:35:23 +00:00 committed by GitHub
commit 34b4e8fd1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 35 additions and 12 deletions

View File

@ -81,6 +81,7 @@ exports[`/datasources fetch returns all the datasources from the server 1`] = `
{ {
"config": {}, "config": {},
"createdAt": "2020-01-01T00:00:00.000Z", "createdAt": "2020-01-01T00:00:00.000Z",
"isSQL": true,
"name": "Test", "name": "Test",
"source": "POSTGRES", "source": "POSTGRES",
"type": "datasource", "type": "datasource",

View File

@ -106,6 +106,7 @@ describe("mysql integrations", () => {
plus: true, plus: true,
source: "MYSQL", source: "MYSQL",
type: "datasource_plus", type: "datasource_plus",
isSQL: true,
_id: expect.any(String), _id: expect.any(String),
_rev: expect.any(String), _rev: expect.any(String),
createdAt: expect.any(String), createdAt: expect.any(String),

View File

@ -319,6 +319,7 @@ describe("postgres integrations", () => {
}, },
plus: true, plus: true,
source: "POSTGRES", source: "POSTGRES",
isSQL: true,
type: "datasource_plus", type: "datasource_plus",
_id: expect.any(String), _id: expect.any(String),
_rev: expect.any(String), _rev: expect.any(String),

View File

@ -699,13 +699,15 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
convertJsonStringColumns( convertJsonStringColumns(
table: Table, table: Table,
results: Record<string, any>[] results: Record<string, any>[],
aliases?: Record<string, string>
): Record<string, any>[] { ): Record<string, any>[] {
for (const [name, field] of Object.entries(table.schema)) { for (const [name, field] of Object.entries(table.schema)) {
if (!this._isJsonColumn(field)) { if (!this._isJsonColumn(field)) {
continue continue
} }
const fullName = `${table.name}.${name}` const tableName = aliases?.[table.name] || table.name
const fullName = `${tableName}.${name}`
for (let row of results) { for (let row of results) {
if (typeof row[fullName] === "string") { if (typeof row[fullName] === "string") {
row[fullName] = JSON.parse(row[fullName]) row[fullName] = JSON.parse(row[fullName])

View File

@ -506,7 +506,11 @@ class SqlServerIntegration extends Sql implements DatasourcePlus {
const queryFn = (query: any, op: string) => this.internalQuery(query, op) const queryFn = (query: any, op: string) => this.internalQuery(query, op)
const processFn = (result: any) => { const processFn = (result: any) => {
if (json?.meta?.table && result.recordset) { if (json?.meta?.table && result.recordset) {
return this.convertJsonStringColumns(json.meta.table, result.recordset) return this.convertJsonStringColumns(
json.meta.table,
result.recordset,
json.tableAliases
)
} else if (result.recordset) { } else if (result.recordset) {
return result.recordset return result.recordset
} }

View File

@ -390,7 +390,11 @@ class MySQLIntegration extends Sql implements DatasourcePlus {
this.internalQuery(query, { connect: false, disableCoercion: true }) this.internalQuery(query, { connect: false, disableCoercion: true })
const processFn = (result: any) => { const processFn = (result: any) => {
if (json?.meta?.table && Array.isArray(result)) { if (json?.meta?.table && Array.isArray(result)) {
return this.convertJsonStringColumns(json.meta.table, result) return this.convertJsonStringColumns(
json.meta.table,
result,
json.tableAliases
)
} }
return result return result
} }

View File

@ -30,9 +30,15 @@ import {
} from "../../../db/utils" } from "../../../db/utils"
import sdk from "../../index" import sdk from "../../index"
import { setupCreationAuth as googleSetupCreationAuth } from "../../../integrations/googlesheets" import { setupCreationAuth as googleSetupCreationAuth } from "../../../integrations/googlesheets"
import { helpers } from "@budibase/shared-core"
const ENV_VAR_PREFIX = "env." const ENV_VAR_PREFIX = "env."
function addDatasourceFlags(datasource: Datasource) {
datasource.isSQL = helpers.isSQL(datasource)
return datasource
}
export async function fetch(opts?: { export async function fetch(opts?: {
enriched: boolean enriched: boolean
}): Promise<Datasource[]> { }): Promise<Datasource[]> {
@ -56,7 +62,7 @@ export async function fetch(opts?: {
} as Datasource } as Datasource
// Get external datasources // Get external datasources
const datasources = ( let datasources = (
await db.allDocs<Datasource>( await db.allDocs<Datasource>(
getDatasourceParams(null, { getDatasourceParams(null, {
include_docs: true, include_docs: true,
@ -75,6 +81,7 @@ export async function fetch(opts?: {
} }
} }
datasources = datasources.map(datasource => addDatasourceFlags(datasource))
if (opts?.enriched) { if (opts?.enriched) {
const envVars = await getEnvironmentVariables() const envVars = await getEnvironmentVariables()
const promises = datasources.map(datasource => const promises = datasources.map(datasource =>
@ -150,6 +157,7 @@ async function enrichDatasourceWithValues(
} }
export async function enrich(datasource: Datasource) { export async function enrich(datasource: Datasource) {
datasource = addDatasourceFlags(datasource)
const { datasource: response } = await enrichDatasourceWithValues(datasource) const { datasource: response } = await enrichDatasourceWithValues(datasource)
return response return response
} }
@ -159,7 +167,8 @@ export async function get(
opts?: { enriched: boolean } opts?: { enriched: boolean }
): Promise<Datasource> { ): Promise<Datasource> {
const appDb = context.getAppDB() const appDb = context.getAppDB()
const datasource = await appDb.get<Datasource>(datasourceId) let datasource = await appDb.get<Datasource>(datasourceId)
datasource = addDatasourceFlags(datasource)
if (opts?.enriched) { if (opts?.enriched) {
return (await enrichDatasourceWithValues(datasource)).datasource return (await enrichDatasourceWithValues(datasource)).datasource
} else { } else {
@ -271,13 +280,14 @@ export function mergeConfigs(update: Datasource, old: Datasource) {
export async function getExternalDatasources(): Promise<Datasource[]> { export async function getExternalDatasources(): Promise<Datasource[]> {
const db = context.getAppDB() const db = context.getAppDB()
const externalDatasources = await db.allDocs<Datasource>( let dsResponse = await db.allDocs<Datasource>(
getDatasourcePlusParams(undefined, { getDatasourcePlusParams(undefined, {
include_docs: true, include_docs: true,
}) })
) )
return externalDatasources.rows.map(r => r.doc!) const externalDatasources = dsResponse.rows.map(r => r.doc!)
return externalDatasources.map(datasource => addDatasourceFlags(datasource))
} }
export async function save( export async function save(
@ -290,11 +300,11 @@ export async function save(
const fetchSchema = opts?.fetchSchema || false const fetchSchema = opts?.fetchSchema || false
const tablesFilter = opts?.tablesFilter || [] const tablesFilter = opts?.tablesFilter || []
datasource = { datasource = addDatasourceFlags({
_id: generateDatasourceID({ plus }), _id: generateDatasourceID({ plus }),
...datasource, ...datasource,
type: plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE, type: plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE,
} })
let errors: Record<string, string> = {} let errors: Record<string, string> = {}
if (fetchSchema) { if (fetchSchema) {

View File

@ -14,7 +14,7 @@ import { makeExternalQuery } from "../../../integrations/base/query"
import { Format } from "../../../api/controllers/view/exporters" import { Format } from "../../../api/controllers/view/exporters"
import sdk from "../.." import sdk from "../.."
import { isRelationshipColumn } from "../../../db/utils" import { isRelationshipColumn } from "../../../db/utils"
import { SqlClient } from "../../../integrations/utils" import { SqlClient, isSQL } from "../../../integrations/utils"
const SQL_CLIENT_SOURCE_MAP: Record<SourceName, SqlClient | undefined> = { const SQL_CLIENT_SOURCE_MAP: Record<SourceName, SqlClient | undefined> = {
[SourceName.POSTGRES]: SqlClient.POSTGRES, [SourceName.POSTGRES]: SqlClient.POSTGRES,
@ -37,7 +37,7 @@ const SQL_CLIENT_SOURCE_MAP: Record<SourceName, SqlClient | undefined> = {
} }
export function getSQLClient(datasource: Datasource): SqlClient { export function getSQLClient(datasource: Datasource): SqlClient {
if (!datasource.isSQL) { if (!isSQL(datasource)) {
throw new Error("Cannot get SQL Client for non-SQL datasource") throw new Error("Cannot get SQL Client for non-SQL datasource")
} }
const lookup = SQL_CLIENT_SOURCE_MAP[datasource.source] const lookup = SQL_CLIENT_SOURCE_MAP[datasource.source]