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 extends ConnectionMutable { /** * The target table. * @type QuerySource */ protected _target?: QuerySource = undefined /** * The where clauses. * @type Array */ protected _wheres: WhereStatement[] = [] /** * The applied scopes. * @type Array */ protected _scopes: Scope[] = [] /** * The fields to select. * @type Array */ 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 extends WhereBuilder, TableRefBuilder {} applyMixins(Delete, [WhereBuilder, TableRefBuilder])