Merge branch 'master' into fix/sql-table-update-aliasing
This commit is contained in:
commit
34b4e8fd1d
|
@ -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",
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue