Merge pull request #14086 from Budibase/fix/couchdb-integration

Typescript improvements for CouchDB integration
This commit is contained in:
Michael Drury 2024-07-04 11:21:56 +01:00 committed by GitHub
commit 86bf153740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 37 deletions

View File

@ -80,6 +80,11 @@ export function DatabaseWithConnection(
connection: string, connection: string,
opts?: DatabaseOpts opts?: DatabaseOpts
) { ) {
if (!dbName || !connection) {
throw new Error(
"Unable to create database without database name or connection"
)
}
const db = new DatabaseImpl(dbName, opts, connection) const db = new DatabaseImpl(dbName, opts, connection)
return new DDInstrumentedDatabase(db) return new DDInstrumentedDatabase(db)
} }

View File

@ -71,6 +71,9 @@ class CouchDBIntegration implements IntegrationBase {
private readonly client: Database private readonly client: Database
constructor(config: CouchDBConfig) { constructor(config: CouchDBConfig) {
if (!config.url || !config.database) {
throw new Error("Unable to connect without URL or database")
}
this.client = dbCore.DatabaseWithConnection(config.database, config.url) this.client = dbCore.DatabaseWithConnection(config.database, config.url)
} }
@ -79,45 +82,30 @@ class CouchDBIntegration implements IntegrationBase {
connected: false, connected: false,
} }
try { try {
const result = await this.query("exists", "validation error", {}) response.connected = await this.client.exists()
response.connected = result === true
} catch (e: any) { } catch (e: any) {
response.error = e.message as string response.error = e.message as string
} }
return response return response
} }
async query(
command: string,
errorMsg: string,
query: { json?: object; id?: string }
) {
try {
return await (this.client as any)[command](query.id || query.json)
} catch (err) {
console.error(errorMsg, err)
throw err
}
}
private parse(query: { json: string | object }) { private parse(query: { json: string | object }) {
return typeof query.json === "string" ? JSON.parse(query.json) : query.json return typeof query.json === "string" ? JSON.parse(query.json) : query.json
} }
async create(query: { json: string | object }) { async create(query: { json: string | object }) {
const parsed = this.parse(query) const parsed = this.parse(query)
return this.query("post", "Error writing to couchDB", { json: parsed }) return await this.client.put(parsed)
} }
async read(query: { json: string | object }) { async read(query: { json: string | object }) {
const parsed = this.parse(query) const parsed = this.parse(query)
const result = await this.query("allDocs", "Error querying couchDB", { const params = {
json: {
include_docs: true, include_docs: true,
...parsed, ...parsed,
}, }
}) const result = await this.client.allDocs(params)
return result.rows.map((row: { doc: object }) => row.doc) return result.rows.map(row => row.doc)
} }
async update(query: { json: string | object }) { async update(query: { json: string | object }) {
@ -126,22 +114,15 @@ class CouchDBIntegration implements IntegrationBase {
const oldDoc = await this.get({ id: parsed._id }) const oldDoc = await this.get({ id: parsed._id })
parsed._rev = oldDoc._rev parsed._rev = oldDoc._rev
} }
return this.query("put", "Error updating couchDB document", { return await this.client.put(parsed)
json: parsed,
})
} }
async get(query: { id: string }) { async get(query: { id: string }) {
return this.query("get", "Error retrieving couchDB document by ID", { return await this.client.get(query.id)
id: query.id,
})
} }
async delete(query: { id: string }) { async delete(query: { id: string }) {
const doc = await this.query("get", "Cannot find doc to be deleted", query) return await this.client.remove(query.id)
return this.query("remove", "Error deleting couchDB document", {
json: doc,
})
} }
} }

View File

@ -6,7 +6,6 @@ jest.mock("@budibase/backend-core", () => {
...core.db, ...core.db,
DatabaseWithConnection: function () { DatabaseWithConnection: function () {
return { return {
post: jest.fn(),
allDocs: jest.fn().mockReturnValue({ rows: [] }), allDocs: jest.fn().mockReturnValue({ rows: [] }),
put: jest.fn(), put: jest.fn(),
get: jest.fn().mockReturnValue({ _rev: "a" }), get: jest.fn().mockReturnValue({ _rev: "a" }),
@ -43,7 +42,7 @@ describe("CouchDB Integration", () => {
await config.integration.create({ await config.integration.create({
json: JSON.stringify(doc), json: JSON.stringify(doc),
}) })
expect(config.integration.client.post).toHaveBeenCalledWith(doc) expect(config.integration.client.put).toHaveBeenCalledWith(doc)
}) })
it("calls the read method with the correct params", async () => { it("calls the read method with the correct params", async () => {
@ -80,7 +79,6 @@ describe("CouchDB Integration", () => {
it("calls the delete method with the correct params", async () => { it("calls the delete method with the correct params", async () => {
const id = "1234" const id = "1234"
await config.integration.delete({ id }) await config.integration.delete({ id })
expect(config.integration.client.get).toHaveBeenCalledWith(id) expect(config.integration.client.remove).toHaveBeenCalledWith(id)
expect(config.integration.client.remove).toHaveBeenCalled()
}) })
}) })