Re-jigging things a bit, hiding as much of the couch/pouch stuff away.
This commit is contained in:
parent
bc94f20794
commit
b4b471e054
|
@ -3,5 +3,4 @@ module.exports = {
|
|||
...require("./src/db/constants"),
|
||||
...require("./src/db"),
|
||||
...require("./src/db/views"),
|
||||
...require("./src/db/pouch"),
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
"preset": "ts-jest",
|
||||
"testEnvironment": "node",
|
||||
"moduleNameMapper": {
|
||||
"@budibase/types": "<rootDir>/../types/src"
|
||||
"@budibase/types": "<rootDir>/../types/src",
|
||||
"axios": "axios/dist/node/axios.cjs"
|
||||
},
|
||||
"setupFiles": [
|
||||
"./scripts/jestSetup.ts"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import BaseCache from "./base"
|
||||
import { getWritethroughClient } from "../redis/init"
|
||||
import { logWarn } from "../logging"
|
||||
import { PouchLike } from "../couch"
|
||||
import { PouchLike } from "../db"
|
||||
|
||||
const DEFAULT_WRITE_RATE_MS = 10000
|
||||
let CACHE: BaseCache | null = null
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { getGlobalUserParams, getAllApps } from "../db/utils"
|
||||
import { doWithDB } from "../db"
|
||||
import { doWithDB, PouchLike } from "../db"
|
||||
import { doWithGlobalDB } from "../tenancy"
|
||||
import { StaticDatabases } from "../db/constants"
|
||||
import { PouchLike } from "../couch"
|
||||
import { User } from "@budibase/types"
|
||||
|
||||
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
|
||||
|
|
|
@ -5,7 +5,7 @@ import { baseGlobalDBName } from "../db/tenancy"
|
|||
import { IdentityContext } from "@budibase/types"
|
||||
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
||||
import { ContextMap, ContextKey } from "./constants"
|
||||
import { PouchLike } from "../couch"
|
||||
import { PouchLike } from "../db"
|
||||
import { getDevelopmentAppID, getProdAppID } from "../db/conversions"
|
||||
|
||||
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import env from "../environment"
|
||||
import { getUrlInfo } from "../db/pouch"
|
||||
|
||||
export const getCouchInfo = () => {
|
||||
const urlInfo = getUrlInfo()
|
||||
let username
|
||||
let password
|
||||
if (env.COUCH_DB_USERNAME) {
|
||||
// set from env
|
||||
username = env.COUCH_DB_USERNAME
|
||||
} else if (urlInfo.auth.username) {
|
||||
// set from url
|
||||
username = urlInfo.auth.username
|
||||
} else if (!env.isTest()) {
|
||||
throw new Error("CouchDB username not set")
|
||||
}
|
||||
if (env.COUCH_DB_PASSWORD) {
|
||||
// set from env
|
||||
password = env.COUCH_DB_PASSWORD
|
||||
} else if (urlInfo.auth.password) {
|
||||
// set from url
|
||||
password = urlInfo.auth.password
|
||||
} else if (!env.isTest()) {
|
||||
throw new Error("CouchDB password not set")
|
||||
}
|
||||
const authCookie = Buffer.from(`${username}:${password}`).toString("base64")
|
||||
return {
|
||||
url: urlInfo.url!,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password,
|
||||
},
|
||||
cookie: `Basic ${authCookie}`,
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
export * from "./couch"
|
||||
export * from "./pouchLike"
|
||||
export * from "./utils"
|
||||
export { init } from "./pouchDB"
|
|
@ -1,37 +0,0 @@
|
|||
import PouchDB from "pouchdb"
|
||||
import env from "../environment"
|
||||
import { PouchOptions } from "@budibase/types"
|
||||
import * as pouch from "../db/pouch"
|
||||
|
||||
let Pouch: any
|
||||
let initialised = false
|
||||
|
||||
export async function init(opts?: PouchOptions) {
|
||||
Pouch = pouch.getPouch(opts)
|
||||
initialised = true
|
||||
}
|
||||
|
||||
const checkInitialised = () => {
|
||||
if (!initialised) {
|
||||
throw new Error("init has not been called")
|
||||
}
|
||||
}
|
||||
|
||||
export function getPouchDB(dbName: string, opts?: any): PouchDB.Database {
|
||||
checkInitialised()
|
||||
return new Pouch(dbName, opts)
|
||||
}
|
||||
|
||||
// use this function if you have called getPouchDB - close
|
||||
// the databases you've opened once finished
|
||||
export async function closePouchDB(db: PouchDB.Database) {
|
||||
if (!db || env.isTest()) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
// specifically await so that if there is an error, it can be ignored
|
||||
return await db.close()
|
||||
} catch (err) {
|
||||
// ignore error, already closed
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { getPouchDB, closePouchDB } from "../couch/pouchDB"
|
||||
import { getPouchDB, closePouchDB } from "./couch/pouchDB"
|
||||
import { DocumentType } from "./constants"
|
||||
|
||||
class Replication {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
import env from "../../environment"
|
||||
|
||||
export const getCouchInfo = () => {
|
||||
const urlInfo = getUrlInfo()
|
||||
let username
|
||||
let password
|
||||
if (env.COUCH_DB_USERNAME) {
|
||||
// set from env
|
||||
username = env.COUCH_DB_USERNAME
|
||||
} else if (urlInfo.auth.username) {
|
||||
// set from url
|
||||
username = urlInfo.auth.username
|
||||
} else if (!env.isTest()) {
|
||||
throw new Error("CouchDB username not set")
|
||||
}
|
||||
if (env.COUCH_DB_PASSWORD) {
|
||||
// set from env
|
||||
password = env.COUCH_DB_PASSWORD
|
||||
} else if (urlInfo.auth.password) {
|
||||
// set from url
|
||||
password = urlInfo.auth.password
|
||||
} else if (!env.isTest()) {
|
||||
throw new Error("CouchDB password not set")
|
||||
}
|
||||
const authCookie = Buffer.from(`${username}:${password}`).toString("base64")
|
||||
return {
|
||||
url: urlInfo.url!,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password,
|
||||
},
|
||||
cookie: `Basic ${authCookie}`,
|
||||
}
|
||||
}
|
||||
|
||||
export const getUrlInfo = (url = env.COUCH_DB_URL) => {
|
||||
let cleanUrl, username, password, host
|
||||
if (url) {
|
||||
// Ensure the URL starts with a protocol
|
||||
const protoRegex = /^https?:\/\//i
|
||||
if (!protoRegex.test(url)) {
|
||||
url = `http://${url}`
|
||||
}
|
||||
|
||||
// Split into protocol and remainder
|
||||
const split = url.split("://")
|
||||
const protocol = split[0]
|
||||
const rest = split.slice(1).join("://")
|
||||
|
||||
// Extract auth if specified
|
||||
if (url.includes("@")) {
|
||||
// Split into host and remainder
|
||||
let parts = rest.split("@")
|
||||
host = parts[parts.length - 1]
|
||||
let auth = parts.slice(0, -1).join("@")
|
||||
|
||||
// Split auth into username and password
|
||||
if (auth.includes(":")) {
|
||||
const authParts = auth.split(":")
|
||||
username = authParts[0]
|
||||
password = authParts.slice(1).join(":")
|
||||
} else {
|
||||
username = auth
|
||||
}
|
||||
} else {
|
||||
host = rest
|
||||
}
|
||||
cleanUrl = `${protocol}://${host}`
|
||||
}
|
||||
return {
|
||||
url: cleanUrl,
|
||||
auth: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export * from "./connections"
|
||||
export * from "./pouchLike"
|
||||
export * from "./utils"
|
||||
export { init, getPouch, getPouchDB } from "./pouchDB"
|
|
@ -1,50 +1,10 @@
|
|||
import PouchDB from "pouchdb"
|
||||
import env from "../environment"
|
||||
import { getCouchInfo } from "../couch"
|
||||
export { getCouchInfo } from "../couch"
|
||||
import env from "../../environment"
|
||||
import { PouchOptions } from "@budibase/types"
|
||||
import { getCouchInfo } from "./connections"
|
||||
|
||||
export const getUrlInfo = (url = env.COUCH_DB_URL) => {
|
||||
let cleanUrl, username, password, host
|
||||
if (url) {
|
||||
// Ensure the URL starts with a protocol
|
||||
const protoRegex = /^https?:\/\//i
|
||||
if (!protoRegex.test(url)) {
|
||||
url = `http://${url}`
|
||||
}
|
||||
|
||||
// Split into protocol and remainder
|
||||
const split = url.split("://")
|
||||
const protocol = split[0]
|
||||
const rest = split.slice(1).join("://")
|
||||
|
||||
// Extract auth if specified
|
||||
if (url.includes("@")) {
|
||||
// Split into host and remainder
|
||||
let parts = rest.split("@")
|
||||
host = parts[parts.length - 1]
|
||||
let auth = parts.slice(0, -1).join("@")
|
||||
|
||||
// Split auth into username and password
|
||||
if (auth.includes(":")) {
|
||||
const authParts = auth.split(":")
|
||||
username = authParts[0]
|
||||
password = authParts.slice(1).join(":")
|
||||
} else {
|
||||
username = auth
|
||||
}
|
||||
} else {
|
||||
host = rest
|
||||
}
|
||||
cleanUrl = `${protocol}://${host}`
|
||||
}
|
||||
return {
|
||||
url: cleanUrl,
|
||||
auth: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
}
|
||||
}
|
||||
let Pouch: any
|
||||
let initialised = false
|
||||
|
||||
/**
|
||||
* Return a constructor for PouchDB.
|
||||
|
@ -92,3 +52,33 @@ export const getPouch = (opts: any = {}) => {
|
|||
|
||||
return PouchDB.defaults(POUCH_DB_DEFAULTS)
|
||||
}
|
||||
|
||||
export async function init(opts?: PouchOptions) {
|
||||
Pouch = getPouch(opts)
|
||||
initialised = true
|
||||
}
|
||||
|
||||
const checkInitialised = () => {
|
||||
if (!initialised) {
|
||||
throw new Error("init has not been called")
|
||||
}
|
||||
}
|
||||
|
||||
export function getPouchDB(dbName: string, opts?: any): PouchDB.Database {
|
||||
checkInitialised()
|
||||
return new Pouch(dbName, opts)
|
||||
}
|
||||
|
||||
// use this function if you have called getPouchDB - close
|
||||
// the databases you've opened once finished
|
||||
export async function closePouchDB(db: PouchDB.Database) {
|
||||
if (!db || env.isTest()) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
// specifically await so that if there is an error, it can be ignored
|
||||
return await db.close()
|
||||
} catch (err) {
|
||||
// ignore error, already closed
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Nano from "nano"
|
||||
import { AllDocsResponse, AnyDocument } from "@budibase/types"
|
||||
import { getCouchInfo } from "./couch"
|
||||
import { getCouchInfo } from "./connections"
|
||||
import { directCouchCall } from "./utils"
|
||||
import { getPouchDB } from "./pouchDB"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { getCouchInfo } from "./couch"
|
||||
import { getCouchInfo } from "./connections"
|
||||
import fetch from "node-fetch"
|
||||
import { checkSlashesInUrl } from "../helpers"
|
||||
import { checkSlashesInUrl } from "../../helpers"
|
||||
|
||||
export async function directCouchCall(
|
||||
path: string,
|
|
@ -1,8 +1,7 @@
|
|||
import env from "../environment"
|
||||
import { CouchFindOptions } from "@budibase/types"
|
||||
import { PouchLike } from "../couch"
|
||||
import { directCouchQuery } from "../couch"
|
||||
export { init, PouchLike } from "../couch"
|
||||
import { directCouchQuery, PouchLike } from "./couch"
|
||||
export { init, PouchLike, getPouch, getPouchDB } from "./couch"
|
||||
|
||||
let initialised = false
|
||||
const dbList = new Set()
|
||||
|
|
|
@ -15,7 +15,7 @@ import { getAppMetadata } from "../cache/appMetadata"
|
|||
import { isDevApp, isDevAppID, getProdAppID } from "./conversions"
|
||||
import { APP_PREFIX } from "./constants"
|
||||
import * as events from "../events"
|
||||
import { PouchLike } from "../couch"
|
||||
import { PouchLike } from "./couch"
|
||||
|
||||
export * from "./constants"
|
||||
export * from "./conversions"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { DocumentType, ViewName, DeprecatedViews, SEPARATOR } from "./utils"
|
||||
import { getGlobalDB } from "../context"
|
||||
import { PouchLike, QueryOpts } from "../couch"
|
||||
import { PouchLike, QueryOpts } from "./couch"
|
||||
import { StaticDatabases } from "./constants"
|
||||
import { doWithDB } from "./"
|
||||
|
||||
|
@ -133,7 +133,9 @@ export const queryView = async <T>(
|
|||
try {
|
||||
let response = await db.query<T>(`database/${viewName}`, params)
|
||||
const rows = response.rows
|
||||
const docs = rows.map(row => (params.include_docs ? row.doc : row.value))
|
||||
const docs = rows.map((row: any) =>
|
||||
params.include_docs ? row.doc : row.value
|
||||
)
|
||||
|
||||
// if arrayResponse has been requested, always return array regardless of length
|
||||
if (opts?.arrayResponse) {
|
||||
|
@ -186,5 +188,5 @@ export const queryGlobalView = async <T>(
|
|||
db = getGlobalDB()
|
||||
}
|
||||
const createFn = CreateFuncByName[viewName]
|
||||
return queryView(viewName, params, db, createFn, opts)
|
||||
return queryView(viewName, params, db!, createFn, opts)
|
||||
}
|
||||
|
|
|
@ -3,5 +3,4 @@
|
|||
export * from "../db"
|
||||
export * from "../db/utils"
|
||||
export * from "../db/views"
|
||||
export * from "../db/pouch"
|
||||
export * from "../db/constants"
|
||||
|
|
|
@ -1 +1 @@
|
|||
export { PouchLike } from "./couch"
|
||||
export { PouchLike } from "./db"
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
"moduleNameMapper": {
|
||||
"@budibase/backend-core/(.*)": "<rootDir>/../backend-core/$1",
|
||||
"@budibase/backend-core": "<rootDir>/../backend-core/src",
|
||||
"@budibase/types": "<rootDir>/../types/src"
|
||||
"@budibase/types": "<rootDir>/../types/src",
|
||||
"axios": "axios/dist/node/axios.cjs"
|
||||
},
|
||||
"setupFiles": [
|
||||
"./scripts/jestSetup.js"
|
||||
|
|
|
@ -98,7 +98,8 @@
|
|||
"moduleNameMapper": {
|
||||
"@budibase/backend-core/(.*)": "<rootDir>/../backend-core/$1",
|
||||
"@budibase/backend-core": "<rootDir>/../backend-core/src",
|
||||
"@budibase/types": "<rootDir>/../types/src"
|
||||
"@budibase/types": "<rootDir>/../types/src",
|
||||
"axios": "axios/dist/node/axios.cjs"
|
||||
},
|
||||
"setupFiles": [
|
||||
"./scripts/jestSetup.js"
|
||||
|
|
Loading…
Reference in New Issue