Final pass refactoring - need to test but all code in server converted.

This commit is contained in:
Michael Drury 2022-01-28 00:05:39 +00:00
parent 40c6eb2007
commit 91c2a40c89
29 changed files with 269 additions and 1004 deletions

View File

@ -4,6 +4,7 @@ const {
getProdAppDB, getProdAppDB,
getAppId, getAppId,
updateAppId, updateAppId,
doInAppContext,
} = require("./src/tenancy/context") } = require("./src/tenancy/context")
module.exports = { module.exports = {
@ -12,4 +13,5 @@ module.exports = {
getProdAppDB, getProdAppDB,
getAppId, getAppId,
updateAppId, updateAppId,
doInAppContext,
} }

View File

@ -32,3 +32,7 @@ exports.StaticDatabases = {
}, },
}, },
} }
exports.APP_PREFIX = exports.DocumentTypes.APP + exports.SEPARATOR
exports.APP_DEV = exports.APP_DEV_PREFIX =
exports.DocumentTypes.APP_DEV + exports.SEPARATOR

View File

@ -0,0 +1,46 @@
const NO_APP_ERROR = "No app provided"
const { APP_DEV_PREFIX, APP_PREFIX } = require("./constants")
exports.isDevAppID = appId => {
if (!appId) {
throw NO_APP_ERROR
}
return appId.startsWith(APP_DEV_PREFIX)
}
exports.isProdAppID = appId => {
if (!appId) {
throw NO_APP_ERROR
}
return appId.startsWith(APP_PREFIX) && !exports.isDevAppID(appId)
}
exports.isDevApp = app => {
if (!app) {
throw NO_APP_ERROR
}
return exports.isDevAppID(app.appId)
}
/**
* Convert a development app ID to a deployed app ID.
*/
exports.getDeployedAppID = appId => {
// if dev, convert it
if (appId.startsWith(APP_DEV_PREFIX)) {
const id = appId.split(APP_DEV_PREFIX)[1]
return `${APP_PREFIX}${id}`
}
return appId
}
/**
* Convert a deployed app ID to a development app ID.
*/
exports.getDevelopmentAppID = appId => {
if (!appId.startsWith(APP_DEV_PREFIX)) {
const id = appId.split(APP_PREFIX)[1]
return `${APP_DEV_PREFIX}${id}`
}
return appId
}

View File

@ -2,7 +2,13 @@ const { newid } = require("../hashing")
const Replication = require("./Replication") const Replication = require("./Replication")
const { DEFAULT_TENANT_ID, Configs } = require("../constants") const { DEFAULT_TENANT_ID, Configs } = require("../constants")
const env = require("../environment") const env = require("../environment")
const { StaticDatabases, SEPARATOR, DocumentTypes } = require("./constants") const {
StaticDatabases,
SEPARATOR,
DocumentTypes,
APP_PREFIX,
APP_DEV,
} = require("./constants")
const { const {
getTenantId, getTenantId,
getTenantIDFromAppID, getTenantIDFromAppID,
@ -12,8 +18,13 @@ const fetch = require("node-fetch")
const { getCouch } = require("./index") const { getCouch } = require("./index")
const { getAppMetadata } = require("../cache/appMetadata") const { getAppMetadata } = require("../cache/appMetadata")
const { checkSlashesInUrl } = require("../helpers") const { checkSlashesInUrl } = require("../helpers")
const {
const NO_APP_ERROR = "No app provided" isDevApp,
isProdAppID,
isDevAppID,
getDevelopmentAppID,
getDeployedAppID,
} = require("./conversions")
const UNICODE_MAX = "\ufff0" const UNICODE_MAX = "\ufff0"
@ -24,10 +35,15 @@ exports.ViewNames = {
exports.StaticDatabases = StaticDatabases exports.StaticDatabases = StaticDatabases
exports.DocumentTypes = DocumentTypes exports.DocumentTypes = DocumentTypes
exports.APP_PREFIX = DocumentTypes.APP + SEPARATOR exports.APP_PREFIX = APP_PREFIX
exports.APP_DEV = exports.APP_DEV_PREFIX = DocumentTypes.APP_DEV + SEPARATOR exports.APP_DEV = exports.APP_DEV_PREFIX = APP_DEV
exports.SEPARATOR = SEPARATOR exports.SEPARATOR = SEPARATOR
exports.getTenantIDFromAppID = getTenantIDFromAppID exports.getTenantIDFromAppID = getTenantIDFromAppID
exports.isDevApp = isDevApp
exports.isProdAppID = isProdAppID
exports.isDevAppID = isDevAppID
exports.getDevelopmentAppID = getDevelopmentAppID
exports.getDeployedAppID = getDeployedAppID
/** /**
* If creating DB allDocs/query params with only a single top level ID this can be used, this * If creating DB allDocs/query params with only a single top level ID this can be used, this
@ -52,27 +68,6 @@ function getDocParams(docType, docId = null, otherProps = {}) {
} }
} }
exports.isDevAppID = appId => {
if (!appId) {
throw NO_APP_ERROR
}
return appId.startsWith(exports.APP_DEV_PREFIX)
}
exports.isProdAppID = appId => {
if (!appId) {
throw NO_APP_ERROR
}
return appId.startsWith(exports.APP_PREFIX) && !exports.isDevAppID(appId)
}
function isDevApp(app) {
if (!app) {
throw NO_APP_ERROR
}
return exports.isDevAppID(app.appId)
}
/** /**
* Generates a new workspace ID. * Generates a new workspace ID.
* @returns {string} The new workspace ID which the workspace doc can be stored under. * @returns {string} The new workspace ID which the workspace doc can be stored under.
@ -157,29 +152,6 @@ exports.getRoleParams = (roleId = null, otherProps = {}) => {
return getDocParams(DocumentTypes.ROLE, roleId, otherProps) return getDocParams(DocumentTypes.ROLE, roleId, otherProps)
} }
/**
* Convert a development app ID to a deployed app ID.
*/
exports.getDeployedAppID = appId => {
// if dev, convert it
if (appId.startsWith(exports.APP_DEV_PREFIX)) {
const id = appId.split(exports.APP_DEV_PREFIX)[1]
return `${exports.APP_PREFIX}${id}`
}
return appId
}
/**
* Convert a deployed app ID to a development app ID.
*/
exports.getDevelopmentAppID = appId => {
if (!appId.startsWith(exports.APP_DEV_PREFIX)) {
const id = appId.split(exports.APP_PREFIX)[1]
return `${exports.APP_DEV_PREFIX}${id}`
}
return appId
}
exports.getCouchUrl = () => { exports.getCouchUrl = () => {
if (!env.COUCH_DB_URL) return if (!env.COUCH_DB_URL) return

View File

@ -2,7 +2,7 @@ const env = require("../environment")
const { Headers } = require("../../constants") const { Headers } = require("../../constants")
const cls = require("./FunctionContext") const cls = require("./FunctionContext")
const { getCouch } = require("../db") const { getCouch } = require("../db")
const { getDeployedAppID, getDevelopmentAppID } = require("../db/utils") const { getDeployedAppID, getDevelopmentAppID } = require("../db/conversions")
const { isEqual } = require("lodash") const { isEqual } = require("lodash")
// some test cases call functions directly, need to // some test cases call functions directly, need to
@ -42,6 +42,16 @@ exports.doInTenant = (tenantId, task) => {
}) })
} }
exports.doInAppContext = (appId, task) => {
return cls.run(() => {
// set the app ID
cls.setOnContext(ContextKeys.APP_ID, appId)
// invoke the task
return task()
})
}
exports.updateTenantId = tenantId => { exports.updateTenantId = tenantId => {
cls.setOnContext(ContextKeys.TENANT_ID, tenantId) cls.setOnContext(ContextKeys.TENANT_ID, tenantId)
} }

View File

@ -1,11 +1,10 @@
const CouchDB = require("../../db")
const { outputProcessing } = require("../../utilities/rowProcessor") const { outputProcessing } = require("../../utilities/rowProcessor")
const { InternalTables } = require("../../db/utils") const { InternalTables } = require("../../db/utils")
const { getFullUser } = require("../../utilities/users") const { getFullUser } = require("../../utilities/users")
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles") const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
const { getAppDB, getAppId } = require("@budibase/backend-core/context")
exports.fetchSelf = async ctx => { exports.fetchSelf = async ctx => {
const appId = ctx.appId
let userId = ctx.user.userId || ctx.user._id let userId = ctx.user.userId || ctx.user._id
/* istanbul ignore next */ /* istanbul ignore next */
if (!userId) { if (!userId) {
@ -17,8 +16,8 @@ exports.fetchSelf = async ctx => {
// this shouldn't be returned by the app self // this shouldn't be returned by the app self
delete user.roles delete user.roles
if (appId) { if (getAppId()) {
const db = new CouchDB(appId) const db = getAppDB()
// remove the full roles structure // remove the full roles structure
delete user.roles delete user.roles
try { try {

View File

@ -1,4 +1,3 @@
const CouchDB = require("../../db")
const actions = require("../../automations/actions") const actions = require("../../automations/actions")
const triggers = require("../../automations/triggers") const triggers = require("../../automations/triggers")
const { getAutomationParams, generateAutomationID } = require("../../db/utils") const { getAutomationParams, generateAutomationID } = require("../../db/utils")
@ -10,6 +9,7 @@ const {
const { deleteEntityMetadata } = require("../../utilities") const { deleteEntityMetadata } = require("../../utilities")
const { MetadataTypes } = require("../../constants") const { MetadataTypes } = require("../../constants")
const { setTestFlag, clearTestFlag } = require("../../utilities/redis") const { setTestFlag, clearTestFlag } = require("../../utilities/redis")
const { getAppDB } = require("@budibase/backend-core/context")
const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS) const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS)
const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS) const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
@ -20,14 +20,9 @@ const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
* * * *
*************************/ *************************/
async function cleanupAutomationMetadata(appId, automationId) { async function cleanupAutomationMetadata(automationId) {
await deleteEntityMetadata(MetadataTypes.AUTOMATION_TEST_INPUT, automationId)
await deleteEntityMetadata( await deleteEntityMetadata(
appId,
MetadataTypes.AUTOMATION_TEST_INPUT,
automationId
)
await deleteEntityMetadata(
appId,
MetadataTypes.AUTOMATION_TEST_HISTORY, MetadataTypes.AUTOMATION_TEST_HISTORY,
automationId automationId
) )
@ -58,7 +53,7 @@ function cleanAutomationInputs(automation) {
} }
exports.create = async function (ctx) { exports.create = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
let automation = ctx.request.body let automation = ctx.request.body
automation.appId = ctx.appId automation.appId = ctx.appId
@ -72,7 +67,6 @@ exports.create = async function (ctx) {
automation.type = "automation" automation.type = "automation"
automation = cleanAutomationInputs(automation) automation = cleanAutomationInputs(automation)
automation = await checkForWebhooks({ automation = await checkForWebhooks({
appId: ctx.appId,
newAuto: automation, newAuto: automation,
}) })
const response = await db.put(automation) const response = await db.put(automation)
@ -89,13 +83,12 @@ exports.create = async function (ctx) {
} }
exports.update = async function (ctx) { exports.update = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
let automation = ctx.request.body let automation = ctx.request.body
automation.appId = ctx.appId automation.appId = ctx.appId
const oldAutomation = await db.get(automation._id) const oldAutomation = await db.get(automation._id)
automation = cleanAutomationInputs(automation) automation = cleanAutomationInputs(automation)
automation = await checkForWebhooks({ automation = await checkForWebhooks({
appId: ctx.appId,
oldAuto: oldAutomation, oldAuto: oldAutomation,
newAuto: automation, newAuto: automation,
}) })
@ -131,7 +124,7 @@ exports.update = async function (ctx) {
} }
exports.fetch = async function (ctx) { exports.fetch = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const response = await db.allDocs( const response = await db.allDocs(
getAutomationParams(null, { getAutomationParams(null, {
include_docs: true, include_docs: true,
@ -141,20 +134,19 @@ exports.fetch = async function (ctx) {
} }
exports.find = async function (ctx) { exports.find = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
ctx.body = await db.get(ctx.params.id) ctx.body = await db.get(ctx.params.id)
} }
exports.destroy = async function (ctx) { exports.destroy = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const automationId = ctx.params.id const automationId = ctx.params.id
const oldAutomation = await db.get(automationId) const oldAutomation = await db.get(automationId)
await checkForWebhooks({ await checkForWebhooks({
appId: ctx.appId,
oldAuto: oldAutomation, oldAuto: oldAutomation,
}) })
// delete metadata first // delete metadata first
await cleanupAutomationMetadata(ctx.appId, automationId) await cleanupAutomationMetadata(automationId)
ctx.body = await db.remove(automationId, ctx.params.rev) ctx.body = await db.remove(automationId, ctx.params.rev)
} }
@ -180,12 +172,11 @@ module.exports.getDefinitionList = async function (ctx) {
*********************/ *********************/
exports.trigger = async function (ctx) { exports.trigger = async function (ctx) {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
let automation = await db.get(ctx.params.id) let automation = await db.get(ctx.params.id)
await triggers.externalTrigger(automation, { await triggers.externalTrigger(automation, {
...ctx.request.body, ...ctx.request.body,
appId, appId: ctx.appId,
}) })
ctx.body = { ctx.body = {
message: `Automation ${automation._id} has been triggered.`, message: `Automation ${automation._id} has been triggered.`,
@ -205,8 +196,7 @@ function prepareTestInput(input) {
} }
exports.test = async function (ctx) { exports.test = async function (ctx) {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
let automation = await db.get(ctx.params.id) let automation = await db.get(ctx.params.id)
await setTestFlag(automation._id) await setTestFlag(automation._id)
const testInput = prepareTestInput(ctx.request.body) const testInput = prepareTestInput(ctx.request.body)
@ -214,7 +204,7 @@ exports.test = async function (ctx) {
automation, automation,
{ {
...testInput, ...testInput,
appId, appId: ctx.appId,
}, },
{ getResponses: true } { getResponses: true }
) )

View File

@ -1,18 +1,14 @@
const newid = require("../../../db/newid") const newid = require("../../../db/newid")
const { getAppId } = require("@budibase/backend-core/context")
/** /**
* This is used to pass around information about the deployment that is occurring * This is used to pass around information about the deployment that is occurring
*/ */
class Deployment { class Deployment {
constructor(appId, id = null) { constructor(id = null) {
this.appId = appId
this._id = id || newid() this._id = id || newid()
} }
getAppId() {
return this.appId
}
setVerification(verification) { setVerification(verification) {
if (!verification) { if (!verification) {
return return
@ -43,7 +39,7 @@ class Deployment {
getJSON() { getJSON() {
const obj = { const obj = {
_id: this._id, _id: this._id,
appId: this.appId, appId: getAppId(),
status: this.status, status: this.status,
} }
if (this.err) { if (this.err) {

View File

@ -1,12 +1,20 @@
const CouchDB = require("../../../db")
const Deployment = require("./Deployment") const Deployment = require("./Deployment")
const { Replication, getDeployedAppID } = require("@budibase/backend-core/db") const {
Replication,
getDeployedAppID,
getDevelopmentAppID,
} = require("@budibase/backend-core/db")
const { DocumentTypes, getAutomationParams } = require("../../../db/utils") const { DocumentTypes, getAutomationParams } = require("../../../db/utils")
const { const {
disableAllCrons, disableAllCrons,
enableCronTrigger, enableCronTrigger,
} = require("../../../automations/utils") } = require("../../../automations/utils")
const { app: appCache } = require("@budibase/backend-core/cache") const { app: appCache } = require("@budibase/backend-core/cache")
const {
getAppId,
getAppDB,
getProdAppDB,
} = require("@budibase/backend-core/context")
// the max time we can wait for an invalidation to complete before considering it failed // the max time we can wait for an invalidation to complete before considering it failed
const MAX_PENDING_TIME_MS = 30 * 60000 const MAX_PENDING_TIME_MS = 30 * 60000
@ -34,9 +42,8 @@ async function checkAllDeployments(deployments) {
} }
async function storeDeploymentHistory(deployment) { async function storeDeploymentHistory(deployment) {
const appId = deployment.getAppId()
const deploymentJSON = deployment.getJSON() const deploymentJSON = deployment.getJSON()
const db = new CouchDB(appId) const db = getAppDB()
let deploymentDoc let deploymentDoc
try { try {
@ -64,7 +71,7 @@ async function storeDeploymentHistory(deployment) {
} }
async function initDeployedApp(prodAppId) { async function initDeployedApp(prodAppId) {
const db = new CouchDB(prodAppId) const db = getProdAppDB()
console.log("Reading automation docs") console.log("Reading automation docs")
const automations = ( const automations = (
await db.allDocs( await db.allDocs(
@ -88,10 +95,12 @@ async function initDeployedApp(prodAppId) {
async function deployApp(deployment) { async function deployApp(deployment) {
try { try {
const productionAppId = getDeployedAppID(deployment.appId) const appId = getAppId()
const devAppId = getDevelopmentAppID(appId)
const productionAppId = getDeployedAppID(appId)
const replication = new Replication({ const replication = new Replication({
source: deployment.appId, source: devAppId,
target: productionAppId, target: productionAppId,
}) })
@ -99,7 +108,7 @@ async function deployApp(deployment) {
await replication.replicate() await replication.replicate()
console.log("replication complete.. replacing app meta doc") console.log("replication complete.. replacing app meta doc")
const db = new CouchDB(productionAppId) const db = getProdAppDB()
const appDoc = await db.get(DocumentTypes.APP_METADATA) const appDoc = await db.get(DocumentTypes.APP_METADATA)
appDoc.appId = productionAppId appDoc.appId = productionAppId
appDoc.instance._id = productionAppId appDoc.instance._id = productionAppId
@ -122,8 +131,7 @@ async function deployApp(deployment) {
exports.fetchDeployments = async function (ctx) { exports.fetchDeployments = async function (ctx) {
try { try {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS) const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS)
const { updated, deployments } = await checkAllDeployments( const { updated, deployments } = await checkAllDeployments(
deploymentDoc, deploymentDoc,
@ -140,8 +148,7 @@ exports.fetchDeployments = async function (ctx) {
exports.deploymentProgress = async function (ctx) { exports.deploymentProgress = async function (ctx) {
try { try {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS) const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS)
ctx.body = deploymentDoc[ctx.params.deploymentId] ctx.body = deploymentDoc[ctx.params.deploymentId]
} catch (err) { } catch (err) {
@ -153,7 +160,7 @@ exports.deploymentProgress = async function (ctx) {
} }
exports.deployApp = async function (ctx) { exports.deployApp = async function (ctx) {
let deployment = new Deployment(ctx.appId) let deployment = new Deployment()
console.log("Deployment object created") console.log("Deployment object created")
deployment.setStatus(DeploymentStatus.PENDING) deployment.setStatus(DeploymentStatus.PENDING)
console.log("Deployment object set to pending") console.log("Deployment object set to pending")

View File

@ -1,12 +1,12 @@
const fetch = require("node-fetch") const fetch = require("node-fetch")
const CouchDB = require("../../db")
const env = require("../../environment") const env = require("../../environment")
const { checkSlashesInUrl } = require("../../utilities") const { checkSlashesInUrl } = require("../../utilities")
const { request } = require("../../utilities/workerRequests") const { request } = require("../../utilities/workerRequests")
const { clearLock } = require("../../utilities/redis") const { clearLock } = require("../../utilities/redis")
const { Replication } = require("@budibase/backend-core/db") const { Replication, getDeployedAppID } = require("@budibase/backend-core/db")
const { DocumentTypes } = require("../../db/utils") const { DocumentTypes } = require("../../db/utils")
const { app: appCache } = require("@budibase/backend-core/cache") const { app: appCache } = require("@budibase/backend-core/cache")
const { getProdAppDB, getAppDB } = require("@budibase/backend-core/context")
async function redirect(ctx, method, path = "global") { async function redirect(ctx, method, path = "global") {
const { devPath } = ctx.params const { devPath } = ctx.params
@ -77,11 +77,11 @@ exports.clearLock = async ctx => {
exports.revert = async ctx => { exports.revert = async ctx => {
const { appId } = ctx.params const { appId } = ctx.params
const productionAppId = appId.replace("_dev", "") const productionAppId = getDeployedAppID(appId)
// App must have been deployed first // App must have been deployed first
try { try {
const db = new CouchDB(productionAppId, { skip_setup: true }) const db = getProdAppDB({ skip_setup: true })
const info = await db.info() const info = await db.info()
if (info.error) throw info.error if (info.error) throw info.error
const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS) const deploymentDoc = await db.get(DocumentTypes.DEPLOYMENTS)
@ -103,7 +103,7 @@ exports.revert = async ctx => {
await replication.rollback() await replication.rollback()
// update appID in reverted app to be dev version again // update appID in reverted app to be dev version again
const db = new CouchDB(appId) const db = getAppDB()
const appDoc = await db.get(DocumentTypes.APP_METADATA) const appDoc = await db.get(DocumentTypes.APP_METADATA)
appDoc.appId = appId appDoc.appId = appId
appDoc.instance._id = appId appDoc.instance._id = appId

View File

@ -1,7 +1,7 @@
const { MetadataTypes } = require("../../constants") const { MetadataTypes } = require("../../constants")
const CouchDB = require("../../db")
const { generateMetadataID } = require("../../db/utils") const { generateMetadataID } = require("../../db/utils")
const { saveEntityMetadata, deleteEntityMetadata } = require("../../utilities") const { saveEntityMetadata, deleteEntityMetadata } = require("../../utilities")
const { getAppDB } = require("@budibase/backend-core/context")
exports.getTypes = async ctx => { exports.getTypes = async ctx => {
ctx.body = { ctx.body = {
@ -14,17 +14,12 @@ exports.saveMetadata = async ctx => {
if (type === MetadataTypes.AUTOMATION_TEST_HISTORY) { if (type === MetadataTypes.AUTOMATION_TEST_HISTORY) {
ctx.throw(400, "Cannot save automation history type") ctx.throw(400, "Cannot save automation history type")
} }
ctx.body = await saveEntityMetadata( ctx.body = await saveEntityMetadata(type, entityId, ctx.request.body)
ctx.appId,
type,
entityId,
ctx.request.body
)
} }
exports.deleteMetadata = async ctx => { exports.deleteMetadata = async ctx => {
const { type, entityId } = ctx.params const { type, entityId } = ctx.params
await deleteEntityMetadata(ctx.appId, type, entityId) await deleteEntityMetadata(type, entityId)
ctx.body = { ctx.body = {
message: "Metadata deleted successfully", message: "Metadata deleted successfully",
} }
@ -32,7 +27,7 @@ exports.deleteMetadata = async ctx => {
exports.getMetadata = async ctx => { exports.getMetadata = async ctx => {
const { type, entityId } = ctx.params const { type, entityId } = ctx.params
const db = new CouchDB(ctx.appId) const db = getAppDB()
const id = generateMetadataID(type, entityId) const id = generateMetadataID(type, entityId)
try { try {
ctx.body = await db.get(id) ctx.body = await db.get(id)

View File

@ -1,10 +1,11 @@
import CouchDB from "../../../../db"
import { queryValidation } from "../validation" import { queryValidation } from "../validation"
import { generateQueryID } from "../../../../db/utils" import { generateQueryID } from "../../../../db/utils"
import { ImportInfo, ImportSource } from "./sources/base" import { ImportInfo, ImportSource } from "./sources/base"
import { OpenAPI2 } from "./sources/openapi2" import { OpenAPI2 } from "./sources/openapi2"
import { Query } from "./../../../../definitions/common" import { Query } from "./../../../../definitions/common"
import { Curl } from "./sources/curl" import { Curl } from "./sources/curl"
// @ts-ignore
import { getAppDB } from "@budibase/backend-core/context"
interface ImportResult { interface ImportResult {
errorQueries: Query[] errorQueries: Query[]
queries: Query[] queries: Query[]
@ -34,7 +35,6 @@ export class RestImporter {
} }
importQueries = async ( importQueries = async (
appId: string,
datasourceId: string datasourceId: string
): Promise<ImportResult> => { ): Promise<ImportResult> => {
// constuct the queries // constuct the queries
@ -58,7 +58,7 @@ export class RestImporter {
}) })
// persist queries // persist queries
const db = new CouchDB(appId) const db = getAppDB()
const response = await db.bulkDocs(queries) const response = await db.bulkDocs(queries)
// create index to seperate queries and errors // create index to seperate queries and errors

View File

@ -77,7 +77,7 @@ describe("Rest Importer", () => {
const testImportQueries = async (key, data, assertions) => { const testImportQueries = async (key, data, assertions) => {
await init(data) await init(data)
bulkDocs.mockReturnValue([]) bulkDocs.mockReturnValue([])
const importResult = await restImporter.importQueries("appId", "datasourceId") const importResult = await restImporter.importQueries("datasourceId")
expect(importResult.errorQueries.length).toBe(0) expect(importResult.errorQueries.length).toBe(0)
expect(importResult.queries.length).toBe(assertions[key].count) expect(importResult.queries.length).toBe(assertions[key].count)
expect(bulkDocs).toHaveBeenCalledTimes(1) expect(bulkDocs).toHaveBeenCalledTimes(1)

View File

@ -1,4 +1,3 @@
const CouchDB = require("../../../db")
const { const {
generateQueryID, generateQueryID,
getQueryParams, getQueryParams,
@ -10,6 +9,7 @@ const { save: saveDatasource } = require("../datasource")
const { RestImporter } = require("./import") const { RestImporter } = require("./import")
const { invalidateDynamicVariables } = require("../../../threads/utils") const { invalidateDynamicVariables } = require("../../../threads/utils")
const environment = require("../../../environment") const environment = require("../../../environment")
const { getAppDB } = require("@budibase/backend-core/context")
const Runner = new Thread(ThreadType.QUERY, { const Runner = new Thread(ThreadType.QUERY, {
timeoutMs: environment.QUERY_THREAD_TIMEOUT || 10000, timeoutMs: environment.QUERY_THREAD_TIMEOUT || 10000,
@ -28,7 +28,7 @@ function enrichQueries(input) {
} }
exports.fetch = async function (ctx) { exports.fetch = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const body = await db.allDocs( const body = await db.allDocs(
getQueryParams(null, { getQueryParams(null, {
@ -69,7 +69,7 @@ exports.import = async ctx => {
datasourceId = body.datasourceId datasourceId = body.datasourceId
} }
const importResult = await importer.importQueries(ctx.appId, datasourceId) const importResult = await importer.importQueries(datasourceId)
ctx.body = { ctx.body = {
...importResult, ...importResult,
@ -79,7 +79,7 @@ exports.import = async ctx => {
} }
exports.save = async function (ctx) { exports.save = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const query = ctx.request.body const query = ctx.request.body
if (!query._id) { if (!query._id) {
@ -94,7 +94,7 @@ exports.save = async function (ctx) {
} }
exports.find = async function (ctx) { exports.find = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const query = enrichQueries(await db.get(ctx.params.queryId)) const query = enrichQueries(await db.get(ctx.params.queryId))
// remove properties that could be dangerous in real app // remove properties that could be dangerous in real app
if (isProdAppID(ctx.appId)) { if (isProdAppID(ctx.appId)) {
@ -105,7 +105,7 @@ exports.find = async function (ctx) {
} }
exports.preview = async function (ctx) { exports.preview = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const datasource = await db.get(ctx.request.body.datasourceId) const datasource = await db.get(ctx.request.body.datasourceId)
// preview may not have a queryId as it hasn't been saved, but if it does // preview may not have a queryId as it hasn't been saved, but if it does
@ -136,7 +136,7 @@ exports.preview = async function (ctx) {
} }
async function execute(ctx, opts = { rowsOnly: false }) { async function execute(ctx, opts = { rowsOnly: false }) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const query = await db.get(ctx.params.queryId) const query = await db.get(ctx.params.queryId)
const datasource = await db.get(query.datasourceId) const datasource = await db.get(query.datasourceId)
@ -181,7 +181,8 @@ exports.executeV2 = async function (ctx) {
return execute(ctx, { rowsOnly: false }) return execute(ctx, { rowsOnly: false })
} }
const removeDynamicVariables = async (db, queryId) => { const removeDynamicVariables = async queryId => {
const db = getAppDB()
const query = await db.get(queryId) const query = await db.get(queryId)
const datasource = await db.get(query.datasourceId) const datasource = await db.get(query.datasourceId)
const dynamicVariables = datasource.config.dynamicVariables const dynamicVariables = datasource.config.dynamicVariables
@ -202,8 +203,8 @@ const removeDynamicVariables = async (db, queryId) => {
} }
exports.destroy = async function (ctx) { exports.destroy = async function (ctx) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
await removeDynamicVariables(db, ctx.params.queryId) await removeDynamicVariables(ctx.params.queryId)
await db.remove(ctx.params.queryId, ctx.params.revId) await db.remove(ctx.params.queryId, ctx.params.revId)
ctx.message = `Query deleted.` ctx.message = `Query deleted.`
ctx.status = 200 ctx.status = 200

View File

@ -39,12 +39,11 @@ Routing.prototype.addScreenId = function (fullpath, roleId, screenId) {
/** /**
* Gets the full routing structure by querying the routing view and processing the result into the tree. * Gets the full routing structure by querying the routing view and processing the result into the tree.
* @param {string} appId The application to produce the routing structure for.
* @returns {Promise<object>} The routing structure, this is the full structure designed for use in the builder, * @returns {Promise<object>} The routing structure, this is the full structure designed for use in the builder,
* if the client routing is required then the updateRoutingStructureForUserRole should be used. * if the client routing is required then the updateRoutingStructureForUserRole should be used.
*/ */
async function getRoutingStructure(appId) { async function getRoutingStructure() {
const screenRoutes = await getRoutingInfo(appId) const screenRoutes = await getRoutingInfo()
const routing = new Routing() const routing = new Routing()
for (let screenRoute of screenRoutes) { for (let screenRoute of screenRoutes) {
@ -57,7 +56,7 @@ async function getRoutingStructure(appId) {
} }
exports.fetch = async ctx => { exports.fetch = async ctx => {
ctx.body = await getRoutingStructure(ctx.appId) ctx.body = await getRoutingStructure()
} }
exports.clientFetch = async ctx => { exports.clientFetch = async ctx => {

View File

@ -9,7 +9,7 @@ const {
breakRowIdField, breakRowIdField,
} = require("../../../integrations/utils") } = require("../../../integrations/utils")
const ExternalRequest = require("./ExternalRequest") const ExternalRequest = require("./ExternalRequest")
const CouchDB = require("../../../db") const { getAppDB } = require("@budibase/backend-core/context")
async function handleRequest(operation, tableId, opts = {}) { async function handleRequest(operation, tableId, opts = {}) {
// make sure the filters are cleaned up, no empty strings for equals, fuzzy or string // make sure the filters are cleaned up, no empty strings for equals, fuzzy or string
@ -179,7 +179,7 @@ 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 db = new CouchDB(appId) const db = getAppDB()
const datasource = await db.get(datasourceId) const datasource = await db.get(datasourceId)
if (!datasource || !datasource.entities) { if (!datasource || !datasource.entities) {
ctx.throw(400, "Datasource has not been configured for plus API.") ctx.throw(400, "Datasource has not been configured for plus API.")

View File

@ -1,4 +1,3 @@
const CouchDB = require("../../../db")
const linkRows = require("../../../db/linkedRows") const linkRows = require("../../../db/linkedRows")
const { getRowParams, generateTableID } = require("../../../db/utils") const { getRowParams, generateTableID } = require("../../../db/utils")
const { FieldTypes } = require("../../../constants") const { FieldTypes } = require("../../../constants")
@ -9,10 +8,10 @@ const {
handleDataImport, handleDataImport,
} = require("./utils") } = require("./utils")
const usageQuota = require("../../../utilities/usageQuota") const usageQuota = require("../../../utilities/usageQuota")
const { getAppDB } = require("@budibase/backend-core/context")
exports.save = async function (ctx) { exports.save = async function (ctx) {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
const { dataImport, ...rest } = ctx.request.body const { dataImport, ...rest } = ctx.request.body
let tableToSave = { let tableToSave = {
type: "table", type: "table",
@ -79,7 +78,6 @@ exports.save = async function (ctx) {
// update linked rows // update linked rows
try { try {
const linkResp = await linkRows.updateLinks({ const linkResp = await linkRows.updateLinks({
appId,
eventType: oldTable eventType: oldTable
? linkRows.EventType.TABLE_UPDATED ? linkRows.EventType.TABLE_UPDATED
: linkRows.EventType.TABLE_SAVE, : linkRows.EventType.TABLE_SAVE,
@ -108,8 +106,7 @@ exports.save = async function (ctx) {
} }
exports.destroy = async function (ctx) { exports.destroy = async function (ctx) {
const appId = ctx.appId const db = getAppDB()
const db = new CouchDB(appId)
const tableToDelete = await db.get(ctx.params.tableId) const tableToDelete = await db.get(ctx.params.tableId)
// Delete all rows for that table // Delete all rows for that table
@ -123,7 +120,6 @@ exports.destroy = async function (ctx) {
// update linked rows // update linked rows
await linkRows.updateLinks({ await linkRows.updateLinks({
appId,
eventType: linkRows.EventType.TABLE_DELETE, eventType: linkRows.EventType.TABLE_DELETE,
table: tableToDelete, table: tableToDelete,
}) })

View File

@ -11,8 +11,8 @@ const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
const { const {
getDevelopmentAppID, getDevelopmentAppID,
getDeployedAppIDs, getDeployedAppIDs,
dbExists,
} = require("@budibase/backend-core/db") } = require("@budibase/backend-core/db")
const { doesDatabaseExist } = require("../../utilities")
const { UserStatus } = require("@budibase/backend-core/constants") const { UserStatus } = require("@budibase/backend-core/constants")
const { getAppDB } = require("@budibase/backend-core/context") const { getAppDB } = require("@budibase/backend-core/context")
@ -102,7 +102,7 @@ exports.syncUser = async function (ctx) {
const roleId = roles[prodAppId] const roleId = roles[prodAppId]
const devAppId = getDevelopmentAppID(prodAppId) const devAppId = getDevelopmentAppID(prodAppId)
for (let appId of [prodAppId, devAppId]) { for (let appId of [prodAppId, devAppId]) {
if (!(await doesDatabaseExist(appId))) { if (!(await dbExists(appId))) {
continue continue
} }
const db = getAppDB() const db = getAppDB()

View File

@ -1,9 +1,9 @@
const CouchDB = require("../../db")
const { generateWebhookID, getWebhookParams } = require("../../db/utils") const { generateWebhookID, getWebhookParams } = require("../../db/utils")
const toJsonSchema = require("to-json-schema") const toJsonSchema = require("to-json-schema")
const validate = require("jsonschema").validate const validate = require("jsonschema").validate
const triggers = require("../../automations/triggers") const triggers = require("../../automations/triggers")
const { getDeployedAppID } = require("@budibase/backend-core/db") const { getDeployedAppID } = require("@budibase/backend-core/db")
const { getAppDB, updateAppId } = require("@budibase/backend-core/context")
const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema" const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema"
@ -23,7 +23,7 @@ exports.WebhookType = {
} }
exports.fetch = async ctx => { exports.fetch = async ctx => {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const response = await db.allDocs( const response = await db.allDocs(
getWebhookParams(null, { getWebhookParams(null, {
include_docs: true, include_docs: true,
@ -33,7 +33,7 @@ exports.fetch = async ctx => {
} }
exports.save = async ctx => { exports.save = async ctx => {
const db = new CouchDB(ctx.appId) const db = getAppDB()
const webhook = ctx.request.body const webhook = ctx.request.body
webhook.appId = ctx.appId webhook.appId = ctx.appId
@ -52,12 +52,13 @@ exports.save = async ctx => {
} }
exports.destroy = async ctx => { exports.destroy = async ctx => {
const db = new CouchDB(ctx.appId) const db = getAppDB()
ctx.body = await db.remove(ctx.params.id, ctx.params.rev) ctx.body = await db.remove(ctx.params.id, ctx.params.rev)
} }
exports.buildSchema = async ctx => { exports.buildSchema = async ctx => {
const db = new CouchDB(ctx.params.instance) updateAppId(ctx.params.instance)
const db = getAppDB()
const webhook = await db.get(ctx.params.id) const webhook = await db.get(ctx.params.id)
webhook.bodySchema = toJsonSchema(ctx.request.body) webhook.bodySchema = toJsonSchema(ctx.request.body)
// update the automation outputs // update the automation outputs
@ -81,9 +82,10 @@ exports.buildSchema = async ctx => {
} }
exports.trigger = async ctx => { exports.trigger = async ctx => {
const prodAppId = getDeployedAppID(ctx.params.instance) const deployedAppId = getDeployedAppID(ctx.params.instance)
updateAppId(deployedAppId)
try { try {
const db = new CouchDB(prodAppId) const db = getAppDB()
const webhook = await db.get(ctx.params.id) const webhook = await db.get(ctx.params.id)
// validate against the schema // validate against the schema
if (webhook.bodySchema) { if (webhook.bodySchema) {
@ -96,7 +98,7 @@ exports.trigger = async ctx => {
await triggers.externalTrigger(target, { await triggers.externalTrigger(target, {
body: ctx.request.body, body: ctx.request.body,
...ctx.request.body, ...ctx.request.body,
appId: prodAppId, appId: deployedAppId,
}) })
} }
ctx.status = 200 ctx.status = 200

View File

@ -1,4 +1,3 @@
const CouchDB = require("../db")
const emitter = require("../events/index") const emitter = require("../events/index")
const { getAutomationParams } = require("../db/utils") const { getAutomationParams } = require("../db/utils")
const { coerce } = require("../utilities/rowProcessor") const { coerce } = require("../utilities/rowProcessor")
@ -9,6 +8,7 @@ const { queue } = require("./bullboard")
const { checkTestFlag } = require("../utilities/redis") const { checkTestFlag } = require("../utilities/redis")
const utils = require("./utils") const utils = require("./utils")
const env = require("../environment") const env = require("../environment")
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const TRIGGER_DEFINITIONS = definitions const TRIGGER_DEFINITIONS = definitions
const JOB_OPTS = { const JOB_OPTS = {
@ -21,7 +21,8 @@ async function queueRelevantRowAutomations(event, eventType) {
throw `No appId specified for ${eventType} - check event emitters.` throw `No appId specified for ${eventType} - check event emitters.`
} }
const db = new CouchDB(event.appId) doInAppContext(event.appId, async () => {
const db = getAppDB()
let automations = await db.allDocs( let automations = await db.allDocs(
getAutomationParams(null, { include_docs: true }) getAutomationParams(null, { include_docs: true })
) )
@ -54,6 +55,7 @@ async function queueRelevantRowAutomations(event, eventType) {
await queue.add({ automation, event }, JOB_OPTS) await queue.add({ automation, event }, JOB_OPTS)
} }
} }
})
} }
emitter.on("row:save", async function (event) { emitter.on("row:save", async function (event) {

View File

@ -8,6 +8,7 @@ const { updateEntityMetadata } = require("../utilities")
const { MetadataTypes } = require("../constants") const { MetadataTypes } = require("../constants")
const { getDeployedAppID } = require("@budibase/backend-core/db") const { getDeployedAppID } = require("@budibase/backend-core/db")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const { getAppDB, getAppId } = require("@budibase/backend-core/context")
const WH_STEP_ID = definitions.WEBHOOK.stepId const WH_STEP_ID = definitions.WEBHOOK.stepId
const CRON_STEP_ID = definitions.CRON.stepId const CRON_STEP_ID = definitions.CRON.stepId
@ -27,7 +28,6 @@ exports.processEvent = async job => {
exports.updateTestHistory = async (appId, automation, history) => { exports.updateTestHistory = async (appId, automation, history) => {
return updateEntityMetadata( return updateEntityMetadata(
appId,
MetadataTypes.AUTOMATION_TEST_HISTORY, MetadataTypes.AUTOMATION_TEST_HISTORY,
automation._id, automation._id,
metadata => { metadata => {
@ -109,7 +109,8 @@ exports.enableCronTrigger = async (appId, automation) => {
* @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
* written to DB (this does not write to DB as it would be wasteful to repeat). * written to DB (this does not write to DB as it would be wasteful to repeat).
*/ */
exports.checkForWebhooks = async ({ appId, oldAuto, newAuto }) => { exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
const appId = getAppId()
const oldTrigger = oldAuto ? oldAuto.definition.trigger : null const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
const newTrigger = newAuto ? newAuto.definition.trigger : null const newTrigger = newAuto ? newAuto.definition.trigger : null
const triggerChanged = const triggerChanged =
@ -128,7 +129,7 @@ exports.checkForWebhooks = async ({ appId, oldAuto, newAuto }) => {
oldTrigger.webhookId oldTrigger.webhookId
) { ) {
try { try {
let db = new CouchDB(appId) let db = getAppDB()
// need to get the webhook to get the rev // need to get the webhook to get the rev
const webhook = await db.get(oldTrigger.webhookId) const webhook = await db.get(oldTrigger.webhookId)
const ctx = { const ctx = {

View File

@ -96,9 +96,9 @@ async function getFullLinkedDocs(links) {
* @param {string} args.eventType states what type of change which is occurring, means this can be expanded upon in the * @param {string} args.eventType states what type of change which is occurring, means this can be expanded upon in the
* future quite easily (all updates go through one function). * future quite easily (all updates go through one function).
* @param {string} args.tableId The ID of the of the table which is being changed. * @param {string} args.tableId The ID of the of the table which is being changed.
* @param {object|null} args.row The row which is changing, e.g. created, updated or deleted. * @param {object|undefined} args.row The row which is changing, e.g. created, updated or deleted.
* @param {object|null} args.table If the table has already been retrieved this can be used to reduce database gets. * @param {object|undefined} args.table If the table has already been retrieved this can be used to reduce database gets.
* @param {object|null} args.oldTable If the table is being updated then the old table can be provided for differencing. * @param {object|undefined} args.oldTable If the table is being updated then the old table can be provided for differencing.
* @returns {Promise<object>} When the update is complete this will respond successfully. Returns the row for * @returns {Promise<object>} When the update is complete this will respond successfully. Returns the row for
* row operations and the table for table operations. * row operations and the table for table operations.
*/ */

View File

@ -1,4 +1,3 @@
const CouchDB = require("../db")
const usageQuota = require("../utilities/usageQuota") const usageQuota = require("../utilities/usageQuota")
const { getUniqueRows } = require("../utilities/usageQuota/rows") const { getUniqueRows } = require("../utilities/usageQuota/rows")
const { const {
@ -6,6 +5,7 @@ const {
isRowId: isExternalRowId, isRowId: isExternalRowId,
} = require("../integrations/utils") } = require("../integrations/utils")
const migration = require("../migrations/usageQuotas") const migration = require("../migrations/usageQuotas")
const { getAppDB } = require("@budibase/backend-core/context")
// currently only counting new writes and deletes // currently only counting new writes and deletes
const METHOD_MAP = { const METHOD_MAP = {
@ -47,7 +47,7 @@ module.exports = async (ctx, next) => {
const usageId = ctx.request.body._id const usageId = ctx.request.body._id
try { try {
if (ctx.appId) { if (ctx.appId) {
const db = new CouchDB(ctx.appId) const db = getAppDB()
await db.get(usageId) await db.get(usageId)
} }
return next() return next()

View File

@ -180,8 +180,8 @@ class TestConfiguration {
} }
async deploy() { async deploy() {
const deployment = await this._req(null, null, controllers.deploy.deployApp) await this._req(null, null, controllers.deploy.deployApp)
const prodAppId = deployment.appId.replace("_dev", "") const prodAppId = this.getAppId().replace("_dev", "")
const appPackage = await this._req( const appPackage = await this._req(
null, null,
{ appId: prodAppId }, { appId: prodAppId },

View File

@ -5,11 +5,11 @@ const automationUtils = require("../automations/automationUtils")
const AutomationEmitter = require("../events/AutomationEmitter") const AutomationEmitter = require("../events/AutomationEmitter")
const { processObject } = require("@budibase/string-templates") const { processObject } = require("@budibase/string-templates")
const { DEFAULT_TENANT_ID } = require("@budibase/backend-core/constants") const { DEFAULT_TENANT_ID } = require("@budibase/backend-core/constants")
const CouchDB = require("../db")
const { DocumentTypes, isDevAppID } = require("../db/utils") const { DocumentTypes, isDevAppID } = require("../db/utils")
const { doInTenant } = require("@budibase/backend-core/tenancy") const { doInTenant } = require("@budibase/backend-core/tenancy")
const usage = require("../utilities/usageQuota") const usage = require("../utilities/usageQuota")
const { definitions: triggerDefs } = require("../automations/triggerInfo") const { definitions: triggerDefs } = require("../automations/triggerInfo")
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
const CRON_STEP_ID = triggerDefs.CRON.stepId const CRON_STEP_ID = triggerDefs.CRON.stepId
@ -59,11 +59,10 @@ class Orchestrator {
} }
async getApp() { async getApp() {
const appId = this._appId
if (this._app) { if (this._app) {
return this._app return this._app
} }
const db = new CouchDB(appId) const db = getAppDB()
this._app = await db.get(DocumentTypes.APP_METADATA) this._app = await db.get(DocumentTypes.APP_METADATA)
return this._app return this._app
} }
@ -131,6 +130,8 @@ class Orchestrator {
} }
module.exports = (input, callback) => { module.exports = (input, callback) => {
const appId = input.data.event.appId
doInAppContext(appId, () => {
const automationOrchestrator = new Orchestrator( const automationOrchestrator = new Orchestrator(
input.data.automation, input.data.automation,
input.data.event input.data.event
@ -143,4 +144,5 @@ module.exports = (input, callback) => {
.catch(err => { .catch(err => {
callback(err) callback(err)
}) })
})
} }

View File

@ -3,14 +3,13 @@ threadUtils.threadSetup()
const ScriptRunner = require("../utilities/scriptRunner") const ScriptRunner = require("../utilities/scriptRunner")
const { integrations } = require("../integrations") const { integrations } = require("../integrations")
const { processStringSync } = require("@budibase/string-templates") const { processStringSync } = require("@budibase/string-templates")
const CouchDB = require("../db") const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/) const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/)
const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/) const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/)
class QueryRunner { class QueryRunner {
constructor(input, flags = { noRecursiveQuery: false }) { constructor(input, flags = { noRecursiveQuery: false }) {
this.appId = input.appId
this.datasource = input.datasource this.datasource = input.datasource
this.queryVerb = input.queryVerb this.queryVerb = input.queryVerb
this.fields = input.fields this.fields = input.fields
@ -104,12 +103,11 @@ class QueryRunner {
} }
async runAnotherQuery(queryId, parameters) { async runAnotherQuery(queryId, parameters) {
const db = new CouchDB(this.appId) const db = getAppDB()
const query = await db.get(queryId) const query = await db.get(queryId)
const datasource = await db.get(query.datasourceId) const datasource = await db.get(query.datasourceId)
return new QueryRunner( return new QueryRunner(
{ {
appId: this.appId,
datasource, datasource,
queryVerb: query.queryVerb, queryVerb: query.queryVerb,
fields: query.fields, fields: query.fields,
@ -223,6 +221,7 @@ class QueryRunner {
} }
module.exports = (input, callback) => { module.exports = (input, callback) => {
doInAppContext(input.appId, () => {
const Runner = new QueryRunner(input) const Runner = new QueryRunner(input)
Runner.execute() Runner.execute()
.then(response => { .then(response => {
@ -231,4 +230,5 @@ module.exports = (input, callback) => {
.catch(err => { .catch(err => {
callback(err) callback(err)
}) })
})
} }

View File

@ -1,9 +1,9 @@
const env = require("../environment") const env = require("../environment")
const { OBJ_STORE_DIRECTORY } = require("../constants") const { OBJ_STORE_DIRECTORY } = require("../constants")
const { sanitizeKey } = require("@budibase/backend-core/objectStore") const { sanitizeKey } = require("@budibase/backend-core/objectStore")
const CouchDB = require("../db")
const { generateMetadataID } = require("../db/utils") const { generateMetadataID } = require("../db/utils")
const Readable = require("stream").Readable const Readable = require("stream").Readable
const { getAppDB } = require("@budibase/backend-core/context")
const BB_CDN = "https://cdn.budi.live" const BB_CDN = "https://cdn.budi.live"
@ -73,8 +73,8 @@ exports.attachmentsRelativeURL = attachmentKey => {
) )
} }
exports.updateEntityMetadata = async (appId, type, entityId, updateFn) => { exports.updateEntityMetadata = async (type, entityId, updateFn) => {
const db = new CouchDB(appId) const db = getAppDB()
const id = generateMetadataID(type, entityId) const id = generateMetadataID(type, entityId)
// read it to see if it exists, we'll overwrite it no matter what // read it to see if it exists, we'll overwrite it no matter what
let rev, let rev,
@ -99,14 +99,14 @@ exports.updateEntityMetadata = async (appId, type, entityId, updateFn) => {
} }
} }
exports.saveEntityMetadata = async (appId, type, entityId, metadata) => { exports.saveEntityMetadata = async (type, entityId, metadata) => {
return exports.updateEntityMetadata(appId, type, entityId, () => { return exports.updateEntityMetadata(type, entityId, () => {
return metadata return metadata
}) })
} }
exports.deleteEntityMetadata = async (appId, type, entityId) => { exports.deleteEntityMetadata = async (type, entityId) => {
const db = new CouchDB(appId) const db = getAppDB()
const id = generateMetadataID(type, entityId) const id = generateMetadataID(type, entityId)
let rev let rev
try { try {
@ -141,16 +141,6 @@ exports.stringToReadStream = string => {
}) })
} }
exports.doesDatabaseExist = async dbName => {
try {
const db = new CouchDB(dbName, { skip_setup: true })
const info = await db.info()
return info && !info.error
} catch (err) {
return false
}
}
exports.formatBytes = bytes => { exports.formatBytes = bytes => {
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
const byteIncrements = 1024 const byteIncrements = 1024

View File

@ -1,9 +1,9 @@
const CouchDB = require("../../db")
const { createRoutingView } = require("../../db/views/staticViews") const { createRoutingView } = require("../../db/views/staticViews")
const { ViewNames, getQueryIndex, UNICODE_MAX } = require("../../db/utils") const { ViewNames, getQueryIndex, UNICODE_MAX } = require("../../db/utils")
const { getAppDB } = require("@budibase/backend-core/context")
exports.getRoutingInfo = async appId => { exports.getRoutingInfo = async () => {
const db = new CouchDB(appId) const db = getAppDB()
try { try {
const allRouting = await db.query(getQueryIndex(ViewNames.ROUTING), { const allRouting = await db.query(getQueryIndex(ViewNames.ROUTING), {
startKey: "", startKey: "",
@ -14,8 +14,8 @@ exports.getRoutingInfo = async appId => {
// check if the view doesn't exist, it should for all new instances // check if the view doesn't exist, it should for all new instances
/* istanbul ignore next */ /* istanbul ignore next */
if (err != null && err.name === "not_found") { if (err != null && err.name === "not_found") {
await createRoutingView(appId) await createRoutingView()
return exports.getRoutingInfo(appId) return exports.getRoutingInfo()
} else { } else {
throw err throw err
} }

File diff suppressed because it is too large Load Diff