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.0 KiB

import ConnectionMutable from './ConnectionMutable.ts'
import {WhereBuilder} from './WhereBuilder.ts'
import {applyMixins} from '../../../../lib/src/support/mixins.ts'
import {QuerySource, WhereStatement, FieldSet} from '../types.ts'
import {TableRefBuilder} from './TableRefBuilder.ts'
import {MalformedSQLGrammarError} from './Select.ts'
import {Scope} from '../Scope.ts'
/**
* Base query builder for DELETE queries.
* @extends ConnectionMutable
* @extends WhereBuilder
* @extends TableRefBuilder
*/
export class Delete<T> extends ConnectionMutable<T> {
/**
* The target table.
* @type QuerySource
*/
protected _target?: QuerySource = undefined
/**
* The where clauses.
* @type Array<WhereStatement>
*/
protected _wheres: WhereStatement[] = []
/**
* The applied scopes.
* @type Array<Scope>
*/
protected _scopes: Scope[] = []
/**
* The fields to select.
* @type Array<string>
*/
protected _fields: string[] = []
/**
* Include the ONLY operator?
* @type boolean
*/
protected _only: boolean = false
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 [
`DELETE FROM ${this._only ? 'ONLY ' : ''}${this.serialize_table_ref(table_ref)}`,
...(wheres.trim() ? ['WHERE', wheres] : []),
...(returning_fields.trim() ? [`RETURNING ${returning_fields}`] : []),
].filter(x => String(x).trim()).join(`\n${indent}`)
}
/**
* Include the only operator.
* @example
* SELECT ONLY ...
* @return Delete
*/
only() {
this._only = true
return this
}
/**
* Set the source to delete from.
* @param {QuerySource} source
* @param {string} alias
* @return Delete
*/
from(source: QuerySource, alias?: string) {
if ( !alias ) this._target = source
else this._target = { ref: source, alias }
return this
}
/**
* Set the fields to be returned from the query.
* @param {...FieldSet} fields
* @return Delete
*/
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 Delete<T> extends WhereBuilder, TableRefBuilder {}
applyMixins(Delete, [WhereBuilder, TableRefBuilder])