2022-10-25 10:02:55 +02:00
|
|
|
import * as pouch from "./pouch"
|
2022-10-12 18:02:23 +02:00
|
|
|
import env from "../environment"
|
|
|
|
import { PouchOptions, CouchFindOptions } from "@budibase/types"
|
2022-10-25 10:02:55 +02:00
|
|
|
import PouchDB from "pouchdb"
|
2022-11-08 17:32:13 +01:00
|
|
|
import { PouchLike } from "../couch"
|
2022-11-07 19:27:39 +01:00
|
|
|
import { directCouchQuery } from "../couch"
|
|
|
|
export { directCouchQuery } from "../couch"
|
2021-04-20 18:17:44 +02:00
|
|
|
|
2022-10-12 18:02:23 +02:00
|
|
|
const openDbs: string[] = []
|
2022-10-25 10:02:55 +02:00
|
|
|
let Pouch: any
|
2022-03-29 17:03:44 +02:00
|
|
|
let initialised = false
|
2022-05-20 19:29:37 +02:00
|
|
|
const dbList = new Set()
|
2022-03-29 17:03:44 +02:00
|
|
|
|
2022-07-14 20:02:00 +02:00
|
|
|
if (env.MEMORY_LEAK_CHECK) {
|
2022-07-14 17:02:05 +02:00
|
|
|
setInterval(() => {
|
|
|
|
console.log("--- OPEN DBS ---")
|
|
|
|
console.log(openDbs)
|
|
|
|
}, 5000)
|
|
|
|
}
|
|
|
|
|
2022-03-29 17:03:44 +02:00
|
|
|
const put =
|
2022-10-12 18:02:23 +02:00
|
|
|
(dbPut: any) =>
|
|
|
|
async (doc: any, options = {}) => {
|
2022-03-30 15:24:04 +02:00
|
|
|
if (!doc.createdAt) {
|
|
|
|
doc.createdAt = new Date().toISOString()
|
|
|
|
}
|
|
|
|
doc.updatedAt = new Date().toISOString()
|
|
|
|
return dbPut(doc, options)
|
2022-03-29 17:03:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const checkInitialised = () => {
|
|
|
|
if (!initialised) {
|
|
|
|
throw new Error("init has not been called")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-12 18:34:17 +02:00
|
|
|
export async function init(opts?: PouchOptions) {
|
2022-10-25 10:02:55 +02:00
|
|
|
Pouch = pouch.getPouch(opts)
|
2022-03-29 17:03:44 +02:00
|
|
|
initialised = true
|
2021-04-15 17:45:21 +02:00
|
|
|
}
|
2021-04-15 17:57:01 +02:00
|
|
|
|
2022-11-08 17:32:13 +01:00
|
|
|
export function getPouchDB(dbName: string, opts?: any): PouchDB.Database {
|
2022-03-29 17:03:44 +02:00
|
|
|
checkInitialised()
|
2022-05-20 19:29:37 +02:00
|
|
|
if (env.isTest()) {
|
|
|
|
dbList.add(dbName)
|
|
|
|
}
|
2022-10-25 10:02:55 +02:00
|
|
|
const db = new Pouch(dbName, opts)
|
2022-07-14 20:02:00 +02:00
|
|
|
if (env.MEMORY_LEAK_CHECK) {
|
2022-07-14 17:02:05 +02:00
|
|
|
openDbs.push(db.name)
|
|
|
|
}
|
2022-03-29 17:03:44 +02:00
|
|
|
const dbPut = db.put
|
|
|
|
db.put = put(dbPut)
|
|
|
|
return db
|
2021-04-20 18:17:44 +02:00
|
|
|
}
|
2021-05-14 17:31:07 +02:00
|
|
|
|
2022-11-08 17:32:13 +01:00
|
|
|
// NOTE: THIS IS A DANGEROUS FUNCTION - USE WITH CAUTION
|
|
|
|
// this function is prone to leaks, should only be used
|
|
|
|
// in situations that using the function doWithDB does not work
|
|
|
|
export function dangerousGetDB(dbName: string, opts?: any): PouchLike {
|
|
|
|
return new PouchLike(dbName, opts)
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:33:42 +02:00
|
|
|
// use this function if you have called dangerousGetDB - close
|
|
|
|
// the databases you've opened once finished
|
2022-10-12 18:02:23 +02:00
|
|
|
export async function closeDB(db: PouchDB.Database) {
|
2022-04-21 15:56:14 +02:00
|
|
|
if (!db || env.isTest()) {
|
2022-04-20 18:33:42 +02:00
|
|
|
return
|
|
|
|
}
|
2022-07-14 20:02:00 +02:00
|
|
|
if (env.MEMORY_LEAK_CHECK) {
|
2022-07-14 17:02:05 +02:00
|
|
|
openDbs.splice(openDbs.indexOf(db.name), 1)
|
|
|
|
}
|
2022-04-20 18:33:42 +02:00
|
|
|
try {
|
2022-04-27 16:58:55 +02:00
|
|
|
// specifically await so that if there is an error, it can be ignored
|
|
|
|
return await db.close()
|
2022-04-20 18:33:42 +02:00
|
|
|
} catch (err) {
|
|
|
|
// ignore error, already closed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-19 20:42:52 +02:00
|
|
|
// we have to use a callback for this so that we can close
|
|
|
|
// the DB when we're done, without this manual requests would
|
|
|
|
// need to close the database when done with it to avoid memory leaks
|
2022-10-12 18:02:23 +02:00
|
|
|
export async function doWithDB(dbName: string, cb: any, opts = {}) {
|
2022-10-12 18:37:52 +02:00
|
|
|
const db = dangerousGetDB(dbName, opts)
|
2022-04-19 20:42:52 +02:00
|
|
|
// need this to be async so that we can correctly close DB after all
|
|
|
|
// async operations have been completed
|
2022-11-08 17:32:13 +01:00
|
|
|
return await cb(db)
|
2022-04-19 20:42:52 +02:00
|
|
|
}
|
|
|
|
|
2022-10-12 18:02:23 +02:00
|
|
|
export function allDbs() {
|
2022-05-20 19:29:37 +02:00
|
|
|
if (!env.isTest()) {
|
|
|
|
throw new Error("Cannot be used outside test environment.")
|
|
|
|
}
|
2022-03-29 17:03:44 +02:00
|
|
|
checkInitialised()
|
2022-05-20 19:29:37 +02:00
|
|
|
return [...dbList]
|
2021-05-14 17:31:07 +02:00
|
|
|
}
|
2022-10-12 18:02:23 +02:00
|
|
|
|
2022-10-12 18:57:31 +02:00
|
|
|
export async function directCouchAllDbs(queryString?: string) {
|
|
|
|
let couchPath = "/_all_dbs"
|
|
|
|
if (queryString) {
|
|
|
|
couchPath += `?${queryString}`
|
|
|
|
}
|
|
|
|
return await directCouchQuery(couchPath)
|
|
|
|
}
|
|
|
|
|
2022-10-12 18:02:23 +02:00
|
|
|
export async function directCouchFind(dbName: string, opts: CouchFindOptions) {
|
|
|
|
const json = await directCouchQuery(`${dbName}/_find`, "POST", opts)
|
|
|
|
return { rows: json.docs, bookmark: json.bookmark }
|
|
|
|
}
|