Has any of MySQL filter

This commit is contained in:
Mel O'Hagan 2022-07-27 13:19:47 +01:00
parent b5dbeb49e4
commit 17bb56a772
4 changed files with 55 additions and 3 deletions

View File

@ -48,7 +48,7 @@ export const OperatorOptions = {
},
ContainsAny: {
value: "containsAny",
label: "Has any"
label: "Has any",
},
}

View File

@ -137,6 +137,9 @@ export interface SearchFilters {
notContains?: {
[key: string]: any[]
}
containsAny?: {
[key: string]: any[]
}
}
export interface SortJson {

View File

@ -157,7 +157,7 @@ class InternalBuilder {
}
}
const contains = (mode: object) => {
const contains = (mode: object, any: boolean = false) => {
const fnc = allOr ? "orWhere" : "where"
const rawFnc = `${fnc}Raw`
const not = mode === filters?.notContains ? "NOT " : ""
@ -182,10 +182,11 @@ class InternalBuilder {
)
})
} else if (this.client === SqlClients.MY_SQL) {
const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS"
iterate(mode, (key: string, value: Array<any>) => {
// @ts-ignore
query = query[rawFnc](
`${not}JSON_CONTAINS(${key}, ${stringifyArray(value)})`
`${not}${jsonFnc}(${key}, ${stringifyArray(value)})`
)
})
} else {
@ -282,6 +283,9 @@ class InternalBuilder {
if (filters.notContains) {
contains(filters.notContains)
}
if (filters.containsAny) {
contains(filters.containsAny, true)
}
return query
}

View File

@ -329,4 +329,49 @@ describe("SQL query builder", () => {
sql: `select * from (select * from \"${TABLE_NAME}\" where NOT \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and NOT \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"`
})
})
it("should use OR like expression for MS-SQL when filter is containsAny", () => {
const query = new Sql(SqlClients.MS_SQL, 10)._query(generateReadJson({
filters: {
containsAny: {
age: [20, 25],
name: ["John", "Mary"]
}
}
}))
expect(query).toEqual({
bindings: [10, "%20%", "%25%", `%"John"%`, `%"Mary"%`],
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}]`
})
})
it("should use JSON_OVERLAPS expression for MySQL when filter is containsAny", () => {
const query = new Sql(SqlClients.MY_SQL, 10)._query(generateReadJson({
filters: {
containsAny: {
age: [20, 25],
name: ["John", "Mary"]
}
}
}))
expect(query).toEqual({
bindings: [10],
sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_OVERLAPS(${TABLE_NAME}.age, '[20,25]') and JSON_OVERLAPS(${TABLE_NAME}.name, '["John","Mary"]') limit ?) as \`${TABLE_NAME}\``
})
})
it("should use OR jsonb operator expression for PostgreSQL when filter is containsAny", () => {
const query = new Sql(SqlClients.POSTGRES, 10)._query(generateReadJson({
filters: {
containsAny: {
age: [20],
name: ["John"]
}
}
}))
expect(query).toEqual({
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}\"`
})
})
})