Updating how between/less than/greater than are handled for sqlite.
This commit is contained in:
parent
94fb8b748a
commit
60ed4d8443
|
@ -6,6 +6,7 @@ import {
|
|||
SqlClient,
|
||||
isValidFilter,
|
||||
getNativeSql,
|
||||
SqlStatements,
|
||||
} from "../utils"
|
||||
import SqlTableQueryBuilder from "./sqlTable"
|
||||
import {
|
||||
|
@ -163,6 +164,13 @@ class InternalBuilder {
|
|||
table: Table,
|
||||
opts: { aliases?: Record<string, string>; relationship?: boolean }
|
||||
): Knex.QueryBuilder {
|
||||
if (!filters) {
|
||||
return query
|
||||
}
|
||||
filters = parseFilters(filters)
|
||||
// if all or specified in filters, then everything is an or
|
||||
const allOr = filters.allOr
|
||||
const sqlStatements = new SqlStatements(this.client, table, { allOr })
|
||||
const tableName =
|
||||
this.client === SqlClient.SQL_LITE ? table._id! : table.name
|
||||
|
||||
|
@ -261,12 +269,6 @@ class InternalBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
if (!filters) {
|
||||
return query
|
||||
}
|
||||
filters = parseFilters(filters)
|
||||
// if all or specified in filters, then everything is an or
|
||||
const allOr = filters.allOr
|
||||
if (filters.oneOf) {
|
||||
iterate(filters.oneOf, (key, array) => {
|
||||
const fnc = allOr ? "orWhereIn" : "whereIn"
|
||||
|
@ -293,9 +295,6 @@ class InternalBuilder {
|
|||
}
|
||||
if (filters.range) {
|
||||
iterate(filters.range, (key, value) => {
|
||||
const fieldName = key.split(".")[1]
|
||||
const field = table.schema[fieldName]
|
||||
|
||||
const isEmptyObject = (val: any) => {
|
||||
return (
|
||||
val &&
|
||||
|
@ -312,47 +311,11 @@ class InternalBuilder {
|
|||
const lowValid = isValidFilter(value.low),
|
||||
highValid = isValidFilter(value.high)
|
||||
if (lowValid && highValid) {
|
||||
// Use a between operator if we have 2 valid range values
|
||||
if (
|
||||
field.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(
|
||||
`CAST(${key} AS INTEGER) BETWEEN CAST(? AS INTEGER) AND CAST(? AS INTEGER)`,
|
||||
[value.low, value.high]
|
||||
)
|
||||
} else {
|
||||
const fnc = allOr ? "orWhereBetween" : "whereBetween"
|
||||
query = query[fnc](key, [value.low, value.high])
|
||||
}
|
||||
query = sqlStatements.between(query, key, value.low, value.high)
|
||||
} else if (lowValid) {
|
||||
// Use just a single greater than operator if we only have a low
|
||||
if (
|
||||
field.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(
|
||||
`CAST(${key} AS INTEGER) >= CAST(? AS INTEGER)`,
|
||||
[value.low]
|
||||
)
|
||||
} else {
|
||||
const fnc = allOr ? "orWhere" : "where"
|
||||
query = query[fnc](key, ">=", value.low)
|
||||
}
|
||||
query = sqlStatements.lower(query, key, value.low)
|
||||
} else if (highValid) {
|
||||
// Use just a single less than operator if we only have a high
|
||||
if (
|
||||
field.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(
|
||||
`CAST(${key} AS INTEGER) <= CAST(? AS INTEGER)`,
|
||||
[value.high]
|
||||
)
|
||||
} else {
|
||||
const fnc = allOr ? "orWhere" : "where"
|
||||
query = query[fnc](key, "<=", value.high)
|
||||
}
|
||||
query = sqlStatements.higher(query, key, value.high)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { SqlClient } from "../utils"
|
||||
import Sql from "../base/sql"
|
||||
import {
|
||||
FieldType,
|
||||
Operation,
|
||||
QueryJson,
|
||||
TableSourceType,
|
||||
Table,
|
||||
FieldType,
|
||||
TableSourceType,
|
||||
} from "@budibase/types"
|
||||
|
||||
const TABLE_NAME = "test"
|
||||
|
@ -13,7 +13,12 @@ const TABLE: Table = {
|
|||
type: "table",
|
||||
sourceType: TableSourceType.EXTERNAL,
|
||||
sourceId: "SOURCE_ID",
|
||||
schema: {},
|
||||
schema: {
|
||||
id: {
|
||||
name: "id",
|
||||
type: FieldType.NUMBER,
|
||||
},
|
||||
},
|
||||
name: TABLE_NAME,
|
||||
primary: ["id"],
|
||||
}
|
||||
|
@ -73,7 +78,7 @@ function generateUpdateJson({
|
|||
meta?: any
|
||||
}): QueryJson {
|
||||
if (!meta.table) {
|
||||
meta.table = table
|
||||
meta.table = TABLE
|
||||
}
|
||||
return {
|
||||
endpoint: endpoint(table, "UPDATE"),
|
||||
|
@ -158,6 +163,9 @@ function generateManyRelationshipJson(config: { schema?: string } = {}) {
|
|||
},
|
||||
],
|
||||
extra: { idFilter: {} },
|
||||
meta: {
|
||||
table: TABLE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,7 +349,7 @@ describe("SQL query builder", () => {
|
|||
)
|
||||
expect(query).toEqual({
|
||||
bindings: [date, limit],
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" > $1 limit $2) as "${TABLE_NAME}"`,
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" >= $1 limit $2) as "${TABLE_NAME}"`,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -360,7 +368,7 @@ describe("SQL query builder", () => {
|
|||
)
|
||||
expect(query).toEqual({
|
||||
bindings: [date, limit],
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" < $1 limit $2) as "${TABLE_NAME}"`,
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" <= $1 limit $2) as "${TABLE_NAME}"`,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -594,7 +602,7 @@ describe("SQL query builder", () => {
|
|||
)
|
||||
expect(query).toEqual({
|
||||
bindings: ["2000-01-01 00:00:00", 500],
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."dob" > $1 limit $2) as "${TABLE_NAME}"`,
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."dob" >= $1 limit $2) as "${TABLE_NAME}"`,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -613,7 +621,7 @@ describe("SQL query builder", () => {
|
|||
)
|
||||
expect(query).toEqual({
|
||||
bindings: ["2010-01-01 00:00:00", 500],
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."dob" < $1 limit $2) as "${TABLE_NAME}"`,
|
||||
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."dob" <= $1 limit $2) as "${TABLE_NAME}"`,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./utils"
|
||||
export { SqlStatements } from "./sqlStatements"
|
|
@ -0,0 +1,80 @@
|
|||
import { FieldType, Table, FieldSchema } from "@budibase/types"
|
||||
import { SqlClient } from "./utils"
|
||||
import { Knex } from "knex"
|
||||
|
||||
export class SqlStatements {
|
||||
client: string
|
||||
table: Table
|
||||
allOr: boolean | undefined
|
||||
constructor(
|
||||
client: string,
|
||||
table: Table,
|
||||
{ allOr }: { allOr?: boolean } = {}
|
||||
) {
|
||||
this.client = client
|
||||
this.table = table
|
||||
this.allOr = allOr
|
||||
}
|
||||
|
||||
getField(key: string): FieldSchema | undefined {
|
||||
const fieldName = key.split(".")[1]
|
||||
return this.table.schema[fieldName]
|
||||
}
|
||||
|
||||
between(
|
||||
query: Knex.QueryBuilder,
|
||||
key: string,
|
||||
low: number | string,
|
||||
high: number | string
|
||||
) {
|
||||
// Use a between operator if we have 2 valid range values
|
||||
const field = this.getField(key)
|
||||
if (
|
||||
field?.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(
|
||||
`CAST(${key} AS INTEGER) BETWEEN CAST(? AS INTEGER) AND CAST(? AS INTEGER)`,
|
||||
[low, high]
|
||||
)
|
||||
} else {
|
||||
const fnc = this.allOr ? "orWhereBetween" : "whereBetween"
|
||||
query = query[fnc](key, [low, high])
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
lower(query: Knex.QueryBuilder, key: string, low: number | string) {
|
||||
// Use just a single greater than operator if we only have a low
|
||||
const field = this.getField(key)
|
||||
if (
|
||||
field?.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(`CAST(${key} AS INTEGER) >= CAST(? AS INTEGER)`, [
|
||||
low,
|
||||
])
|
||||
} else {
|
||||
const fnc = this.allOr ? "orWhere" : "where"
|
||||
query = query[fnc](key, ">=", low)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
higher(query: Knex.QueryBuilder, key: string, high: number | string) {
|
||||
const field = this.getField(key)
|
||||
// Use just a single less than operator if we only have a high
|
||||
if (
|
||||
field?.type === FieldType.BIGINT &&
|
||||
this.client === SqlClient.SQL_LITE
|
||||
) {
|
||||
query = query.whereRaw(`CAST(${key} AS INTEGER) <= CAST(? AS INTEGER)`, [
|
||||
high,
|
||||
])
|
||||
} else {
|
||||
const fnc = this.allOr ? "orWhere" : "where"
|
||||
query = query[fnc](key, "<=", high)
|
||||
}
|
||||
return query
|
||||
}
|
||||
}
|
|
@ -5,10 +5,10 @@ import {
|
|||
FieldType,
|
||||
TableSourceType,
|
||||
} from "@budibase/types"
|
||||
import { DocumentType, SEPARATOR } from "../db/utils"
|
||||
import { InvalidColumns, DEFAULT_BB_DATASOURCE_ID } from "../constants"
|
||||
import { DocumentType, SEPARATOR } from "../../db/utils"
|
||||
import { InvalidColumns, DEFAULT_BB_DATASOURCE_ID } from "../../constants"
|
||||
import { helpers } from "@budibase/shared-core"
|
||||
import env from "../environment"
|
||||
import env from "../../environment"
|
||||
import { Knex } from "knex"
|
||||
|
||||
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
Loading…
Reference in New Issue