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.
91 lines
3.3 KiB
91 lines
3.3 KiB
import ConnectionExecutable from './ConnectionExecutable.ts'
|
|
import {escape, EscapedValue, FieldValue, FieldValueObject, QuerySource, WhereStatement, FieldSet} from '../types.ts'
|
|
import {Collection} from '../../../../lib/src/collection/Collection.ts'
|
|
import {WhereBuilder} from './WhereBuilder.ts'
|
|
import {applyMixins} from '../../../../lib/src/support/mixins.ts'
|
|
import {TableRefBuilder} from './TableRefBuilder.ts'
|
|
import {MalformedSQLGrammarError} from './Select.ts'
|
|
import ConnectionMutable from './ConnectionMutable.ts'
|
|
import {Scope} from '../Scope.ts'
|
|
|
|
// TODO FROM
|
|
// TODO WHERE CURRENT OF
|
|
export class Update<T> extends ConnectionMutable<T> {
|
|
protected _target?: QuerySource = undefined
|
|
protected _only = false
|
|
protected _sets: Collection<FieldValue> = new Collection<FieldValue>()
|
|
protected _wheres: WhereStatement[] = []
|
|
protected _scopes: Scope[] = []
|
|
protected _fields: string[] = []
|
|
|
|
sql(level = 0): string {
|
|
const indent = Array(level * 2).fill(' ').join('')
|
|
if ( typeof this._target === 'undefined' )
|
|
throw new MalformedSQLGrammarError('No table reference has been provided.')
|
|
|
|
const table_ref = this.source_alias_to_table_ref(this._target)
|
|
const wheres = this.wheres_to_sql(this._wheres, level + 1)
|
|
const returning_fields = this._fields.join(', ')
|
|
|
|
return [
|
|
`UPDATE ${this._only ? 'ONLY ' : ''}${this.serialize_table_ref(table_ref)}`,
|
|
`SET`,
|
|
this.serialize_sets(this._sets, level + 1),
|
|
...(wheres.trim() ? ['WHERE', wheres] : []),
|
|
...(returning_fields.trim() ? [`RETURNING ${returning_fields}`] : []),
|
|
].filter(x => String(x).trim()).join(`\n${indent}`)
|
|
}
|
|
|
|
protected serialize_sets(sets: Collection<FieldValue>, level = 0): string {
|
|
const indent = Array(level * 2).fill(' ').join('')
|
|
return indent + sets.map(field_value => `${field_value.field} = ${escape(field_value.value)}`).join(`,\n${indent}`)
|
|
}
|
|
|
|
to(source: QuerySource, alias?: string) {
|
|
if ( !alias ) this._target = source
|
|
else this._target = { ref: source, alias }
|
|
return this
|
|
}
|
|
|
|
only() {
|
|
this._only = true
|
|
return this
|
|
}
|
|
|
|
set(field: string, value: EscapedValue) {
|
|
const existing = this._sets.firstWhere('field', '=', field)
|
|
if ( existing ) {
|
|
existing.value = value
|
|
} else {
|
|
this._sets.push({ field, value })
|
|
}
|
|
return this
|
|
}
|
|
|
|
data(values: FieldValueObject) {
|
|
for ( const field in values ) {
|
|
if ( !values.hasOwnProperty(field) ) continue
|
|
this.set(field, values[field])
|
|
}
|
|
return this
|
|
}
|
|
|
|
returning(...fields: FieldSet[]) {
|
|
for ( const field_set of fields ) {
|
|
if ( typeof field_set === 'string' ) {
|
|
if ( !this._fields.includes(field_set) )
|
|
this._fields.push(field_set)
|
|
} else {
|
|
for ( const field of field_set ) {
|
|
if ( !this._fields.includes(field) )
|
|
this._fields.push(field)
|
|
}
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
}
|
|
|
|
export interface Update<T> extends WhereBuilder, TableRefBuilder {}
|
|
applyMixins(Update, [WhereBuilder, TableRefBuilder])
|