Merge pull request #12765 from Budibase/fix/remove-db-head-requests
Remove constant CouchDB HEAD requests
This commit is contained in:
commit
4da2b0e361
|
@ -19,6 +19,8 @@ import { WriteStream, ReadStream } from "fs"
|
||||||
import { newid } from "../../docIds/newid"
|
import { newid } from "../../docIds/newid"
|
||||||
import { DDInstrumentedDatabase } from "../instrumentation"
|
import { DDInstrumentedDatabase } from "../instrumentation"
|
||||||
|
|
||||||
|
const DATABASE_NOT_FOUND = "Database does not exist."
|
||||||
|
|
||||||
function buildNano(couchInfo: { url: string; cookie: string }) {
|
function buildNano(couchInfo: { url: string; cookie: string }) {
|
||||||
return Nano({
|
return Nano({
|
||||||
url: couchInfo.url,
|
url: couchInfo.url,
|
||||||
|
@ -31,6 +33,8 @@ function buildNano(couchInfo: { url: string; cookie: string }) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DBCall<T> = () => Promise<T>
|
||||||
|
|
||||||
export function DatabaseWithConnection(
|
export function DatabaseWithConnection(
|
||||||
dbName: string,
|
dbName: string,
|
||||||
connection: string,
|
connection: string,
|
||||||
|
@ -78,7 +82,11 @@ export class DatabaseImpl implements Database {
|
||||||
return this.instanceNano || DatabaseImpl.nano
|
return this.instanceNano || DatabaseImpl.nano
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkSetup() {
|
private getDb() {
|
||||||
|
return this.nano().db.use(this.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkAndCreateDb() {
|
||||||
let shouldCreate = !this.pouchOpts?.skip_setup
|
let shouldCreate = !this.pouchOpts?.skip_setup
|
||||||
// check exists in a lightweight fashion
|
// check exists in a lightweight fashion
|
||||||
let exists = await this.exists()
|
let exists = await this.exists()
|
||||||
|
@ -95,14 +103,22 @@ export class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.nano().db.use(this.name)
|
return this.getDb()
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateOutput(fnc: any) {
|
// this function fetches the DB and handles if DB creation is needed
|
||||||
|
private async performCall<T>(
|
||||||
|
call: (db: Nano.DocumentScope<any>) => Promise<DBCall<T>> | DBCall<T>
|
||||||
|
): Promise<any> {
|
||||||
|
const db = this.getDb()
|
||||||
|
const fnc = await call(db)
|
||||||
try {
|
try {
|
||||||
return await fnc()
|
return await fnc()
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.statusCode) {
|
if (err.statusCode === 404 && err.reason === DATABASE_NOT_FOUND) {
|
||||||
|
await this.checkAndCreateDb()
|
||||||
|
return await this.performCall(call)
|
||||||
|
} else if (err.statusCode) {
|
||||||
err.status = err.statusCode
|
err.status = err.statusCode
|
||||||
}
|
}
|
||||||
throw err
|
throw err
|
||||||
|
@ -110,11 +126,12 @@ export class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
async get<T extends Document>(id?: string): Promise<T> {
|
async get<T extends Document>(id?: string): Promise<T> {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
throw new Error("Unable to get doc without a valid _id.")
|
throw new Error("Unable to get doc without a valid _id.")
|
||||||
}
|
}
|
||||||
return this.updateOutput(() => db.get(id))
|
return () => db.get(id)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMultiple<T extends Document>(
|
async getMultiple<T extends Document>(
|
||||||
|
@ -147,7 +164,7 @@ export class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(idOrDoc: string | Document, rev?: string) {
|
async remove(idOrDoc: string | Document, rev?: string) {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
let _id: string
|
let _id: string
|
||||||
let _rev: string
|
let _rev: string
|
||||||
|
|
||||||
|
@ -162,7 +179,8 @@ export class DatabaseImpl implements Database {
|
||||||
if (!_id || !_rev) {
|
if (!_id || !_rev) {
|
||||||
throw new Error("Unable to remove doc without a valid _id and _rev.")
|
throw new Error("Unable to remove doc without a valid _id and _rev.")
|
||||||
}
|
}
|
||||||
return this.updateOutput(() => db.destroy(_id, _rev))
|
return () => db.destroy(_id, _rev)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(document: AnyDocument, opts?: DatabasePutOpts) {
|
async post(document: AnyDocument, opts?: DatabasePutOpts) {
|
||||||
|
@ -176,7 +194,7 @@ export class DatabaseImpl implements Database {
|
||||||
if (!document._id) {
|
if (!document._id) {
|
||||||
throw new Error("Cannot store document without _id field.")
|
throw new Error("Cannot store document without _id field.")
|
||||||
}
|
}
|
||||||
const db = await this.checkSetup()
|
return this.performCall(async db => {
|
||||||
if (!document.createdAt) {
|
if (!document.createdAt) {
|
||||||
document.createdAt = new Date().toISOString()
|
document.createdAt = new Date().toISOString()
|
||||||
}
|
}
|
||||||
|
@ -193,28 +211,32 @@ export class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.updateOutput(() => db.insert(document))
|
return () => db.insert(document)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async bulkDocs(documents: AnyDocument[]) {
|
async bulkDocs(documents: AnyDocument[]) {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
return this.updateOutput(() => db.bulk({ docs: documents }))
|
return () => db.bulk({ docs: documents })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async allDocs<T extends Document>(
|
async allDocs<T extends Document>(
|
||||||
params: DatabaseQueryOpts
|
params: DatabaseQueryOpts
|
||||||
): Promise<AllDocsResponse<T>> {
|
): Promise<AllDocsResponse<T>> {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
return this.updateOutput(() => db.list(params))
|
return () => db.list(params)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async query<T extends Document>(
|
async query<T extends Document>(
|
||||||
viewName: string,
|
viewName: string,
|
||||||
params: DatabaseQueryOpts
|
params: DatabaseQueryOpts
|
||||||
): Promise<AllDocsResponse<T>> {
|
): Promise<AllDocsResponse<T>> {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
const [database, view] = viewName.split("/")
|
const [database, view] = viewName.split("/")
|
||||||
return this.updateOutput(() => db.view(database, view, params))
|
return () => db.view(database, view, params)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async destroy() {
|
async destroy() {
|
||||||
|
@ -231,8 +253,9 @@ export class DatabaseImpl implements Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
async compact() {
|
async compact() {
|
||||||
const db = await this.checkSetup()
|
return this.performCall(db => {
|
||||||
return this.updateOutput(() => db.compact())
|
return () => db.compact()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// All below functions are in-frequently called, just utilise PouchDB
|
// All below functions are in-frequently called, just utilise PouchDB
|
||||||
|
|
|
@ -31,13 +31,6 @@ export class DDInstrumentedDatabase implements Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSetup(): Promise<DocumentScope<any>> {
|
|
||||||
return tracer.trace("db.checkSetup", span => {
|
|
||||||
span?.addTags({ db_name: this.name })
|
|
||||||
return this.db.checkSetup()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
get<T extends Document>(id?: string | undefined): Promise<T> {
|
get<T extends Document>(id?: string | undefined): Promise<T> {
|
||||||
return tracer.trace("db.get", span => {
|
return tracer.trace("db.get", span => {
|
||||||
span?.addTags({ db_name: this.name, doc_id: id })
|
span?.addTags({ db_name: this.name, doc_id: id })
|
||||||
|
|
|
@ -121,7 +121,6 @@ export interface Database {
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
exists(): Promise<boolean>
|
exists(): Promise<boolean>
|
||||||
checkSetup(): Promise<Nano.DocumentScope<any>>
|
|
||||||
get<T extends Document>(id?: string): Promise<T>
|
get<T extends Document>(id?: string): Promise<T>
|
||||||
getMultiple<T extends Document>(
|
getMultiple<T extends Document>(
|
||||||
ids: string[],
|
ids: string[],
|
||||||
|
|
Loading…
Reference in New Issue