1
0
Fork 0
mirror of synced 2024-09-09 22:16: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, aliases: tableAliases,
}) })
// add sorting to pre-query // add sorting to pre-query
query = this.addSorting(query, json) if (!counting) {
query = this.addSorting(query, json)
}
const alias = tableAliases?.[tableName] || tableName const alias = tableAliases?.[tableName] || tableName
let preQuery = knex({ let preQuery = knex({
[alias]: query, [alias]: query,
@ -610,7 +612,7 @@ class InternalBuilder {
preQuery = preQuery.select(selectStatement) preQuery = preQuery.select(selectStatement)
} }
// have to add after as well (this breaks MS-SQL) // 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) preQuery = this.addSorting(preQuery, json)
} }
// handle joins // handle joins

View file

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

View file

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

View file

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

View file

@ -249,7 +249,8 @@ export default class AliasTables {
json.endpoint.operation = Operation.COUNT json.endpoint.operation = Operation.COUNT
let response = await this.queryWithAliasing(json, queryFn) let response = await this.queryWithAliasing(json, queryFn)
if (response && response.length === 1 && "total" in response[0]) { 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 { } else {
throw new Error("Unable to count rows in query - no count response") throw new Error("Unable to count rows in query - no count response")
} }

View file

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

View file

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