Re-writing a bit so that it is aware some functionality is SQL only, makes future plus endpoints easier.
This commit is contained in:
parent
71f96f9601
commit
11f6abee0a
|
@ -5,7 +5,7 @@ import {
|
||||||
PaginationJson,
|
PaginationJson,
|
||||||
RelationshipsJson,
|
RelationshipsJson,
|
||||||
} from "../../../definitions/datasource"
|
} from "../../../definitions/datasource"
|
||||||
import { Row, Table, FieldSchema } from "../../../definitions/common"
|
import {Row, Table, FieldSchema, Datasource} from "../../../definitions/common"
|
||||||
import {
|
import {
|
||||||
breakRowIdField,
|
breakRowIdField,
|
||||||
generateRowIdField,
|
generateRowIdField,
|
||||||
|
@ -29,11 +29,11 @@ interface RunConfig {
|
||||||
module External {
|
module External {
|
||||||
const { makeExternalQuery } = require("./utils")
|
const { makeExternalQuery } = require("./utils")
|
||||||
const { DataSourceOperation, FieldTypes } = require("../../../constants")
|
const { DataSourceOperation, FieldTypes } = require("../../../constants")
|
||||||
const { getAllExternalTables } = require("../table/utils")
|
const { breakExternalTableId, isSQL } = require("../../../integrations/utils")
|
||||||
const { breakExternalTableId } = require("../../../integrations/utils")
|
|
||||||
const { processObjectSync } = require("@budibase/string-templates")
|
const { processObjectSync } = require("@budibase/string-templates")
|
||||||
const { cloneDeep } = require("lodash/fp")
|
const { cloneDeep } = require("lodash/fp")
|
||||||
const { isEqual } = require("lodash")
|
const { isEqual } = require("lodash")
|
||||||
|
const CouchDB = require("../../../db")
|
||||||
|
|
||||||
function buildFilters(
|
function buildFilters(
|
||||||
id: string | undefined,
|
id: string | undefined,
|
||||||
|
@ -128,18 +128,22 @@ module External {
|
||||||
private readonly appId: string
|
private readonly appId: string
|
||||||
private operation: Operation
|
private operation: Operation
|
||||||
private tableId: string
|
private tableId: string
|
||||||
private tables: { [key: string]: Table }
|
private datasource: Datasource
|
||||||
|
private tables: { [key: string]: Table } = {}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
appId: string,
|
appId: string,
|
||||||
operation: Operation,
|
operation: Operation,
|
||||||
tableId: string,
|
tableId: string,
|
||||||
tables: { [key: string]: Table }
|
datasource: Datasource
|
||||||
) {
|
) {
|
||||||
this.appId = appId
|
this.appId = appId
|
||||||
this.operation = operation
|
this.operation = operation
|
||||||
this.tableId = tableId
|
this.tableId = tableId
|
||||||
this.tables = tables
|
this.datasource = datasource
|
||||||
|
if (datasource && datasource.entities) {
|
||||||
|
this.tables = datasource.entities
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputProcessing(row: Row, table: Table) {
|
inputProcessing(row: Row, table: Table) {
|
||||||
|
@ -451,10 +455,16 @@ module External {
|
||||||
async run({ id, row, filters, sort, paginate }: RunConfig) {
|
async run({ id, row, filters, sort, paginate }: RunConfig) {
|
||||||
const { appId, operation, tableId } = this
|
const { appId, operation, tableId } = this
|
||||||
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
||||||
if (!this.tables) {
|
if (!this.datasource) {
|
||||||
this.tables = await getAllExternalTables(appId, datasourceId)
|
const db = new CouchDB(appId)
|
||||||
|
this.datasource = await db.get(datasourceId)
|
||||||
|
if (!this.datasource || !this.datasource.entities) {
|
||||||
|
throw "No tables found, fetch tables before query."
|
||||||
|
}
|
||||||
|
this.tables = this.datasource.entities
|
||||||
}
|
}
|
||||||
const table = this.tables[tableName]
|
const table = this.tables[tableName]
|
||||||
|
let isSql = isSQL(this.datasource)
|
||||||
if (!table) {
|
if (!table) {
|
||||||
throw `Unable to process query, table "${tableName}" not defined.`
|
throw `Unable to process query, table "${tableName}" not defined.`
|
||||||
}
|
}
|
||||||
|
@ -476,8 +486,8 @@ module External {
|
||||||
operation,
|
operation,
|
||||||
},
|
},
|
||||||
resource: {
|
resource: {
|
||||||
// have to specify the fields to avoid column overlap
|
// have to specify the fields to avoid column overlap (for SQL)
|
||||||
fields: this.buildFields(table),
|
fields: isSql ? this.buildFields(table) : [],
|
||||||
},
|
},
|
||||||
filters,
|
filters,
|
||||||
sort,
|
sort,
|
||||||
|
|
|
@ -9,9 +9,10 @@ const {
|
||||||
breakRowIdField,
|
breakRowIdField,
|
||||||
} = require("../../../integrations/utils")
|
} = require("../../../integrations/utils")
|
||||||
const ExternalRequest = require("./ExternalRequest")
|
const ExternalRequest = require("./ExternalRequest")
|
||||||
|
const CouchDB = require("../../../db")
|
||||||
|
|
||||||
async function handleRequest(appId, operation, tableId, opts = {}) {
|
async function handleRequest(appId, operation, tableId, opts = {}) {
|
||||||
return new ExternalRequest(appId, operation, tableId, opts.tables).run(opts)
|
return new ExternalRequest(appId, operation, tableId, opts.datasource).run(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.patch = async ctx => {
|
exports.patch = async ctx => {
|
||||||
|
@ -162,14 +163,19 @@ exports.fetchEnrichedRow = async ctx => {
|
||||||
const id = ctx.params.rowId
|
const id = ctx.params.rowId
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
||||||
const tables = await getAllExternalTables(appId, datasourceId)
|
const db = new CouchDB(appId)
|
||||||
|
const datasource = await db.get(datasourceId)
|
||||||
|
if (!datasource || !datasource.entities) {
|
||||||
|
ctx.throw(400, "Datasource has not been configured for plus API.")
|
||||||
|
}
|
||||||
|
const tables = datasource.entities
|
||||||
const response = await handleRequest(
|
const response = await handleRequest(
|
||||||
appId,
|
appId,
|
||||||
DataSourceOperation.READ,
|
DataSourceOperation.READ,
|
||||||
tableId,
|
tableId,
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
tables,
|
datasource,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const table = tables[tableName]
|
const table = tables[tableName]
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { SourceNames } from "./datasource"
|
||||||
|
|
||||||
interface Base {
|
interface Base {
|
||||||
_id?: string
|
_id?: string
|
||||||
_rev?: string
|
_rev?: string
|
||||||
|
@ -82,3 +84,17 @@ export interface Automation extends Base {
|
||||||
trigger?: AutomationStep
|
trigger?: AutomationStep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Datasource extends Base {
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
source: SourceNames
|
||||||
|
// the config is defined by the schema
|
||||||
|
config: {
|
||||||
|
[key: string]: string | number | boolean
|
||||||
|
}
|
||||||
|
plus: boolean
|
||||||
|
entities?: {
|
||||||
|
[key: string]: Table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,20 @@ export enum DatasourceFieldTypes {
|
||||||
JSON = "json",
|
JSON = "json",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SourceNames {
|
||||||
|
POSTGRES = "POSTGRES",
|
||||||
|
DYNAMODB = "DYNAMODB",
|
||||||
|
MONGODB = "MONGODB",
|
||||||
|
ELASTICSEARCH = "ELASTICSEARCH",
|
||||||
|
COUCHDB = "COUCHDB",
|
||||||
|
SQL_SERVER = "SQL_SERVER",
|
||||||
|
S3 = "S3",
|
||||||
|
AIRTABLE = "AIRTABLE",
|
||||||
|
MYSQL = "MYSQL",
|
||||||
|
ARANGODB = "ARANGODB",
|
||||||
|
REST = "REST",
|
||||||
|
}
|
||||||
|
|
||||||
export interface QueryDefinition {
|
export interface QueryDefinition {
|
||||||
type: QueryTypes
|
type: QueryTypes
|
||||||
displayName?: string
|
displayName?: string
|
||||||
|
|
|
@ -9,33 +9,34 @@ const airtable = require("./airtable")
|
||||||
const mysql = require("./mysql")
|
const mysql = require("./mysql")
|
||||||
const arangodb = require("./arangodb")
|
const arangodb = require("./arangodb")
|
||||||
const rest = require("./rest")
|
const rest = require("./rest")
|
||||||
|
const { SourceNames } = require("../definitions/datasource")
|
||||||
|
|
||||||
const DEFINITIONS = {
|
const DEFINITIONS = {
|
||||||
POSTGRES: postgres.schema,
|
[SourceNames.POSTGRES]: postgres.schema,
|
||||||
DYNAMODB: dynamodb.schema,
|
[SourceNames.DYNAMODB]: dynamodb.schema,
|
||||||
MONGODB: mongodb.schema,
|
[SourceNames.MONGODB]: mongodb.schema,
|
||||||
ELASTICSEARCH: elasticsearch.schema,
|
[SourceNames.ELASTICSEARCH]: elasticsearch.schema,
|
||||||
COUCHDB: couchdb.schema,
|
[SourceNames.COUCHDB]: couchdb.schema,
|
||||||
SQL_SERVER: sqlServer.schema,
|
[SourceNames.SQL_SERVER]: sqlServer.schema,
|
||||||
S3: s3.schema,
|
[SourceNames.S3]: s3.schema,
|
||||||
AIRTABLE: airtable.schema,
|
[SourceNames.AIRTABLE]: airtable.schema,
|
||||||
MYSQL: mysql.schema,
|
[SourceNames.MYSQL]: mysql.schema,
|
||||||
ARANGODB: arangodb.schema,
|
[SourceNames.ARANGODB]: arangodb.schema,
|
||||||
REST: rest.schema,
|
[SourceNames.REST]: rest.schema,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INTEGRATIONS = {
|
const INTEGRATIONS = {
|
||||||
POSTGRES: postgres.integration,
|
[SourceNames.POSTGRES]: postgres.integration,
|
||||||
DYNAMODB: dynamodb.integration,
|
[SourceNames.DYNAMODB]: dynamodb.integration,
|
||||||
MONGODB: mongodb.integration,
|
[SourceNames.MONGODB]: mongodb.integration,
|
||||||
ELASTICSEARCH: elasticsearch.integration,
|
[SourceNames.ELASTICSEARCH]: elasticsearch.integration,
|
||||||
COUCHDB: couchdb.integration,
|
[SourceNames.COUCHDB]: couchdb.integration,
|
||||||
S3: s3.integration,
|
[SourceNames.SQL_SERVER]: s3.integration,
|
||||||
SQL_SERVER: sqlServer.integration,
|
[SourceNames.S3]: sqlServer.integration,
|
||||||
AIRTABLE: airtable.integration,
|
[SourceNames.AIRTABLE]: airtable.integration,
|
||||||
MYSQL: mysql.integration,
|
[SourceNames.MYSQL]: mysql.integration,
|
||||||
ARANGODB: arangodb.integration,
|
[SourceNames.ARANGODB]: arangodb.integration,
|
||||||
REST: rest.integration,
|
[SourceNames.REST]: rest.integration,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { SqlQuery } from "../definitions/datasource"
|
import { SqlQuery } from "../definitions/datasource"
|
||||||
|
import { Datasource } from "../definitions/common"
|
||||||
|
import { SourceNames } from "../definitions/datasource"
|
||||||
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
||||||
const { FieldTypes } = require("../constants")
|
const { FieldTypes } = require("../constants")
|
||||||
|
|
||||||
|
@ -51,3 +53,11 @@ export function getSqlQuery(query: SqlQuery | string): SqlQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isSQL(datasource: Datasource): boolean {
|
||||||
|
if (!datasource || !datasource.source) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const SQL = [SourceNames.POSTGRES, SourceNames.SQL_SERVER, SourceNames.MYSQL]
|
||||||
|
return SQL.indexOf(datasource.source) !== -1
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue