Changing how apps are retrieved to be more efficient.

This commit is contained in:
mike12345567 2021-07-23 20:01:53 +01:00
parent 9a9c552629
commit 4d0faa38e3
7 changed files with 38 additions and 19 deletions

View File

@ -26,19 +26,24 @@ exports.StaticDatabases = {
}, },
} }
const PRE_APP = "app"
const PRE_DEV = "dev"
const DocumentTypes = { const DocumentTypes = {
USER: "us", USER: "us",
WORKSPACE: "workspace", WORKSPACE: "workspace",
CONFIG: "config", CONFIG: "config",
TEMPLATE: "template", TEMPLATE: "template",
APP: "app", APP: PRE_APP,
APP_DEV: "app_dev", DEV: PRE_DEV,
APP_METADATA: "app_metadata", APP_DEV: `${PRE_APP}${SEPARATOR}${PRE_DEV}`,
APP_METADATA: `${PRE_APP}${SEPARATOR}metadata`,
ROLE: "role", ROLE: "role",
} }
exports.DocumentTypes = DocumentTypes exports.DocumentTypes = DocumentTypes
exports.APP_PREFIX = DocumentTypes.APP + SEPARATOR exports.APP_PREFIX = DocumentTypes.APP + SEPARATOR
exports.APP_DEV =
exports.APP_DEV_PREFIX = DocumentTypes.APP_DEV + SEPARATOR exports.APP_DEV_PREFIX = DocumentTypes.APP_DEV + SEPARATOR
exports.SEPARATOR = SEPARATOR exports.SEPARATOR = SEPARATOR
@ -85,6 +90,9 @@ exports.getGlobalDB = tenantId => {
* Given a koa context this tries to extra what tenant is being accessed. * Given a koa context this tries to extra what tenant is being accessed.
*/ */
exports.getTenantIdFromCtx = ctx => { exports.getTenantIdFromCtx = ctx => {
if (!ctx) {
return null
}
const user = ctx.user || {} const user = ctx.user || {}
const params = ctx.request.params || {} const params = ctx.request.params || {}
const query = ctx.request.query || {} const query = ctx.request.query || {}
@ -208,9 +216,18 @@ exports.getAllApps = async ({ tenantId, dev, all } = {}) => {
} }
const CouchDB = getCouch() const CouchDB = getCouch()
let allDbs = await CouchDB.allDbs() let allDbs = await CouchDB.allDbs()
const appDbNames = allDbs.filter(dbName => const appDbNames = allDbs.filter(dbName => {
dbName.startsWith(exports.APP_PREFIX) const split = dbName.split(SEPARATOR)
) // it is an app, check the tenantId
if (split[0] === DocumentTypes.APP) {
const noTenantId = split.length === 2 || split[1] === DocumentTypes.DEV
// tenantId is always right before the UUID
const possibleTenantId = split[split.length - 2]
return (tenantId === DEFAULT_TENANT_ID && noTenantId) ||
(possibleTenantId === tenantId)
}
return false
})
const appPromises = appDbNames.map(db => const appPromises = appDbNames.map(db =>
// skip setup otherwise databases could be re-created // skip setup otherwise databases could be re-created
new CouchDB(db, { skip_setup: true }).get(DocumentTypes.APP_METADATA) new CouchDB(db, { skip_setup: true }).get(DocumentTypes.APP_METADATA)
@ -222,10 +239,6 @@ exports.getAllApps = async ({ tenantId, dev, all } = {}) => {
const apps = response const apps = response
.filter(result => result.status === "fulfilled") .filter(result => result.status === "fulfilled")
.map(({ value }) => value) .map(({ value }) => value)
.filter(app => {
const appTenant = !app.tenantId ? DEFAULT_TENANT_ID : app.tenantId
return tenantId === appTenant
})
if (!all) { if (!all) {
return apps.filter(app => { return apps.filter(app => {
if (dev) { if (dev) {

View File

@ -47,6 +47,7 @@ async function init() {
COUCH_DB_PASSWORD: "budibase", COUCH_DB_PASSWORD: "budibase",
COUCH_DB_USER: "budibase", COUCH_DB_USER: "budibase",
SELF_HOSTED: 1, SELF_HOSTED: 1,
MULTI_TENANCY: 0,
} }
let envFile = "" let envFile = ""
Object.keys(envFileJson).forEach(key => { Object.keys(envFileJson).forEach(key => {

View File

@ -92,8 +92,8 @@ async function getAppUrlIfNotInUse(ctx) {
return url return url
} }
async function createInstance(template) { async function createInstance(tenantId, template) {
const baseAppId = generateAppID() const baseAppId = generateAppID(env.MULTI_TENANCY ? tenantId : null)
const appId = generateDevAppID(baseAppId) const appId = generateDevAppID(baseAppId)
const db = new CouchDB(appId) const db = new CouchDB(appId)
@ -198,7 +198,7 @@ exports.create = async function (ctx) {
if (ctx.request.files && ctx.request.files.templateFile) { if (ctx.request.files && ctx.request.files.templateFile) {
instanceConfig.file = ctx.request.files.templateFile instanceConfig.file = ctx.request.files.templateFile
} }
const instance = await createInstance(instanceConfig) const instance = await createInstance(tenantId, instanceConfig)
const appId = instance._id const appId = instance._id
const url = await getAppUrlIfNotInUse(ctx) const url = await getAppUrlIfNotInUse(ctx)

View File

@ -225,8 +225,12 @@ exports.getLinkParams = (otherProps = {}) => {
* Generates a new app ID. * Generates a new app ID.
* @returns {string} The new app ID which the app doc can be stored under. * @returns {string} The new app ID which the app doc can be stored under.
*/ */
exports.generateAppID = () => { exports.generateAppID = (tenantId = null) => {
return `${DocumentTypes.APP}${SEPARATOR}${newid()}` let id = `${DocumentTypes.APP}${SEPARATOR}`
if (tenantId) {
id += `${tenantId}${SEPARATOR}`
}
return `${id}${newid()}`
} }
/** /**
@ -235,8 +239,8 @@ exports.generateAppID = () => {
*/ */
exports.generateDevAppID = appId => { exports.generateDevAppID = appId => {
const prefix = `${DocumentTypes.APP}${SEPARATOR}` const prefix = `${DocumentTypes.APP}${SEPARATOR}`
const uuid = appId.split(prefix)[1] const rest = appId.split(prefix)[1]
return `${DocumentTypes.APP_DEV}${SEPARATOR}${uuid}` return `${DocumentTypes.APP_DEV}${SEPARATOR}${rest}`
} }
/** /**

View File

@ -35,6 +35,7 @@ module.exports = {
REDIS_URL: process.env.REDIS_URL, REDIS_URL: process.env.REDIS_URL,
REDIS_PASSWORD: process.env.REDIS_PASSWORD, REDIS_PASSWORD: process.env.REDIS_PASSWORD,
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
MULTI_TENANCY: process.env.MULTI_TENANCY,
// environment // environment
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
JEST_WORKER_ID: process.env.JEST_WORKER_ID, JEST_WORKER_ID: process.env.JEST_WORKER_ID,

View File

@ -16,7 +16,7 @@ async function init() {
REDIS_PASSWORD: "budibase", REDIS_PASSWORD: "budibase",
MINIO_URL: "http://localhost:10000/", MINIO_URL: "http://localhost:10000/",
COUCH_DB_URL: "http://budibase:budibase@localhost:10000/db/", COUCH_DB_URL: "http://budibase:budibase@localhost:10000/db/",
MULTI_TENANCY: false, MULTI_TENANCY: 0,
} }
let envFile = "" let envFile = ""
Object.keys(envFileJson).forEach(key => { Object.keys(envFileJson).forEach(key => {

View File

@ -211,7 +211,7 @@ exports.destroy = async ctx => {
exports.removeAppRole = async ctx => { exports.removeAppRole = async ctx => {
const { appId } = ctx.params const { appId } = ctx.params
const db = getGlobalDBFromCtx(ctx) const db = getGlobalDBFromCtx(ctx)
const users = await allUsers() const users = await allUsers(ctx)
const bulk = [] const bulk = []
const cacheInvalidations = [] const cacheInvalidations = []
for (let user of users) { for (let user of users) {