1
0
Fork 0
mirror of synced 2024-08-05 13:21:26 +12:00

Getting counting flow working correctly for external datasources.

This commit is contained in:
mike12345567 2024-06-14 19:00:59 +01:00
parent 908b77fd9b
commit 1b36d8af51
7 changed files with 44 additions and 20 deletions

View file

@ -599,7 +599,9 @@ class InternalBuilder {
aliases: tableAliases,
})
// add sorting to pre-query
query = this.addSorting(query, json)
if (!counting) {
query = this.addSorting(query, json)
}
const alias = tableAliases?.[tableName] || tableName
let preQuery = knex({
[alias]: query,
@ -610,7 +612,7 @@ class InternalBuilder {
preQuery = preQuery.select(selectStatement)
}
// have to add after as well (this breaks MS-SQL)
if (this.client !== SqlClient.MS_SQL) {
if (this.client !== SqlClient.MS_SQL && !counting) {
preQuery = this.addSorting(preQuery, json)
}
// handle joins

View file

@ -7,6 +7,7 @@ import {
FieldType,
FilterType,
IncludeRelationship,
isManyToOne,
OneToManyRelationshipFieldMetadata,
Operation,
PaginationJson,
@ -16,22 +17,21 @@ import {
SortJson,
SortType,
Table,
isManyToOne,
} from "@budibase/types"
import {
breakExternalTableId,
breakRowIdField,
convertRowId,
generateRowIdField,
isRowId,
isSQL,
generateRowIdField,
} from "../../../integrations/utils"
import {
buildExternalRelationships,
buildSqlFieldList,
generateIdForRow,
sqlOutputProcessing,
isManyToMany,
sqlOutputProcessing,
} from "./utils"
import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils"
import { processObjectSync } from "@budibase/string-templates"
@ -61,6 +61,13 @@ export interface RunConfig {
includeSqlRelationships?: IncludeRelationship
}
export type ExternalRequestReturnType<T extends Operation> =
T extends Operation.READ
? Row[]
: T extends Operation.COUNT
? number
: { row: Row; table: Table }
function buildFilters(
id: string | undefined | string[],
filters: SearchFilters,
@ -224,9 +231,6 @@ function isEditableColumn(column: FieldSchema) {
return !(isExternalAutoColumn || isFormula)
}
export type ExternalRequestReturnType<T extends Operation> =
T extends Operation.READ ? Row[] : { row: Row; table: Table }
export class ExternalRequest<T extends Operation> {
private readonly operation: T
private readonly tableId: string
@ -429,7 +433,10 @@ export class ExternalRequest<T extends Operation> {
})
// this is the response from knex if no rows found
const rows: Row[] =
!Array.isArray(response) || response?.[0].read ? [] : response
!Array.isArray(response) ||
(response.length === 1 && "read" in response[0])
? []
: response
const storeTo = isManyToMany(field)
? field.throughFrom || linkPrimaryKey
: fieldName
@ -664,10 +671,15 @@ export class ExternalRequest<T extends Operation> {
// aliasing can be disabled fully if desired
let response
const aliasing = new sdk.rows.AliasTables(Object.keys(this.tables))
if (env.SQL_ALIASING_DISABLE) {
response = await getDatasourceAndQuery(json)
} else if (this.operation === Operation.COUNT) {
return (await aliasing.countWithAliasing(
json,
makeExternalQuery
)) as ExternalRequestReturnType<T>
} else {
const aliasing = new sdk.rows.AliasTables(Object.keys(this.tables))
response = await aliasing.queryWithAliasing(json, makeExternalQuery)
}

View file

@ -33,5 +33,5 @@ export async function makeTableRequest(
if (renamed) {
json.meta!.renamed = renamed
}
return makeExternalQuery(datasource, json)
return makeExternalQuery(json, datasource)
}

View file

@ -1,14 +1,14 @@
import {
SortJson,
IncludeRelationship,
Operation,
PaginationJson,
IncludeRelationship,
Row,
SearchFilters,
RowSearchParams,
SearchFilters,
SearchResponse,
Table,
SortJson,
SortOrder,
Table,
} from "@budibase/types"
import * as exporters from "../../../../api/controllers/view/exporters"
import { handleRequest } from "../../../../api/controllers/row/external"
@ -18,7 +18,7 @@ import {
} from "../../../../integrations/utils"
import { utils } from "@budibase/shared-core"
import { ExportRowsParams, ExportRowsResult } from "./types"
import { HTTPError, db } from "@budibase/backend-core"
import { db, HTTPError } from "@budibase/backend-core"
import pick from "lodash/pick"
import { outputProcessing } from "../../../../utilities/rowProcessor"
import sdk from "../../../"
@ -75,12 +75,17 @@ export async function search(
}
try {
let rows = await handleRequest(Operation.READ, tableId, {
const parameters = {
filters: query,
sort,
paginate: paginateObj as PaginationJson,
includeSqlRelationships: IncludeRelationship.INCLUDE,
})
}
let rows = await handleRequest(Operation.READ, tableId, parameters)
let totalRows: number | undefined
if (true) {
totalRows = await handleRequest(Operation.COUNT, tableId, parameters)
}
let hasNextPage = false
// remove the extra row if it's there
if (paginate && limit && rows.length > limit) {
@ -103,6 +108,9 @@ export async function search(
if (hasNextPage && bookmark != null) {
response.bookmark = bookmark + 1
}
if (totalRows != null) {
response.totalRows = totalRows
}
return response
} catch (err: any) {
if (err.message && err.message.includes("does not exist")) {

View file

@ -249,7 +249,8 @@ export default class AliasTables {
json.endpoint.operation = Operation.COUNT
let response = await this.queryWithAliasing(json, queryFn)
if (response && response.length === 1 && "total" in response[0]) {
return response[0].total
const total = response[0].total
return typeof total === "number" ? total : parseInt(total)
} else {
throw new Error("Unable to count rows in query - no count response")
}

View file

@ -61,7 +61,7 @@ export async function getDatasourceAndQuery(
table,
}
}
return makeExternalQuery(datasource, json)
return makeExternalQuery(json, datasource)
}
export function cleanExportRows(

View file

@ -197,6 +197,7 @@ enum DSPlusOperation {
export type DatasourcePlusQueryResponse =
| Row[]
| Record<DSPlusOperation, boolean>[]
| { total: number }[]
| void
export interface DatasourcePlus extends IntegrationBase {