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.
91 lines
3.0 KiB
91 lines
3.0 KiB
import {Model} from '../Model.ts'
|
|
import AppClass from '../../../../lib/src/lifecycle/AppClass.ts'
|
|
import RelationResultOperator from '../RelationResultOperator.ts'
|
|
import ConnectionExecutable from '../../builder/type/ConnectionExecutable.ts'
|
|
import {AsyncCollection} from '../../../../lib/src/collection/AsyncCollection.ts'
|
|
import {Collection} from '../../../../lib/src/collection/Collection.ts'
|
|
import {WhereBuilder} from '../../builder/type/WhereBuilder.ts'
|
|
import {RelationBuilder} from './RelationBuilder.ts'
|
|
import {Select} from '../../builder/type/Select.ts'
|
|
import {FieldSet} from '../../builder/types.ts'
|
|
import {Update} from '../../builder/type/Update.ts'
|
|
import {Delete} from '../../builder/type/Delete.ts'
|
|
import ModelResultOperator from '../ModelResultOperator.ts'
|
|
import {ModelSelect} from '../query/ModelSelect.ts'
|
|
|
|
export type RelationResult<T> = T | Collection<T> | undefined
|
|
|
|
export abstract class Relation<T extends Model<T>, T2 extends Model<T2>> extends AppClass {
|
|
constructor(
|
|
protected parent: T,
|
|
public readonly related: T2,
|
|
) {
|
|
super()
|
|
}
|
|
|
|
protected abstract get parent_value(): any
|
|
|
|
public get_operator() {
|
|
const related_class = this.related.constructor as typeof Model
|
|
return this.make(ModelResultOperator, related_class)
|
|
}
|
|
|
|
public abstract query(): ConnectionExecutable<T2>
|
|
|
|
public abstract scope_query(where: WhereBuilder): void
|
|
|
|
public abstract build_eager_query(parent_query: ModelSelect<T>, result: Collection<T>): ModelSelect<T2>
|
|
|
|
public abstract match_results(possibly_related: Collection<T>): Collection<T>
|
|
|
|
public abstract set_value(related: Collection<T2>): void
|
|
public abstract get_value(): Collection<T2> | T2 | undefined
|
|
public abstract is_loaded(): boolean
|
|
|
|
public fetch(): AsyncCollection<T2> {
|
|
return this.query().results()
|
|
}
|
|
|
|
public abstract get(): Promise<RelationResult<T2>>
|
|
|
|
public then(callback: (result: RelationResult<T2>) => any) {
|
|
if ( this.is_loaded() ) {
|
|
callback(this.get_value() as RelationResult<T2>)
|
|
} else {
|
|
this.get().then(result => {
|
|
if ( result instanceof Collection ) {
|
|
this.set_value(result as any)
|
|
}
|
|
|
|
callback(result)
|
|
})
|
|
}
|
|
}
|
|
|
|
public get value(): RelationResult<T2> {
|
|
return this.get_value()
|
|
}
|
|
|
|
public get related_query_source() {
|
|
const related_class = this.related.constructor as typeof Model
|
|
return related_class.query_source()
|
|
}
|
|
|
|
public builder(): RelationBuilder<T2> {
|
|
return new RelationBuilder(this)
|
|
}
|
|
|
|
public select(...fields: FieldSet[]): Select<T2> {
|
|
if ( fields.length < 1 ) fields.push(this.related.qualify_column('*'))
|
|
return this.builder().select(...fields)
|
|
}
|
|
|
|
public update(): Update<T2> {
|
|
return this.builder().update()
|
|
}
|
|
|
|
public delete(): Delete<T2> {
|
|
return this.builder().delete()
|
|
}
|
|
}
|