Finish fleshing out Model; refactor mixin types; TRUNCATE
This commit is contained in:
@@ -2,8 +2,10 @@ import {escape, EscapedValue, FieldSet, QuerySource} from './types.ts'
|
||||
import { Select } from './type/Select.ts'
|
||||
import RawValue from './RawValue.ts'
|
||||
import {Statement} from './Statement.ts'
|
||||
import {Update} from "./type/Update.ts";
|
||||
import {Insert} from "./type/Insert.ts";
|
||||
import {Update} from './type/Update.ts'
|
||||
import {Insert} from './type/Insert.ts'
|
||||
import {Delete} from './type/Delete.ts'
|
||||
import {Truncate} from "./type/Truncate.ts";
|
||||
|
||||
export function raw(value: string) {
|
||||
return new RawValue(value)
|
||||
@@ -15,29 +17,39 @@ export class IncorrectInterpolationError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export class Builder {
|
||||
// create table, insert, delete, alter table, drop table, select
|
||||
export class Builder<T> {
|
||||
// create table, alter table, drop table, select
|
||||
|
||||
public select(...fields: FieldSet[]) {
|
||||
public select(...fields: FieldSet[]): Select<T> {
|
||||
fields = fields.flat()
|
||||
const select = new Select()
|
||||
const select = new Select<T>()
|
||||
return select.fields(...fields)
|
||||
}
|
||||
|
||||
public update(target?: QuerySource, alias?: string) {
|
||||
const update = new Update()
|
||||
public update(target?: QuerySource, alias?: string): Update<T> {
|
||||
const update = new Update<T>()
|
||||
if ( target ) update.to(target, alias)
|
||||
return update
|
||||
}
|
||||
|
||||
public insert(target?: QuerySource, alias?: string) {
|
||||
const insert = new Insert()
|
||||
public delete(target?: QuerySource, alias?: string): Delete<T> {
|
||||
const del = new Delete<T>()
|
||||
if ( target ) del.from(target, alias)
|
||||
return del
|
||||
}
|
||||
|
||||
public insert(target?: QuerySource, alias?: string): Insert<T> {
|
||||
const insert = new Insert<T>()
|
||||
if ( target ) insert.into(target, alias)
|
||||
return insert
|
||||
}
|
||||
|
||||
public statement(statement: string, ...interpolations: EscapedValue[]) {
|
||||
return new Statement(statement, interpolations)
|
||||
public statement(statement: string, ...interpolations: EscapedValue[]): Statement<T> {
|
||||
return new Statement<T>(statement, interpolations)
|
||||
}
|
||||
|
||||
public truncate(target?: QuerySource, alias?: string): Truncate<T> {
|
||||
return new Truncate<T>(target, alias)
|
||||
}
|
||||
|
||||
public static raw(value: string) {
|
||||
|
||||
5
orm/src/builder/Scope.ts
Normal file
5
orm/src/builder/Scope.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import {WhereBuilder} from './type/WhereBuilder.ts'
|
||||
|
||||
export abstract class Scope {
|
||||
abstract apply(query: WhereBuilder): WhereBuilder
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import {EscapedValue, escape} from './types.ts'
|
||||
import {IncorrectInterpolationError} from './Builder.ts'
|
||||
import ConnectionExecutable from './type/ConnectionExecutable.ts'
|
||||
|
||||
export class Statement extends ConnectionExecutable {
|
||||
export class Statement<T> extends ConnectionExecutable<T> {
|
||||
constructor(
|
||||
public statement: string,
|
||||
public interpolations: EscapedValue[]
|
||||
|
||||
14
orm/src/builder/scope/FunctionScope.ts
Normal file
14
orm/src/builder/scope/FunctionScope.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {Scope} from '../Scope.ts'
|
||||
import {WhereBuilder} from '../type/WhereBuilder.ts'
|
||||
|
||||
export type ScopeFunction = (query: WhereBuilder) => WhereBuilder
|
||||
|
||||
export class FunctionScope extends Scope {
|
||||
constructor(protected _fn: ScopeFunction) {
|
||||
super()
|
||||
}
|
||||
|
||||
apply(query: WhereBuilder): WhereBuilder {
|
||||
return this._fn(query)
|
||||
}
|
||||
}
|
||||
@@ -6,53 +6,59 @@ import {Connection} from '../../db/Connection.ts'
|
||||
import {ResultCollection} from './result/ResultCollection.ts'
|
||||
import {ResultIterable} from './result/ResultIterable.ts'
|
||||
import ResultOperator from './result/ResultOperator.ts'
|
||||
import ObjectResultOperator from './result/ObjectResultOperator.ts'
|
||||
import {Collection} from '../../../../lib/src/collection/Collection.ts'
|
||||
import NoTargetOperatorError from '../../error/NoTargetOperatorError.ts'
|
||||
|
||||
export default abstract class ConnectionExecutable {
|
||||
export default abstract class ConnectionExecutable<T> {
|
||||
abstract sql(level: number): string
|
||||
|
||||
to_count(): string {
|
||||
return `SELECT COUNT(*) AS to_count FROM (${this.sql(0)}) AS target_query`
|
||||
}
|
||||
|
||||
async get_row(i: number) {
|
||||
async get_row(i: number): Promise<T | undefined> {
|
||||
if ( !(this.__target_connection instanceof Connection) ) {
|
||||
throw new Error('Unable to execute database item: no target connection.')
|
||||
}
|
||||
|
||||
if ( !this.__target_operator ) throw new NoTargetOperatorError()
|
||||
|
||||
const query = `SELECT * FROM (${this.sql(0)}) AS target_query OFFSET ${i} LIMIT 1`
|
||||
const result = await this.__target_connection.query(query)
|
||||
const row = result.rows.first()
|
||||
if ( row ) return this.__target_operator.inflate_row(row)
|
||||
}
|
||||
|
||||
async get_range(start: number, end: number) {
|
||||
async get_range(start: number, end: number): Promise<Collection<T>> {
|
||||
if ( !(this.__target_connection instanceof Connection) ) {
|
||||
throw new Error('Unable to execute database item: no target connection.')
|
||||
}
|
||||
|
||||
const query = `SELECT * FROM (${this.sql(0)}) AS target_query OFFSET ${start} LIMIT ${(end - start) + 1}`
|
||||
const result = await this.__target_connection.query(query)
|
||||
return result.rows.map(row => this.__target_operator.inflate_row(row))
|
||||
return result.rows.map(row => {
|
||||
if ( !this.__target_operator ) throw new NoTargetOperatorError()
|
||||
return this.__target_operator.inflate_row(row)
|
||||
})
|
||||
}
|
||||
|
||||
iterator() {
|
||||
return new ResultIterable(this)
|
||||
iterator(): ResultIterable<T> {
|
||||
return new ResultIterable<T>(this)
|
||||
}
|
||||
|
||||
results(chunk_size = 1000) {
|
||||
return new ResultCollection(this.iterator(), chunk_size)
|
||||
return new ResultCollection<T>(this.iterator(), chunk_size)
|
||||
}
|
||||
|
||||
__target_connection?: Connection
|
||||
__target_operator: ResultOperator<any> = new ObjectResultOperator()
|
||||
__target_operator?: ResultOperator<T>
|
||||
|
||||
target_connection(connection: string | Connection) {
|
||||
this.__target_connection = typeof connection === 'string' ? make(Database).connection(connection) : connection
|
||||
return this
|
||||
}
|
||||
|
||||
target_operator(operator: ResultOperator<any>) {
|
||||
target_operator(operator: ResultOperator<T>) {
|
||||
this.__target_operator = operator
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
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 {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'
|
||||
|
||||
export default abstract class ConnectionMutable extends ConnectionExecutable {
|
||||
export default abstract class ConnectionMutable<T> extends ConnectionExecutable<T> {
|
||||
__execution_result?: QueryResult
|
||||
|
||||
async get_row(i: number) {
|
||||
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) {
|
||||
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 => this.__target_operator.inflate_row(row))
|
||||
return rows.map(row => {
|
||||
if ( !this.__target_operator ) throw new NoTargetOperatorError()
|
||||
return this.__target_operator.inflate_row(row)
|
||||
})
|
||||
}
|
||||
|
||||
async count() {
|
||||
|
||||
60
orm/src/builder/type/Delete.ts
Normal file
60
orm/src/builder/type/Delete.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
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'
|
||||
|
||||
export class Delete<T> extends ConnectionMutable<T> {
|
||||
protected _target?: QuerySource = undefined
|
||||
protected _wheres: WhereStatement[] = []
|
||||
protected _scopes: Scope[] = []
|
||||
protected _fields: string[] = []
|
||||
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}`)
|
||||
}
|
||||
|
||||
only() {
|
||||
this._only = true
|
||||
return this
|
||||
}
|
||||
|
||||
from(source: QuerySource, alias?: string) {
|
||||
if ( !alias ) this._target = source
|
||||
else this._target = { ref: source, alias }
|
||||
return this
|
||||
}
|
||||
|
||||
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])
|
||||
@@ -8,7 +8,7 @@ import {raw} from '../Builder.ts'
|
||||
|
||||
// TODO support DEFAULT VALUES
|
||||
// TODO support ON CONFLICT
|
||||
export class Insert extends ConnectionMutable {
|
||||
export class Insert<T> extends ConnectionMutable<T> {
|
||||
protected _target?: QuerySource = undefined
|
||||
protected _columns: string[] = []
|
||||
protected _rows: string[] = []
|
||||
@@ -114,5 +114,5 @@ export class Insert extends ConnectionMutable {
|
||||
}
|
||||
}
|
||||
|
||||
export interface Insert extends TableRefBuilder {}
|
||||
export interface Insert<T> extends TableRefBuilder {}
|
||||
applyMixins(Insert, [TableRefBuilder])
|
||||
|
||||
@@ -19,16 +19,18 @@ import {RightOuterJoin} from './join/RightOuterJoin.ts'
|
||||
import {FullOuterJoin} from './join/FullOuterJoin.ts'
|
||||
import {HavingBuilder} from './HavingBuilder.ts'
|
||||
import ConnectionExecutable from './ConnectionExecutable.ts'
|
||||
import {Scope} from '../Scope.ts'
|
||||
|
||||
export type WhereBuilderFunction = (group: WhereBuilder) => any
|
||||
export type HavingBuilderFunction = (group: HavingBuilder) => any
|
||||
export type JoinFunction = (join: Join) => any
|
||||
export class MalformedSQLGrammarError extends Error {}
|
||||
|
||||
export class Select extends ConnectionExecutable {
|
||||
export class Select<T> extends ConnectionExecutable<T> {
|
||||
protected _fields: string[] = []
|
||||
protected _source?: QuerySource = undefined
|
||||
protected _wheres: WhereStatement[] = []
|
||||
protected _scopes: Scope[] = []
|
||||
protected _havings: HavingStatement[] = []
|
||||
protected _limit?: number
|
||||
protected _offset?: number
|
||||
@@ -200,5 +202,5 @@ export class Select extends ConnectionExecutable {
|
||||
// TODO raw()
|
||||
}
|
||||
|
||||
export interface Select extends WhereBuilder, TableRefBuilder, HavingBuilder {}
|
||||
export interface Select<T> extends WhereBuilder, TableRefBuilder, HavingBuilder {}
|
||||
applyMixins(Select, [WhereBuilder, TableRefBuilder, HavingBuilder])
|
||||
|
||||
72
orm/src/builder/type/Truncate.ts
Normal file
72
orm/src/builder/type/Truncate.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import ConnectionMutable from "./ConnectionMutable.ts";
|
||||
import {MalformedSQLGrammarError} from "./Select.ts";
|
||||
import {TableRefBuilder} from "./TableRefBuilder.ts";
|
||||
import {applyMixins} from "../../../../lib/src/support/mixins.ts";
|
||||
import {QuerySource} from "../types.ts";
|
||||
|
||||
export class Truncate<T> extends ConnectionMutable<T> {
|
||||
protected _source?: QuerySource
|
||||
protected _only: boolean = false
|
||||
protected _restart: boolean = false
|
||||
protected _continue: boolean = false
|
||||
protected _cascade: boolean = false
|
||||
protected _restrict: boolean = false
|
||||
|
||||
constructor(table?: QuerySource, alias?: string) {
|
||||
super()
|
||||
if ( table ) this.table(table, alias)
|
||||
}
|
||||
|
||||
sql(level: number = 0): string {
|
||||
const indent = Array(level).fill(' ').join('')
|
||||
if ( typeof this._source === 'undefined' )
|
||||
throw new MalformedSQLGrammarError(`No table reference has been provided.`)
|
||||
const table_ref = this.source_alias_to_table_ref(this._source)
|
||||
|
||||
let identity = ''
|
||||
if ( this._continue ) identity = 'CONTINUE IDENTITY '
|
||||
else if ( this._restart ) identity = 'RESTART IDENTITY '
|
||||
|
||||
let cascade_redirect = ''
|
||||
if ( this._cascade ) cascade_redirect = 'CASCADE '
|
||||
else if ( this._restrict ) cascade_redirect = 'RESTRICT'
|
||||
|
||||
return [
|
||||
`TRUNCATE TABLE ${this._only ? 'ONLY ' : ''}${this.serialize_table_ref(table_ref)}`,
|
||||
`${identity}${cascade_redirect}`,
|
||||
].filter(x => String(x).trim()).join(`\n${indent}`)
|
||||
}
|
||||
|
||||
table(source: QuerySource, alias?: string) {
|
||||
if ( !alias ) this._source = source
|
||||
else this._source = { ref: source, alias }
|
||||
return this
|
||||
}
|
||||
|
||||
restart_identity() {
|
||||
this._continue = false
|
||||
this._restart = true
|
||||
return this
|
||||
}
|
||||
|
||||
continue_identity() {
|
||||
this._continue = true
|
||||
this._restart = false
|
||||
return this
|
||||
}
|
||||
|
||||
cascade() {
|
||||
this._cascade = true
|
||||
this._restrict = false
|
||||
return this
|
||||
}
|
||||
|
||||
restrict() {
|
||||
this._cascade = false
|
||||
this._restrict = true
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export interface Truncate<T> extends TableRefBuilder {}
|
||||
applyMixins(Truncate, [TableRefBuilder])
|
||||
@@ -6,14 +6,16 @@ import {applyMixins} from '../../../../lib/src/support/mixins.ts'
|
||||
import {TableRefBuilder} from './TableRefBuilder.ts'
|
||||
import {MalformedSQLGrammarError} from './Select.ts'
|
||||
import ConnectionMutable from './ConnectionMutable.ts'
|
||||
import {Scope} from '../Scope.ts'
|
||||
|
||||
// TODO FROM
|
||||
// TODO WHERE CURRENT OF
|
||||
export class Update extends ConnectionMutable {
|
||||
export class Update<T> extends ConnectionMutable<T> {
|
||||
protected _target?: QuerySource = undefined
|
||||
protected _only = false
|
||||
protected _sets: Collection<FieldValue> = new Collection<FieldValue>()
|
||||
protected _wheres: WhereStatement[] = []
|
||||
protected _scopes: Scope[] = []
|
||||
protected _fields: string[] = []
|
||||
|
||||
sql(level = 0): string {
|
||||
@@ -84,5 +86,5 @@ export class Update extends ConnectionMutable {
|
||||
}
|
||||
}
|
||||
|
||||
export interface Update extends WhereBuilder, TableRefBuilder {}
|
||||
export interface Update<T> extends WhereBuilder, TableRefBuilder {}
|
||||
applyMixins(Update, [WhereBuilder, TableRefBuilder])
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
import {EscapedValue, isWhereClause, isWhereGroup, WhereStatement} from '../types.ts'
|
||||
import {escape, SQLWhereOperator, WherePreOperator} from '../types.ts'
|
||||
import {WhereBuilderFunction} from "./Select.ts";
|
||||
import {WhereBuilderFunction} from './Select.ts'
|
||||
import {apply_filter_to_where, QueryFilter} from '../../model/filter.ts'
|
||||
import {Scope} from '../Scope.ts'
|
||||
import {FunctionScope, ScopeFunction} from '../scope/FunctionScope.ts'
|
||||
import {make} from '../../../../di/src/global.ts'
|
||||
|
||||
export class WhereBuilder {
|
||||
protected _wheres: WhereStatement[] = []
|
||||
protected _scopes: Scope[] = []
|
||||
|
||||
get where_items() {
|
||||
return this._wheres
|
||||
}
|
||||
|
||||
without_scope(scope: typeof Scope) {
|
||||
this._scopes = this._scopes.filter(x => !(x instanceof Scope))
|
||||
return this
|
||||
}
|
||||
|
||||
with_scope(scope: Scope | ScopeFunction) {
|
||||
if ( scope instanceof Scope ) {
|
||||
this._scopes.push(scope)
|
||||
} else {
|
||||
this._scopes.push(new FunctionScope(scope))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
with_scopes(scopes: (Scope | ScopeFunction)[]) {
|
||||
scopes.forEach(scope => this.with_scope(scope))
|
||||
return this
|
||||
}
|
||||
|
||||
wheres_to_sql(wheres?: WhereStatement[], level = 0): string {
|
||||
this._scopes.forEach(scope => scope.apply(this))
|
||||
const indent = Array(level * 2).fill(' ').join('')
|
||||
let statements = []
|
||||
for ( const where of wheres || this._wheres ) {
|
||||
@@ -97,4 +122,48 @@ export class WhereBuilder {
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
whereBetween(field: string, lower_bound: EscapedValue, upper_bound: EscapedValue) {
|
||||
this._wheres.push({
|
||||
field,
|
||||
operator: 'BETWEEN',
|
||||
operand: `${escape(lower_bound)} AND ${escape(upper_bound)}`,
|
||||
preop: 'AND',
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
orWhereBetween(field: string, lower_bound: EscapedValue, upper_bound: EscapedValue) {
|
||||
this._wheres.push({
|
||||
field,
|
||||
operator: 'BETWEEN',
|
||||
operand: `${escape(lower_bound)} AND ${escape(upper_bound)}`,
|
||||
preop: 'OR',
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
whereNotBetween(field: string, lower_bound: EscapedValue, upper_bound: EscapedValue) {
|
||||
this._wheres.push({
|
||||
field,
|
||||
operator: 'NOT BETWEEN',
|
||||
operand: `${escape(lower_bound)} AND ${escape(upper_bound)}`,
|
||||
preop: 'AND',
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
orWhereNotBetween(field: string, lower_bound: EscapedValue, upper_bound: EscapedValue) {
|
||||
this._wheres.push({
|
||||
field,
|
||||
operator: 'NOT BETWEEN',
|
||||
operand: `${escape(lower_bound)} AND ${escape(upper_bound)}`,
|
||||
preop: 'OR',
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
filter(filter: QueryFilter) {
|
||||
return apply_filter_to_where(filter, this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ import {JoinOperator, TableRef, WhereStatement} from '../../types.ts'
|
||||
import {TableRefBuilder} from '../TableRefBuilder.ts'
|
||||
import {applyMixins} from '../../../../../lib/src/support/mixins.ts'
|
||||
import {WhereBuilder} from '../WhereBuilder.ts'
|
||||
import {Scope} from '../../Scope.ts'
|
||||
|
||||
export class Join {
|
||||
public readonly operator: JoinOperator = 'JOIN'
|
||||
protected _wheres: WhereStatement[] = []
|
||||
protected _scopes: Scope[] = []
|
||||
|
||||
constructor(
|
||||
public readonly table_ref: TableRef
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import {AsyncCollection} from '../../../../../lib/src/collection/AsyncCollection.ts'
|
||||
import {ResultIterable} from './ResultIterable.ts'
|
||||
import {Collection} from "../../../../../lib/src/collection/Collection.ts";
|
||||
import {Collection} from '../../../../../lib/src/collection/Collection.ts'
|
||||
|
||||
export class ResultCollection extends AsyncCollection<any> {
|
||||
export class ResultCollection<T> extends AsyncCollection<T> {
|
||||
constructor(
|
||||
executable: ResultIterable,
|
||||
executable: ResultIterable<T>,
|
||||
chunk_size: number = 1000
|
||||
) {
|
||||
super(executable, chunk_size)
|
||||
}
|
||||
|
||||
then(func?: (items: Collection<any>) => any) {
|
||||
then(func?: (items: Collection<T>) => any) {
|
||||
if ( func ) {
|
||||
this.collect().then((items: Collection<any>) => func(items))
|
||||
this.collect().then((items: Collection<T>) => func(items))
|
||||
} else {
|
||||
return new Promise(res => [
|
||||
this.collect().then((items: Collection<any>) => res(items))
|
||||
this.collect().then((items: Collection<T>) => res(items))
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import {Iterable} from '../../../../../lib/src/collection/Iterable.ts'
|
||||
import ConnectionExecutable from '../ConnectionExecutable.ts'
|
||||
import {Collection} from '../../../../../lib/src/collection/Collection.ts'
|
||||
import {QueryRow} from '../../../db/types.ts'
|
||||
|
||||
export class ResultIterable extends Iterable<any> {
|
||||
export class ResultIterable<T> extends Iterable<T> {
|
||||
|
||||
constructor(
|
||||
protected executable: ConnectionExecutable
|
||||
protected executable: ConnectionExecutable<T>
|
||||
) { super() }
|
||||
|
||||
async at_index(i: number): Promise<any> {
|
||||
async at_index(i: number): Promise<T | undefined> {
|
||||
return this.executable.get_row(i)
|
||||
}
|
||||
|
||||
async from_range(start: number, end: number): Promise<Collection<any>> {
|
||||
async from_range(start: number, end: number): Promise<Collection<T>> {
|
||||
return this.executable.get_range(start, end)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export type WherePreOperator = 'AND' | 'OR' | 'AND NOT' | 'OR NOT'
|
||||
export type WhereClause = { field: string, operator: SQLWhereOperator, operand: string, preop: WherePreOperator }
|
||||
export type WhereGroup = { items: WhereStatement[], preop: WherePreOperator }
|
||||
export type WhereStatement = WhereClause | WhereGroup
|
||||
export type SQLWhereOperator = WhereOperator | 'IN' | 'NOT IN' | 'LIKE'
|
||||
export type SQLWhereOperator = WhereOperator | 'IN' | 'NOT IN' | 'LIKE' | 'BETWEEN' | 'NOT BETWEEN'
|
||||
export type OrderDirection = 'ASC' | 'DESC'
|
||||
export type OrderStatement = { direction: OrderDirection, field: string }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user