import {Model} from '../Model.ts' import {Relation} from './Relation.ts' import ConnectionExecutable from '../../builder/type/ConnectionExecutable.ts' import {WhereBuilder} from '../../builder/type/WhereBuilder.ts' import {ModelSelect} from '../query/ModelSelect.ts' import {Collection} from '../../../../lib/src/collection/Collection.ts' export abstract class HasOneOrMany, T2 extends Model> extends Relation { constructor( protected parent: T, public readonly related: T2, protected foreign_key_spec?: string, protected local_key_spec?: string, ) { super(parent, related) } public get foreign_key() { return this.foreign_key_spec || this.parent.key_name() } public get local_key() { return this.local_key_spec || this.foreign_key } public get qualified_foreign_key() { return this.related.qualify_column(this.foreign_key) } public get qualified_local_key() { return this.related.qualify_column(this.local_key) } protected get parent_value() { // @ts-ignore return this.parent[this.local_key] } public query(): ConnectionExecutable { return this.builder().select('*') } public scope_query(where: WhereBuilder) { where.where(where => { where.where(this.qualified_foreign_key, '=', this.parent_value) .whereRaw(this.qualified_foreign_key, 'IS NOT', 'NULL') }) } public build_eager_query(parent_query: ModelSelect, result: Collection): ModelSelect { const keys = result.pluck(this.local_key).toArray() return this.related.select().whereIn(this.foreign_key, keys) } public match_results(possibly_related: Collection) { return possibly_related.where(this.foreign_key, '=', this.parent_value) } }