From 20da8bb816762a93d995ad30011708b53979a7d7 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 10 Apr 2024 17:36:57 +0100 Subject: [PATCH] Adding support for SQS prepared statement API. --- packages/backend-core/src/db/couch/DatabaseImpl.ts | 11 +++++++++-- packages/backend-core/src/db/instrumentation.ts | 8 ++++++-- packages/server/src/sdk/app/rows/search/sqs.ts | 7 ++++--- packages/types/src/sdk/db.ts | 6 +++++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/backend-core/src/db/couch/DatabaseImpl.ts b/packages/backend-core/src/db/couch/DatabaseImpl.ts index c1347f4f2b..d220d0a8ac 100644 --- a/packages/backend-core/src/db/couch/DatabaseImpl.ts +++ b/packages/backend-core/src/db/couch/DatabaseImpl.ts @@ -12,6 +12,7 @@ import { isDocument, RowResponse, RowValue, + SqlQueryBinding, } from "@budibase/types" import { getCouchInfo } from "./connections" import { directCouchUrlCall } from "./utils" @@ -248,14 +249,20 @@ export class DatabaseImpl implements Database { }) } - async sql(sql: string): Promise { + async sql( + sql: string, + parameters?: SqlQueryBinding + ): Promise { const dbName = this.name const url = `/${dbName}/${SQLITE_DESIGN_DOC_ID}` const response = await directCouchUrlCall({ url: `${this.couchInfo.sqlUrl}/${url}`, method: "POST", cookie: this.couchInfo.cookie, - body: sql, + body: { + query: sql, + args: parameters, + }, }) if (response.status > 300) { throw new Error(await response.text()) diff --git a/packages/backend-core/src/db/instrumentation.ts b/packages/backend-core/src/db/instrumentation.ts index 880f0a3c72..32ba81ebd8 100644 --- a/packages/backend-core/src/db/instrumentation.ts +++ b/packages/backend-core/src/db/instrumentation.ts @@ -13,6 +13,7 @@ import { DatabaseQueryOpts, Document, RowValue, + SqlQueryBinding, } from "@budibase/types" import tracer from "dd-trace" import { Writable } from "stream" @@ -150,10 +151,13 @@ export class DDInstrumentedDatabase implements Database { }) } - sql(sql: string): Promise { + sql( + sql: string, + parameters?: SqlQueryBinding + ): Promise { return tracer.trace("db.sql", span => { span?.addTags({ db_name: this.name }) - return this.db.sql(sql) + return this.db.sql(sql, parameters) }) } } diff --git a/packages/server/src/sdk/app/rows/search/sqs.ts b/packages/server/src/sdk/app/rows/search/sqs.ts index 89dae7628f..f270353821 100644 --- a/packages/server/src/sdk/app/rows/search/sqs.ts +++ b/packages/server/src/sdk/app/rows/search/sqs.ts @@ -11,6 +11,7 @@ import { SortOrder, SortType, Table, + SqlQuery, } from "@budibase/types" import SqlQueryBuilder from "../../../../integrations/base/sql" import { SqlClient } from "../../../../integrations/utils" @@ -156,21 +157,21 @@ export async function search( try { const query = builder._query(request, { disableReturning: true, - disableBindings: true, }) if (Array.isArray(query)) { throw new Error("SQS cannot currently handle multiple queries") } - let sql = query.sql + let sql = query.sql, + bindings = query.bindings // quick hack for docIds sql = sql.replace(/`doc1`.`rowId`/g, "`doc1.rowId`") sql = sql.replace(/`doc2`.`rowId`/g, "`doc2.rowId`") const db = context.getAppDB() - const rows = await db.sql(sql) + const rows = await db.sql(sql, bindings) return { rows: await sqlOutputProcessing( diff --git a/packages/types/src/sdk/db.ts b/packages/types/src/sdk/db.ts index 692ddcf737..c723f5f8d6 100644 --- a/packages/types/src/sdk/db.ts +++ b/packages/types/src/sdk/db.ts @@ -4,6 +4,7 @@ import { AnyDocument, Document, RowValue, + SqlQueryBinding, ViewTemplateOpts, } from "../" import { Writable } from "stream" @@ -143,7 +144,10 @@ export interface Database { opts?: DatabasePutOpts ): Promise bulkDocs(documents: AnyDocument[]): Promise - sql(sql: string): Promise + sql( + sql: string, + parameters?: SqlQueryBinding + ): Promise allDocs( params: DatabaseQueryOpts ): Promise>