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.
62 lines
2.2 KiB
62 lines
2.2 KiB
3 years ago
|
import {Model} from "./Model";
|
||
|
import {AbstractResultIterable} from "../builder/result/AbstractResultIterable";
|
||
|
import {Connection} from "../connection/Connection";
|
||
|
import {ModelBuilder} from "./ModelBuilder";
|
||
|
import {Container, Instantiable} from "../../di";
|
||
|
import {QueryRow} from "../types";
|
||
|
import {Collection} from "../../util";
|
||
|
|
||
|
/**
|
||
|
* Implementation of the result iterable that returns query results as instances of the defined model.
|
||
|
*/
|
||
|
export class ModelResultIterable<T extends Model<T>> extends AbstractResultIterable<T> {
|
||
|
constructor(
|
||
|
public readonly builder: ModelBuilder<T>,
|
||
|
public readonly connection: Connection,
|
||
|
/** The model that should be instantiated for each row. */
|
||
|
protected readonly ModelClass: Instantiable<T>
|
||
|
) { super(builder, connection) }
|
||
|
|
||
|
public get selectSQL() {
|
||
|
return this.connection.dialect().renderSelect(this.builder)
|
||
|
}
|
||
|
|
||
|
async at(i: number) {
|
||
|
const query = this.connection.dialect().renderRangedSelect(this.selectSQL, i, i + 1)
|
||
|
const row = (await this.connection.query(query)).rows.first()
|
||
|
|
||
|
if ( row ) {
|
||
|
return this.inflateRow(row)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async range(start: number, end: number): Promise<Collection<T>> {
|
||
|
const query = this.connection.dialect().renderRangedSelect(this.selectSQL, start, end)
|
||
|
return (await this.connection.query(query)).rows.promiseMap<T>(row => this.inflateRow(row))
|
||
|
}
|
||
|
|
||
|
async count() {
|
||
|
const query = this.connection.dialect().renderCount(this.selectSQL)
|
||
|
const result = (await this.connection.query(query)).rows.first()
|
||
|
return result?.extollo_render_count ?? 0
|
||
|
}
|
||
|
|
||
|
async all(): Promise<Collection<T>> {
|
||
|
const result = await this.connection.query(this.selectSQL)
|
||
|
return result.rows.promiseMap<T>(row => this.inflateRow(row))
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Given a query row, create an instance of the configured model class from it.
|
||
|
* @param row
|
||
|
* @protected
|
||
|
*/
|
||
|
protected async inflateRow(row: QueryRow): Promise<T> {
|
||
|
return Container.getContainer().make<T>(this.ModelClass).assumeFromSource(row)
|
||
|
}
|
||
|
|
||
|
clone() {
|
||
|
return new ModelResultIterable(this.builder, this.connection, this.ModelClass)
|
||
|
}
|
||
|
}
|