Getting counting flow working correctly for external datasources.
This commit is contained in:
parent
908b77fd9b
commit
1b36d8af51
7 changed files with 44 additions and 20 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")) {
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ export async function getDatasourceAndQuery(
|
||||||
table,
|
table,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return makeExternalQuery(datasource, json)
|
return makeExternalQuery(json, datasource)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanExportRows(
|
export function cleanExportRows(
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue