Re-jigging things a bit, hiding as much of the couch/pouch stuff away.

This commit is contained in:
mike12345567 2022-11-11 12:46:32 +00:00
parent bc94f20794
commit b4b471e054
21 changed files with 138 additions and 142 deletions

View File

@ -3,5 +3,4 @@ module.exports = {
...require("./src/db/constants"),
...require("./src/db"),
...require("./src/db/views"),
...require("./src/db/pouch"),
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}`,
}
}

View File

@ -1,4 +0,0 @@
export * from "./couch"
export * from "./pouchLike"
export * from "./utils"
export { init } from "./pouchDB"

View File

@ -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
}
}

View File

@ -1,4 +1,4 @@
import { getPouchDB, closePouchDB } from "../couch/pouchDB"
import { getPouchDB, closePouchDB } from "./couch/pouchDB"
import { DocumentType } from "./constants"
class Replication {

View File

@ -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,
},
}
}

View File

@ -0,0 +1,4 @@
export * from "./connections"
export * from "./pouchLike"
export * from "./utils"
export { init, getPouch, getPouchDB } from "./pouchDB"

View File

@ -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
}
}

View File

@ -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"

View File

@ -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,

View File

@ -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()

View File

@ -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"

View File

@ -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)
}

View File

@ -3,5 +3,4 @@
export * from "../db"
export * from "../db/utils"
export * from "../db/views"
export * from "../db/pouch"
export * from "../db/constants"

View File

@ -1 +1 @@
export { PouchLike } from "./couch"
export { PouchLike } from "./db"

View File

@ -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"

View File

@ -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"