2020-12-19 07:19:43 +13:00
|
|
|
const CouchDB = require("../../db")
|
2021-01-13 05:49:11 +13:00
|
|
|
const {
|
|
|
|
generateDatasourceID,
|
|
|
|
getDatasourceParams,
|
|
|
|
getQueryParams,
|
2021-06-12 04:52:08 +12:00
|
|
|
DocumentTypes,
|
2021-06-16 06:48:05 +12:00
|
|
|
BudibaseInternalDB,
|
|
|
|
getTableParams,
|
2021-01-13 05:49:11 +13:00
|
|
|
} = require("../../db/utils")
|
2021-06-02 02:00:28 +12:00
|
|
|
const { integrations } = require("../../integrations")
|
2021-06-15 06:05:39 +12:00
|
|
|
const { makeExternalQuery } = require("./row/utils")
|
2020-12-19 07:19:43 +13:00
|
|
|
|
2021-05-03 19:31:09 +12:00
|
|
|
exports.fetch = async function (ctx) {
|
2021-03-30 05:32:05 +13:00
|
|
|
const database = new CouchDB(ctx.appId)
|
2021-06-16 06:48:05 +12:00
|
|
|
|
|
|
|
// Get internal tables
|
|
|
|
const db = new CouchDB(ctx.appId)
|
|
|
|
const internalTables = await db.allDocs(
|
|
|
|
getTableParams(null, {
|
|
|
|
include_docs: true,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
const internal = internalTables.rows.map(row => row.doc)
|
|
|
|
|
|
|
|
const bbInternalDb = {
|
|
|
|
...BudibaseInternalDB,
|
|
|
|
entities: internal,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get external datasources
|
|
|
|
const datasources = (
|
2020-12-19 07:19:43 +13:00
|
|
|
await database.allDocs(
|
|
|
|
getDatasourceParams(null, {
|
|
|
|
include_docs: true,
|
|
|
|
})
|
|
|
|
)
|
2021-05-04 22:32:22 +12:00
|
|
|
).rows.map(row => row.doc)
|
2021-06-16 06:48:05 +12:00
|
|
|
|
|
|
|
ctx.body = [bbInternalDb, ...datasources]
|
2020-12-19 07:19:43 +13:00
|
|
|
}
|
|
|
|
|
2021-06-17 02:45:57 +12:00
|
|
|
exports.buildSchemaFromDb = async function (ctx) {
|
|
|
|
const db = new CouchDB(ctx.appId)
|
2021-09-29 00:25:57 +13:00
|
|
|
const datasource = await db.get(ctx.params.datasourceId)
|
2021-06-17 02:45:57 +12:00
|
|
|
|
2021-09-29 00:25:57 +13:00
|
|
|
const tables = await buildSchemaHelper(datasource)
|
|
|
|
datasource.entities = tables
|
2021-06-17 02:45:57 +12:00
|
|
|
|
2021-09-22 03:07:04 +12:00
|
|
|
const response = await db.put(datasource)
|
2021-06-17 02:45:57 +12:00
|
|
|
datasource._rev = response.rev
|
|
|
|
|
|
|
|
ctx.body = datasource
|
|
|
|
}
|
|
|
|
|
2021-08-18 09:57:11 +12:00
|
|
|
exports.update = async function (ctx) {
|
|
|
|
const db = new CouchDB(ctx.appId)
|
|
|
|
const datasourceId = ctx.params.datasourceId
|
2021-08-27 08:01:24 +12:00
|
|
|
let datasource = await db.get(datasourceId)
|
|
|
|
datasource = { ...datasource, ...ctx.request.body }
|
2021-08-18 09:57:11 +12:00
|
|
|
|
|
|
|
const response = await db.put(datasource)
|
|
|
|
datasource._rev = response.rev
|
|
|
|
|
|
|
|
// Drain connection pools when configuration is changed
|
|
|
|
if (datasource.source) {
|
|
|
|
const source = integrations[datasource.source]
|
|
|
|
if (source && source.pool) {
|
|
|
|
await source.pool.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.status = 200
|
|
|
|
ctx.message = "Datasource saved successfully."
|
|
|
|
ctx.body = datasource
|
|
|
|
}
|
|
|
|
|
2021-05-03 19:31:09 +12:00
|
|
|
exports.save = async function (ctx) {
|
2021-03-30 05:32:05 +13:00
|
|
|
const db = new CouchDB(ctx.appId)
|
2021-09-29 00:25:57 +13:00
|
|
|
const plus = ctx.request.body.datasource.plus
|
|
|
|
const fetchSchema = ctx.request.body.fetchSchema
|
2020-12-19 07:19:43 +13:00
|
|
|
|
|
|
|
const datasource = {
|
2021-06-12 04:52:08 +12:00
|
|
|
_id: generateDatasourceID({ plus }),
|
|
|
|
type: plus ? DocumentTypes.DATASOURCE_PLUS : DocumentTypes.DATASOURCE,
|
2021-09-29 00:25:57 +13:00
|
|
|
...ctx.request.body.datasource,
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fetchSchema) {
|
|
|
|
let tables = await buildSchemaHelper(datasource)
|
|
|
|
datasource.entities = tables
|
2020-12-19 07:19:43 +13:00
|
|
|
}
|
|
|
|
|
2021-09-22 03:07:04 +12:00
|
|
|
const response = await db.put(datasource)
|
2021-03-11 00:56:52 +13:00
|
|
|
datasource._rev = response.rev
|
2020-12-19 07:19:43 +13:00
|
|
|
|
2021-06-02 02:00:28 +12:00
|
|
|
// Drain connection pools when configuration is changed
|
2021-06-04 04:56:04 +12:00
|
|
|
if (datasource.source) {
|
|
|
|
const source = integrations[datasource.source]
|
|
|
|
if (source && source.pool) {
|
|
|
|
await source.pool.end()
|
|
|
|
}
|
2021-06-02 02:00:28 +12:00
|
|
|
}
|
|
|
|
|
2020-12-19 07:19:43 +13:00
|
|
|
ctx.status = 200
|
2021-03-11 00:56:52 +13:00
|
|
|
ctx.message = "Datasource saved successfully."
|
|
|
|
ctx.body = datasource
|
2020-12-19 07:19:43 +13:00
|
|
|
}
|
|
|
|
|
2021-05-03 19:31:09 +12:00
|
|
|
exports.destroy = async function (ctx) {
|
2021-03-30 05:32:05 +13:00
|
|
|
const db = new CouchDB(ctx.appId)
|
2021-01-13 05:49:11 +13:00
|
|
|
|
|
|
|
// Delete all queries for the datasource
|
|
|
|
const rows = await db.allDocs(getQueryParams(ctx.params.datasourceId, null))
|
2021-05-04 22:32:22 +12:00
|
|
|
await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
|
2021-01-13 05:49:11 +13:00
|
|
|
|
|
|
|
// delete the datasource
|
2021-01-13 06:45:43 +13:00
|
|
|
await db.remove(ctx.params.datasourceId, ctx.params.revId)
|
2021-01-13 05:49:11 +13:00
|
|
|
|
2020-12-19 07:19:43 +13:00
|
|
|
ctx.message = `Datasource deleted.`
|
|
|
|
ctx.status = 200
|
|
|
|
}
|
|
|
|
|
2021-05-03 19:31:09 +12:00
|
|
|
exports.find = async function (ctx) {
|
2021-03-30 05:32:05 +13:00
|
|
|
const database = new CouchDB(ctx.appId)
|
2021-03-11 00:56:52 +13:00
|
|
|
ctx.body = await database.get(ctx.params.datasourceId)
|
2020-12-19 07:19:43 +13:00
|
|
|
}
|
2021-06-04 04:56:04 +12:00
|
|
|
|
2021-06-04 05:48:04 +12:00
|
|
|
// dynamic query functionality
|
|
|
|
exports.query = async function (ctx) {
|
2021-06-05 01:53:49 +12:00
|
|
|
const queryJson = ctx.request.body
|
2021-06-15 06:05:39 +12:00
|
|
|
try {
|
|
|
|
ctx.body = await makeExternalQuery(ctx.appId, queryJson)
|
|
|
|
} catch (err) {
|
|
|
|
ctx.throw(400, err)
|
2021-06-05 01:53:49 +12:00
|
|
|
}
|
2021-06-04 05:48:04 +12:00
|
|
|
}
|
2021-09-29 00:25:57 +13:00
|
|
|
|
|
|
|
const buildSchemaHelper = async datasource => {
|
|
|
|
const Connector = integrations[datasource.source]
|
|
|
|
|
|
|
|
// Connect to the DB and build the schema
|
|
|
|
const connector = new Connector(datasource.config)
|
|
|
|
await connector.buildSchema(datasource._id, datasource.entities)
|
|
|
|
datasource.entities = connector.tables
|
|
|
|
|
|
|
|
return connector.tables
|
|
|
|
}
|