Has any of MySQL filter

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

View File

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

View File

@ -137,6 +137,9 @@ export interface SearchFilters {
notContains?: { notContains?: {
[key: string]: any[] [key: string]: any[]
} }
containsAny?: {
[key: string]: any[]
}
} }
export interface SortJson { 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 fnc = allOr ? "orWhere" : "where"
const rawFnc = `${fnc}Raw` const rawFnc = `${fnc}Raw`
const not = mode === filters?.notContains ? "NOT " : "" const not = mode === filters?.notContains ? "NOT " : ""
@ -182,10 +182,11 @@ class InternalBuilder {
) )
}) })
} else if (this.client === SqlClients.MY_SQL) { } else if (this.client === SqlClients.MY_SQL) {
const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS"
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}JSON_CONTAINS(${key}, ${stringifyArray(value)})` `${not}${jsonFnc}(${key}, ${stringifyArray(value)})`
) )
}) })
} else { } else {
@ -282,6 +283,9 @@ class InternalBuilder {
if (filters.notContains) { if (filters.notContains) {
contains(filters.notContains) contains(filters.notContains)
} }
if (filters.containsAny) {
contains(filters.containsAny, true)
}
return query 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}\"` 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}\"`
})
})
}) })