Updating underlying sql to not use ilike unless in postgres client.

This commit is contained in:
mike12345567 2021-11-05 13:48:13 +00:00
parent 5ec0d803af
commit 3474f3ae8e
3 changed files with 220 additions and 207 deletions

View File

@ -342,7 +342,7 @@ module External {
table: Table,
relationships: RelationshipsJson[]
) {
if (rows[0].read === true) {
if (!rows || rows.length === 0 || rows[0].read === true) {
return []
}
let finalRows: { [key: string]: Row } = {}

View File

@ -29,12 +29,19 @@ function parseBody(body: any) {
return body
}
// right now we only do filters on the specific table being queried
function addFilters(
class InternalBuilder {
private readonly client: string
constructor(client: string) {
this.client = client
}
// right now we only do filters on the specific table being queried
addFilters(
tableName: string,
query: KnexQuery,
filters: SearchFilters | undefined
): KnexQuery {
): KnexQuery {
function iterate(
structure: { [key: string]: any },
fn: (key: string, value: any) => void
@ -57,13 +64,27 @@ function addFilters(
if (filters.string) {
iterate(filters.string, (key, value) => {
const fnc = allOr ? "orWhere" : "where"
// postgres supports ilike, nothing else does
if (this.client === "pg") {
query = query[fnc](key, "ilike", `${value}%`)
} else {
const rawFnc = `${fnc}Raw`
// @ts-ignore
query = query[rawFnc](`LOWER(${key}) LIKE ?`, [`${value}%`])
}
})
}
if (filters.fuzzy) {
iterate(filters.fuzzy, (key, value) => {
const fnc = allOr ? "orWhere" : "where"
// postgres supports ilike, nothing else does
if (this.client === "pg") {
query = query[fnc](key, "ilike", `%${value}%`)
} else {
const rawFnc = `${fnc}Raw`
// @ts-ignore
query = query[rawFnc](`LOWER(${key}) LIKE ?`, [`%${value}%`])
}
})
}
if (filters.range) {
@ -100,15 +121,15 @@ function addFilters(
})
}
return query
}
}
function addRelationships(
addRelationships(
knex: Knex,
query: KnexQuery,
fields: string | string[],
fromTable: string,
relationships: RelationshipsJson[] | undefined
): KnexQuery {
): KnexQuery {
if (!relationships) {
return query
}
@ -138,13 +159,9 @@ function addRelationships(
}
}
return query.limit(BASE_LIMIT)
}
}
function buildCreate(
knex: Knex,
json: QueryJson,
opts: QueryOptions
): KnexQuery {
create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
const { endpoint, body } = json
let query: KnexQuery = knex(endpoint.entityId)
const parsedBody = parseBody(body)
@ -160,9 +177,9 @@ function buildCreate(
} else {
return query.insert(parsedBody).returning("*")
}
}
}
function buildRead(knex: Knex, json: QueryJson, limit: number): KnexQuery {
read(knex: Knex, json: QueryJson, limit: number): KnexQuery {
let { endpoint, resource, filters, sort, paginate, relationships } = json
const tableName = endpoint.entityId
// select all if not specified
@ -199,53 +216,46 @@ function buildRead(knex: Knex, json: QueryJson, limit: number): KnexQuery {
query = query.orderBy(key, direction)
}
}
query = addFilters(tableName, query, filters)
query = this.addFilters(tableName, query, filters)
// @ts-ignore
let preQuery: KnexQuery = knex({
// @ts-ignore
[tableName]: query,
}).select(selectStatement)
// handle joins
return addRelationships(
return this.addRelationships(
knex,
preQuery,
selectStatement,
tableName,
relationships
)
}
}
function buildUpdate(
knex: Knex,
json: QueryJson,
opts: QueryOptions
): KnexQuery {
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
const { endpoint, body, filters } = json
let query: KnexQuery = knex(endpoint.entityId)
const parsedBody = parseBody(body)
query = addFilters(endpoint.entityId, query, filters)
query = this.addFilters(endpoint.entityId, query, filters)
// mysql can't use returning
if (opts.disableReturning) {
return query.update(parsedBody)
} else {
return query.update(parsedBody).returning("*")
}
}
}
function buildDelete(
knex: Knex,
json: QueryJson,
opts: QueryOptions
): KnexQuery {
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
const { endpoint, filters } = json
let query: KnexQuery = knex(endpoint.entityId)
query = addFilters(endpoint.entityId, query, filters)
query = this.addFilters(endpoint.entityId, query, filters)
// mysql can't use returning
if (opts.disableReturning) {
return query.delete()
} else {
return query.delete().returning("*")
}
}
}
class SqlQueryBuilder extends SqlTableQueryBuilder {
@ -266,18 +276,19 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
const sqlClient = this.getSqlClient()
const client = knex({ client: sqlClient })
let query
const builder = new InternalBuilder(sqlClient)
switch (this._operation(json)) {
case Operation.CREATE:
query = buildCreate(client, json, opts)
query = builder.create(client, json, opts)
break
case Operation.READ:
query = buildRead(client, json, this.limit)
query = builder.read(client, json, this.limit)
break
case Operation.UPDATE:
query = buildUpdate(client, json, opts)
query = builder.update(client, json, opts)
break
case Operation.DELETE:
query = buildDelete(client, json, opts)
query = builder.delete(client, json, opts)
break
case Operation.CREATE_TABLE:
case Operation.UPDATE_TABLE:

View File

@ -245,7 +245,9 @@ module MSSQLModule {
schema,
}
}
this.tables = tables
const final = finaliseExternalTables(tables)
this.tables = final.tables
this.schemaErrors = final.errors
}
async read(query: SqlQuery | string) {