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.

58 lines
2.1 KiB

import ConnectionExecutable from './ConnectionExecutable.ts'
import {QueryResult, QueryRow} from '../../db/types.ts'
import {Connection} from '../../db/Connection.ts'
import {Collection} from '../../../../lib/src/collection/Collection.ts'
import NoTargetOperatorError from '../../error/NoTargetOperatorError.ts'
/**
* Variant of the ConnectionExecutable used to build queries that mutate data. This
* structure overrides methods to ensure that the query is run only once.
* @extends ConnectionExecutable
* @abstract
*/
export default abstract class ConnectionMutable<T> extends ConnectionExecutable<T> {
/**
* The cached execution result.
* @type QueryResult
*/
__execution_result?: QueryResult
async get_row(i: number): Promise<T | undefined> {
const result = await this.get_execution_result()
const row = result.rows.at(i)
if ( !this.__target_operator ) throw new NoTargetOperatorError()
if ( row ) return this.__target_operator.inflate_row(row)
}
async get_range(start: number, end: number): Promise<Collection<T>> {
const result = await this.get_execution_result()
const rows: Collection<QueryRow> = result.rows.slice(start, end + 1) as Collection<QueryRow>
return rows.map(row => {
if ( !this.__target_operator ) throw new NoTargetOperatorError()
return this.__target_operator.inflate_row(row)
})
}
async count() {
const result = await this.get_execution_result()
return result.row_count
}
/**
* Get the query result. Executes the query if it hasn't already. If it has,
* return the cached query result.
* @return Promise<QueryResult>
*/
async get_execution_result(): Promise<QueryResult> {
if ( this.__execution_result ) return this.__execution_result
else return this.execute()
}
async execute_in_connection(connection: string | Connection): Promise<QueryResult> {
const result = await super.execute_in_connection(connection)
this.__execution_result = result
return result
}
}