|
|
|
import {EscapedValue, escape} from './types.ts'
|
|
|
|
import {IncorrectInterpolationError} from './Builder.ts'
|
|
|
|
import ConnectionExecutable from './type/ConnectionExecutable.ts'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query builder base class for a raw SQL statement.
|
|
|
|
* @extends ConnectionExecutable
|
|
|
|
*/
|
|
|
|
export class Statement<T> extends ConnectionExecutable<T> {
|
|
|
|
constructor(
|
|
|
|
/**
|
|
|
|
* The statement to be executed.
|
|
|
|
* @type string
|
|
|
|
*/
|
|
|
|
public statement: string,
|
|
|
|
/**
|
|
|
|
* The variables to be interpolated into the statement.
|
|
|
|
* @type Array<EscapedValue>
|
|
|
|
*/
|
|
|
|
public interpolations: EscapedValue[]
|
|
|
|
) {
|
|
|
|
super()
|
|
|
|
}
|
|
|
|
|
|
|
|
sql(): string {
|
|
|
|
const statement = this.statement
|
|
|
|
const interpolations = [...this.interpolations].reverse()
|
|
|
|
const expected_interpolations = (statement.match(/\?/g) || []).length
|
|
|
|
if ( expected_interpolations !== interpolations.length ) {
|
|
|
|
throw new IncorrectInterpolationError(expected_interpolations, interpolations.length)
|
|
|
|
}
|
|
|
|
|
|
|
|
const query_chars = []
|
|
|
|
for ( const char of statement.split('') ) {
|
|
|
|
if ( char === '?' ) {
|
|
|
|
const val = interpolations.pop()
|
|
|
|
if ( typeof val !== 'undefined' )
|
|
|
|
query_chars.push(escape(val))
|
|
|
|
else
|
|
|
|
throw new TypeError('Got an undefined interpolation value. Unable to continue.')
|
|
|
|
} else {
|
|
|
|
query_chars.push(char)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return query_chars.join('')
|
|
|
|
}
|
|
|
|
}
|