Updating select statement generation.

This commit is contained in:
mike12345567 2024-09-05 19:04:45 +01:00
parent 888c4214bd
commit f7d9b8a9b3
1 changed files with 72 additions and 70 deletions

View File

@ -94,6 +94,23 @@ class InternalBuilder {
}) })
} }
// states the various situations in which we need a full mapped select statement
private readonly SPECIAL_SELECT_CASES = {
POSTGRES_MONEY: (field: FieldSchema | undefined) => {
return (
this.client === SqlClient.POSTGRES &&
field?.externalType?.includes("money")
)
},
MSSQL_DATES: (field: FieldSchema | undefined) => {
return (
this.client === SqlClient.MS_SQL &&
field?.type === FieldType.DATETIME &&
field.timeOnly
)
},
}
get table(): Table { get table(): Table {
return this.query.meta.table return this.query.meta.table
} }
@ -127,8 +144,20 @@ class InternalBuilder {
.join(".") .join(".")
} }
private isFullSelectStatementRequired(): boolean {
const { meta } = this.query
for (let column of Object.values(meta.table.schema)) {
if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(column)) {
return true
} else if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(column)) {
return true
}
}
return false
}
private generateSelectStatement(): (string | Knex.Raw)[] | "*" { private generateSelectStatement(): (string | Knex.Raw)[] | "*" {
const { endpoint, resource, tableAliases } = this.query const { meta, endpoint, resource, tableAliases } = this.query
if (!resource || !resource.fields || resource.fields.length === 0) { if (!resource || !resource.fields || resource.fields.length === 0) {
return "*" return "*"
@ -137,75 +166,48 @@ class InternalBuilder {
const alias = tableAliases?.[endpoint.entityId] const alias = tableAliases?.[endpoint.entityId]
? tableAliases?.[endpoint.entityId] ? tableAliases?.[endpoint.entityId]
: endpoint.entityId : endpoint.entityId
return [this.knex.raw(`${this.quote(alias)}.*`)] const schema = meta.table.schema
// if (!this.isFullSelectStatementRequired()) {
// return [this.knex.raw(`${this.quote(alias)}.*`)]
// const schema = meta.table.schema }
// return resource.fields.map(field => { // get just the fields for this table
// const parts = field.split(/\./g) return resource.fields
// let table: string | undefined = undefined .map(field => {
// let column: string | undefined = undefined const parts = field.split(/\./g)
// let table: string | undefined = undefined
// // Just a column name, e.g.: "column" let column = parts[0]
// if (parts.length === 1) {
// column = parts[0] // Just a column name, e.g.: "column"
// } if (parts.length > 1) {
// table = parts[0]
// // A table name and a column name, e.g.: "table.column" column = parts.slice(1).join(".")
// if (parts.length === 2) { }
// table = parts[0]
// column = parts[1] return { table, column, field }
// } })
// .filter(({ table }) => !table || table === alias)
// // A link doc, e.g.: "table.doc1.fieldName" .map(({ table, column, field }) => {
// if (parts.length > 2) { const columnSchema = schema[column]
// table = parts[0]
// column = parts.slice(1).join(".") if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(columnSchema)) {
// } return this.knex.raw(
// `${this.quotedIdentifier(
// if (!column) { [table, column].join(".")
// throw new Error(`Invalid field name: ${field}`) )}::money::numeric as ${this.quote(field)}`
// } )
// }
// const columnSchema = schema[column]
// if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(columnSchema)) {
// if ( // Time gets returned as timestamp from mssql, not matching the expected
// this.client === SqlClient.POSTGRES && // HH:mm format
// columnSchema?.externalType?.includes("money") return this.knex.raw(`CONVERT(varchar, ${field}, 108) as "${field}"`)
// ) { }
// return this.knex.raw(
// `${this.quotedIdentifier( const quoted = table
// [table, column].join(".") ? `${this.quote(table)}.${this.quote(column)}`
// )}::money::numeric as ${this.quote(field)}` : this.quote(field)
// ) return this.knex.raw(quoted)
// } })
//
// if (
// this.client === SqlClient.MS_SQL &&
// columnSchema?.type === FieldType.DATETIME &&
// columnSchema.timeOnly
// ) {
// // Time gets returned as timestamp from mssql, not matching the expected
// // HH:mm format
// return this.knex.raw(`CONVERT(varchar, ${field}, 108) as "${field}"`)
// }
//
// // There's at least two edge cases being handled in the expression below.
// // 1. The column name could start/end with a space, and in that case we
// // want to preseve that space.
// // 2. Almost all column names are specified in the form table.column, except
// // in the case of relationships, where it's table.doc1.column. In that
// // case, we want to split it into `table`.`doc1.column` for reasons that
// // aren't actually clear to me, but `table`.`doc1` breaks things with the
// // sample data tests.
// if (table) {
// return this.knex.raw(
// `${this.quote(table)}.${this.quote(column)} as ${this.quote(field)}`
// )
// } else {
// return this.knex.raw(`${this.quote(field)} as ${this.quote(field)}`)
// }
// })
} }
// OracleDB can't use character-large-objects (CLOBs) in WHERE clauses, // OracleDB can't use character-large-objects (CLOBs) in WHERE clauses,