Has any of filter Postgres

This commit is contained in:
Mel O'Hagan 2022-07-27 16:37:29 +01:00
parent 17bb56a772
commit 4abd984d99
2 changed files with 14 additions and 13 deletions

View File

@ -161,24 +161,25 @@ class InternalBuilder {
const fnc = allOr ? "orWhere" : "where" const fnc = allOr ? "orWhere" : "where"
const rawFnc = `${fnc}Raw` const rawFnc = `${fnc}Raw`
const not = mode === filters?.notContains ? "NOT " : "" const not = mode === filters?.notContains ? "NOT " : ""
function stringifyArray(value: Array<any>): string { function stringifyArray(value: Array<any>, quoteStyle = '"'): string {
for (let i in value) { for (let i in value) {
if (typeof value[i] === "string") { if (typeof value[i] === "string") {
value[i] = `"${value[i]}"` value[i] = `${quoteStyle}${value[i]}${quoteStyle}`
} }
} }
return `'[${value.join(",")}]'` return `[${value.join(",")}]`
} }
if (this.client === SqlClients.POSTGRES) { if (this.client === SqlClients.POSTGRES) {
iterate(mode, (key: string, value: Array<any>) => { iterate(mode, (key: string, value: Array<any>) => {
const wrap = any ? "" : "'"
const containsOp = any ? "\\?| array" : "@>"
const fieldNames = key.split(/\./g) const fieldNames = key.split(/\./g)
const tableName = fieldNames[0] const tableName = fieldNames[0]
const columnName = fieldNames[1] const columnName = fieldNames[1]
// @ts-ignore // @ts-ignore
query = query[rawFnc]( query = query[rawFnc](`${not}"${tableName}"."${columnName}"::jsonb ${containsOp} ${wrap}${stringifyArray(
`${not}"${tableName}"."${columnName}"::jsonb @> ${stringifyArray( value, any ? "'" : '"'
value )}${wrap}`
)}`
) )
}) })
} else if (this.client === SqlClients.MY_SQL) { } else if (this.client === SqlClients.MY_SQL) {
@ -186,7 +187,7 @@ class InternalBuilder {
iterate(mode, (key: string, value: Array<any>) => { iterate(mode, (key: string, value: Array<any>) => {
// @ts-ignore // @ts-ignore
query = query[rawFnc]( query = query[rawFnc](
`${not}${jsonFnc}(${key}, ${stringifyArray(value)})` `${not}${jsonFnc}(${key}, '${stringifyArray(value)}')`
) )
}) })
} else { } else {

View File

@ -251,7 +251,7 @@ describe("SQL query builder", () => {
})) }))
expect(query).toEqual({ expect(query).toEqual({
bindings: [10, "%20%", `%"John"%`], bindings: [10, "%20%", `%"John"%`],
sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where LOWER(${TABLE_NAME}.age) LIKE @p1 and LOWER(${TABLE_NAME}.name) LIKE @p2) as [${TABLE_NAME}]` sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where (LOWER(${TABLE_NAME}.age) LIKE @p1) and (LOWER(${TABLE_NAME}.name) LIKE @p2)) as [${TABLE_NAME}]`
}) })
}) })
@ -360,18 +360,18 @@ describe("SQL query builder", () => {
}) })
}) })
it("should use OR jsonb operator expression for PostgreSQL when filter is containsAny", () => { it("should use ?| operator expression for PostgreSQL when filter is containsAny", () => {
const query = new Sql(SqlClients.POSTGRES, 10)._query(generateReadJson({ const query = new Sql(SqlClients.POSTGRES, 10)._query(generateReadJson({
filters: { filters: {
containsAny: { containsAny: {
age: [20], age: [20, 25],
name: ["John"] name: ["John", "Mary"]
} }
} }
})) }))
expect(query).toEqual({ expect(query).toEqual({
bindings: [10], bindings: [10],
sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"` sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb ?| array [20,25] and \"${TABLE_NAME}\".\"name\"::jsonb ?| array ['John','Mary'] limit $1) as \"${TABLE_NAME}\"`
}) })
}) })
}) })