Changing how counting occurs in SQL layer.
This commit is contained in:
parent
aab100b130
commit
1056efdbf6
|
@ -595,19 +595,23 @@ class InternalBuilder {
|
||||||
return query.upsert(parsedBody)
|
return query.upsert(parsedBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
read(knex: Knex, json: QueryJson, limit: number): Knex.QueryBuilder {
|
read(
|
||||||
|
knex: Knex,
|
||||||
|
json: QueryJson,
|
||||||
|
limits?: { base?: number; query?: number }
|
||||||
|
): Knex.QueryBuilder {
|
||||||
let { endpoint, resource, filters, paginate, relationships, tableAliases } =
|
let { endpoint, resource, filters, paginate, relationships, tableAliases } =
|
||||||
json
|
json
|
||||||
const counting = endpoint.operation === Operation.COUNT
|
|
||||||
|
|
||||||
const tableName = endpoint.entityId
|
const tableName = endpoint.entityId
|
||||||
|
const counting = endpoint.operation === Operation.COUNT
|
||||||
// select all if not specified
|
// select all if not specified
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
resource = { fields: [] }
|
resource = { fields: [] }
|
||||||
}
|
}
|
||||||
let selectStatement: string | (string | Knex.Raw)[] = "*"
|
let selectStatement: string | (string | Knex.Raw)[] = "*"
|
||||||
// handle select
|
// handle select
|
||||||
if (!counting && resource.fields && resource.fields.length > 0) {
|
if (resource.fields && resource.fields.length > 0) {
|
||||||
// select the resources as the format "table.columnName" - this is what is provided
|
// select the resources as the format "table.columnName" - this is what is provided
|
||||||
// by the resource builder further up
|
// by the resource builder further up
|
||||||
selectStatement = generateSelectStatement(json, knex)
|
selectStatement = generateSelectStatement(json, knex)
|
||||||
|
@ -616,7 +620,7 @@ class InternalBuilder {
|
||||||
let query = this.knexWithAlias(knex, endpoint, tableAliases)
|
let query = this.knexWithAlias(knex, endpoint, tableAliases)
|
||||||
// handle pagination
|
// handle pagination
|
||||||
let foundOffset: number | null = null
|
let foundOffset: number | null = null
|
||||||
let foundLimit = limit || BASE_LIMIT
|
let foundLimit = limits?.query || limits?.base
|
||||||
if (paginate && paginate.page && paginate.limit) {
|
if (paginate && paginate.page && paginate.limit) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const page = paginate.page <= 1 ? 0 : paginate.page - 1
|
const page = paginate.page <= 1 ? 0 : paginate.page - 1
|
||||||
|
@ -629,12 +633,12 @@ class InternalBuilder {
|
||||||
} else if (paginate && paginate.limit) {
|
} else if (paginate && paginate.limit) {
|
||||||
foundLimit = paginate.limit
|
foundLimit = paginate.limit
|
||||||
}
|
}
|
||||||
// always add the found limit, unless counting
|
// add the found limit if supplied
|
||||||
if (!counting) {
|
if (foundLimit) {
|
||||||
query = query.limit(foundLimit)
|
query = query.limit(foundLimit)
|
||||||
}
|
}
|
||||||
// add overall pagination
|
// add overall pagination
|
||||||
if (!counting && foundOffset) {
|
if (foundOffset) {
|
||||||
query = query.offset(foundOffset)
|
query = query.offset(foundOffset)
|
||||||
}
|
}
|
||||||
// add filters to the query (where)
|
// add filters to the query (where)
|
||||||
|
@ -642,9 +646,11 @@ class InternalBuilder {
|
||||||
aliases: tableAliases,
|
aliases: tableAliases,
|
||||||
})
|
})
|
||||||
// add sorting to pre-query
|
// add sorting to pre-query
|
||||||
|
// no point in sorting when counting
|
||||||
if (!counting) {
|
if (!counting) {
|
||||||
query = this.addSorting(query, json)
|
query = this.addSorting(query, json)
|
||||||
}
|
}
|
||||||
|
|
||||||
const alias = tableAliases?.[tableName] || tableName
|
const alias = tableAliases?.[tableName] || tableName
|
||||||
let preQuery: Knex.QueryBuilder = knex({
|
let preQuery: Knex.QueryBuilder = knex({
|
||||||
// the typescript definition for the knex constructor doesn't support this
|
// the typescript definition for the knex constructor doesn't support this
|
||||||
|
@ -653,11 +659,7 @@ class InternalBuilder {
|
||||||
// be a table name, not a pre-query
|
// be a table name, not a pre-query
|
||||||
[alias]: query as any,
|
[alias]: query as any,
|
||||||
})
|
})
|
||||||
if (counting) {
|
preQuery = preQuery.select(selectStatement)
|
||||||
preQuery = preQuery.count("* as total")
|
|
||||||
} else {
|
|
||||||
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 && !counting) {
|
if (this.client !== SqlClient.MS_SQL && !counting) {
|
||||||
preQuery = this.addSorting(preQuery, json)
|
preQuery = this.addSorting(preQuery, json)
|
||||||
|
@ -672,8 +674,9 @@ class InternalBuilder {
|
||||||
)
|
)
|
||||||
|
|
||||||
// add a base limit over the whole query
|
// add a base limit over the whole query
|
||||||
if (!counting) {
|
// if counting we can't set this limit
|
||||||
query = query.limit(BASE_LIMIT)
|
if (limits?.base) {
|
||||||
|
query = query.limit(limits.base)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.addFilters(query, filters, json.meta.table, {
|
return this.addFilters(query, filters, json.meta.table, {
|
||||||
|
@ -682,6 +685,15 @@ class InternalBuilder {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count(knex: Knex, json: QueryJson) {
|
||||||
|
const readQuery = this.read(knex, json)
|
||||||
|
// have to alias the sub-query, this is a requirement for my-sql and ms-sql
|
||||||
|
// without this we get an error "Every derived table must have its own alias"
|
||||||
|
return knex({
|
||||||
|
subquery: readQuery as any,
|
||||||
|
}).count("* as total")
|
||||||
|
}
|
||||||
|
|
||||||
update(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder {
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder {
|
||||||
const { endpoint, body, filters, tableAliases } = json
|
const { endpoint, body, filters, tableAliases } = json
|
||||||
let query = this.knexWithAlias(knex, endpoint, tableAliases)
|
let query = this.knexWithAlias(knex, endpoint, tableAliases)
|
||||||
|
@ -756,8 +768,13 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
|
||||||
query = builder.create(client, json, opts)
|
query = builder.create(client, json, opts)
|
||||||
break
|
break
|
||||||
case Operation.READ:
|
case Operation.READ:
|
||||||
|
query = builder.read(client, json, {
|
||||||
|
query: this.limit,
|
||||||
|
base: BASE_LIMIT,
|
||||||
|
})
|
||||||
|
break
|
||||||
case Operation.COUNT:
|
case Operation.COUNT:
|
||||||
query = builder.read(client, json, this.limit)
|
query = builder.count(client, json)
|
||||||
break
|
break
|
||||||
case Operation.UPDATE:
|
case Operation.UPDATE:
|
||||||
query = builder.update(client, json, opts)
|
query = builder.update(client, json, opts)
|
||||||
|
|
Loading…
Reference in New Issue