Fixes for a lot of issues generated by the use of the pouchdb allDbs call, which is not designed for multi-client DB setups like ours, using CouchDB method instead.

This commit is contained in:
mike12345567 2021-08-06 16:38:07 +01:00
parent cea35f7fd4
commit be48677490
10 changed files with 43 additions and 31 deletions

View File

@ -1,5 +1,8 @@
const { newid } = require("../hashing") const { newid } = require("../hashing")
const Replication = require("./Replication") const Replication = require("./Replication")
const env = require("../environment")
const fetch = require("node-fetch")
const { getCouch } = require("./index")
const UNICODE_MAX = "\ufff0" const UNICODE_MAX = "\ufff0"
const SEPARATOR = "_" const SEPARATOR = "_"
@ -156,6 +159,23 @@ exports.getDeployedAppID = appId => {
return appId return appId
} }
/**
* if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing
* when using Pouch it will use the pouchdb-all-dbs package.
*/
exports.getAllDbs = async () => {
// specifically for testing we use the pouch package for this
if (env.isTest()) {
return getCouch().allDbs()
}
const response = await fetch(`${env.COUCH_DB_URL}/_all_dbs`)
if (response.status === 200) {
return response.json()
} else {
throw "Cannot connect to CouchDB instance"
}
}
/** /**
* Lots of different points in the system need to find the full list of apps, this will * Lots of different points in the system need to find the full list of apps, this will
* enumerate the entire CouchDB cluster and get the list of databases (every app). * enumerate the entire CouchDB cluster and get the list of databases (every app).
@ -164,8 +184,8 @@ exports.getDeployedAppID = appId => {
* @return {Promise<object[]>} returns the app information document stored in each app database. * @return {Promise<object[]>} returns the app information document stored in each app database.
*/ */
exports.getAllApps = async ({ CouchDB, dev, all } = {}) => { exports.getAllApps = async ({ CouchDB, dev, all } = {}) => {
let allDbs = await CouchDB.allDbs() let dbs = await exports.getAllDbs()
const appDbNames = allDbs.filter(dbName => const appDbNames = dbs.filter(dbName =>
dbName.startsWith(exports.APP_PREFIX) dbName.startsWith(exports.APP_PREFIX)
) )
const appPromises = appDbNames.map(db => const appPromises = appDbNames.map(db =>

View File

@ -1,5 +1,4 @@
const PouchDB = require("pouchdb") const PouchDB = require("pouchdb")
const allDbs = require("pouchdb-all-dbs")
const env = require("../../../../environment") const env = require("../../../../environment")
let POUCH_DB_DEFAULTS let POUCH_DB_DEFAULTS
@ -15,6 +14,4 @@ if (env.isTest()) {
const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS) const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS)
allDbs(Pouch)
module.exports = Pouch module.exports = Pouch

View File

@ -9,6 +9,7 @@
Checkbox, Checkbox,
} from "@budibase/bbui" } from "@budibase/bbui"
import { store, automationStore, hostingStore } from "builderStore" import { store, automationStore, hostingStore } from "builderStore"
import { admin } from "stores/portal"
import { string, mixed, object } from "yup" import { string, mixed, object } from "yup"
import api, { get, post } from "builderStore/api" import api, { get, post } from "builderStore/api"
import analytics from "analytics" import analytics from "analytics"
@ -102,6 +103,8 @@
if (applicationPkg.ok) { if (applicationPkg.ok) {
await store.actions.initialise(pkg) await store.actions.initialise(pkg)
await automationStore.actions.fetch() await automationStore.actions.fetch()
// update checklist - incase first app
await admin.init()
} else { } else {
throw new Error(pkg) throw new Error(pkg)
} }

View File

@ -18,7 +18,7 @@
import api, { del } from "builderStore/api" import api, { del } from "builderStore/api"
import analytics from "analytics" import analytics from "analytics"
import { onMount } from "svelte" import { onMount } from "svelte"
import { apps, auth } from "stores/portal" import { apps, auth, admin } from "stores/portal"
import download from "downloadjs" import download from "downloadjs"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
@ -159,6 +159,8 @@
throw json.message throw json.message
} }
await apps.load() await apps.load()
// get checklist, just in case that was the last app
await admin.init()
notifications.success("App deleted successfully") notifications.success("App deleted successfully")
} catch (err) { } catch (err) {
notifications.error(`Error deleting app: ${err}`) notifications.error(`Error deleting app: ${err}`)

View File

@ -2,7 +2,7 @@ import { writable, get } from "svelte/store"
import api from "builderStore/api" import api from "builderStore/api"
const DEFAULT_CONFIG = { const DEFAULT_CONFIG = {
platformUrl: "http://localhost:1000", platformUrl: "http://localhost:10000",
logoUrl: undefined, logoUrl: undefined,
docsUrl: undefined, docsUrl: undefined,
company: "Budibase", company: "Budibase",

View File

@ -7,6 +7,7 @@
const CouchDB = require("../src/db") const CouchDB = require("../src/db")
const { DocumentTypes } = require("../src/db/utils") const { DocumentTypes } = require("../src/db/utils")
const { getAllDbs } = require("@budibase/auth/db")
const appName = process.argv[2].toLowerCase() const appName = process.argv[2].toLowerCase()
const remoteUrl = process.argv[3] const remoteUrl = process.argv[3]
@ -14,8 +15,8 @@ const remoteUrl = process.argv[3]
console.log(`Replicating from ${appName} to ${remoteUrl}/${appName}`) console.log(`Replicating from ${appName} to ${remoteUrl}/${appName}`)
const run = async () => { const run = async () => {
const allDbs = await CouchDB.allDbs() const dbs = await getAllDbs()
const appDbNames = allDbs.filter(dbName => dbName.startsWith("inst_app")) const appDbNames = dbs.filter(dbName => dbName.startsWith("inst_app"))
let apps = [] let apps = []
for (let dbName of appDbNames) { for (let dbName of appDbNames) {
const db = new CouchDB(dbName) const db = new CouchDB(dbName)

View File

@ -24,21 +24,7 @@ if (env.isTest()) {
const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS) const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS)
// have to still have pouch alldbs for testing
allDbs(Pouch) allDbs(Pouch)
// replicate your local levelDB pouch to a running HTTP compliant couch or pouchdb server.
/* istanbul ignore next */
// eslint-disable-next-line no-unused-vars
function replicateLocal() {
Pouch.allDbs().then(dbs => {
for (let db of dbs) {
new Pouch(db).sync(
new PouchDB(`http://127.0.0.1:5984/${db}`, { live: true })
)
}
})
}
// replicateLocal()
module.exports = Pouch module.exports = Pouch

View File

@ -5,10 +5,13 @@ const {
getConfigParams, getConfigParams,
getGlobalUserParams, getGlobalUserParams,
getScopedFullConfig, getScopedFullConfig,
getAllDbs,
} = require("@budibase/auth").db } = require("@budibase/auth").db
const { Configs } = require("../../../constants") const { Configs } = require("../../../constants")
const email = require("../../../utilities/email") const email = require("../../../utilities/email")
const { upload, ObjectStoreBuckets } = require("@budibase/auth").objectStore const { upload, ObjectStoreBuckets } = require("@budibase/auth").objectStore
const fetch = require("node-fetch")
const env = require("../../../environment")
const APP_PREFIX = "app_" const APP_PREFIX = "app_"
@ -229,8 +232,8 @@ exports.configChecklist = async function (ctx) {
// TODO: Watch get started video // TODO: Watch get started video
// Apps exist // Apps exist
let allDbs = await CouchDB.allDbs() let dbs = await getAllDbs()
const appDbNames = allDbs.filter(dbName => dbName.startsWith(APP_PREFIX)) const appDbNames = dbs.filter(dbName => dbName.startsWith(APP_PREFIX))
// They have set up SMTP // They have set up SMTP
const smtpConfig = await getScopedFullConfig(db, { const smtpConfig = await getScopedFullConfig(db, {

View File

@ -1,15 +1,14 @@
const { DocumentTypes } = require("@budibase/auth").db const { DocumentTypes, getAllDbs } = require("@budibase/auth").db
const CouchDB = require("../../db") const CouchDB = require("../../db")
const APP_PREFIX = "app_" const APP_PREFIX = "app_"
const URL_REGEX_SLASH = /\/|\\/g const URL_REGEX_SLASH = /\/|\\/g
exports.getApps = async ctx => { exports.getApps = async ctx => {
// allDbs call of CouchDB is very inaccurate in production const dbs = await getAllDbs()
const allDbs = await CouchDB.allDbs() const appDbNames = dbs.filter(dbName => dbName.startsWith(APP_PREFIX))
const appDbNames = allDbs.filter(dbName => dbName.startsWith(APP_PREFIX))
const appPromises = appDbNames.map(db => const appPromises = appDbNames.map(db =>
new CouchDB(db).get(DocumentTypes.APP_METADATA) new CouchDB(db, { skip_setup: true }).get(DocumentTypes.APP_METADATA)
) )
const apps = await Promise.allSettled(appPromises) const apps = await Promise.allSettled(appPromises)

View File

@ -19,6 +19,7 @@ if (env.isTest()) {
const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS) const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS)
// have to still have pouch alldbs for testing
allDbs(Pouch) allDbs(Pouch)
module.exports = Pouch module.exports = Pouch