You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.3 KiB
108 lines
3.3 KiB
import {
|
|
EscapedValue,
|
|
HavingPreOperator,
|
|
HavingStatement,
|
|
SQLHavingOperator,
|
|
escape,
|
|
isHavingClause,
|
|
isHavingGroup
|
|
} from '../types.ts'
|
|
import {HavingBuilderFunction} from './Select.ts'
|
|
|
|
export class HavingBuilder {
|
|
protected _havings: HavingStatement[] = []
|
|
|
|
get having_items() {
|
|
return this._havings
|
|
}
|
|
|
|
havings_to_sql(havings?: HavingStatement[], level = 0): string {
|
|
const indent = Array(level * 2).fill(' ').join('')
|
|
let statements = []
|
|
for ( const having of havings || this._havings ) {
|
|
if ( isHavingClause(having) ) {
|
|
statements.push(`${indent}${statements.length < 1 ? '' : having.preop + ' '}${having.field} ${having.operator} ${having.operand}`)
|
|
} else if ( isHavingGroup(having) ) {
|
|
statements.push(`${indent}${statements.length < 1 ? '' : having.preop + ' '}(\n${this.havings_to_sql(having.items, level + 1)}\n${indent})`)
|
|
}
|
|
}
|
|
|
|
return statements.filter(Boolean).join('\n')
|
|
}
|
|
|
|
private _createHaving(preop: HavingPreOperator, field: string | HavingBuilderFunction, operator?: SQLHavingOperator, operand?: any) {
|
|
if ( typeof field === 'function' ) {
|
|
const having_builder = new HavingBuilder()
|
|
field(having_builder)
|
|
this._havings.push({
|
|
preop,
|
|
items: having_builder.having_items,
|
|
})
|
|
} else if ( field && operator && typeof operand !== 'undefined' ) {
|
|
this._havings.push({
|
|
field, operator, operand: escape(operand), preop
|
|
})
|
|
}
|
|
}
|
|
|
|
having(field: string | HavingBuilderFunction, operator?: SQLHavingOperator, operand?: any) {
|
|
this._createHaving('AND', field, operator, operand)
|
|
return this
|
|
}
|
|
|
|
havingIn(field: string, values: EscapedValue) {
|
|
this._havings.push({
|
|
field,
|
|
operator: 'IN',
|
|
operand: escape(values),
|
|
preop: 'AND',
|
|
})
|
|
return this
|
|
}
|
|
|
|
havingNot(field: string | HavingBuilderFunction, operator?: SQLHavingOperator, operand?: EscapedValue) {
|
|
this._createHaving('AND NOT', field, operator, operand)
|
|
return this
|
|
}
|
|
|
|
havingNotIn(field: string, values: EscapedValue) {
|
|
this._havings.push({
|
|
field,
|
|
operator: 'NOT IN',
|
|
operand: escape(values),
|
|
preop: 'AND'
|
|
})
|
|
return this
|
|
}
|
|
|
|
orHaving(field: string | HavingBuilderFunction, operator?: SQLHavingOperator, operand?: EscapedValue) {
|
|
this._createHaving('OR', field, operator, operand)
|
|
return this
|
|
}
|
|
|
|
orHavingNot(field: string | HavingBuilderFunction, operator?: SQLHavingOperator, operand?: EscapedValue) {
|
|
this._createHaving('OR NOT', field, operator, operand)
|
|
return this
|
|
}
|
|
|
|
orHavingIn(field: string, values: EscapedValue) {
|
|
this._havings.push({
|
|
field,
|
|
operator: 'IN',
|
|
operand: escape(values),
|
|
preop: 'OR',
|
|
})
|
|
return this
|
|
}
|
|
|
|
orHavingNotIn(field: string, values: EscapedValue) {
|
|
this._havings.push({
|
|
field,
|
|
operator: 'NOT IN',
|
|
operand: escape(values),
|
|
preop: 'OR',
|
|
})
|
|
return this
|
|
}
|
|
}
|