Lazy load ModelRelation query modifiers
This commit is contained in:
parent
52780ebf7c
commit
b245bec0d0
@ -5,7 +5,8 @@ import ModelFactory from "./ModelFactory";
|
|||||||
export default abstract class ModelRelation<S extends Model, O extends Model, R extends O | O[] | null> {
|
export default abstract class ModelRelation<S extends Model, O extends Model, R extends O | O[] | null> {
|
||||||
protected readonly model: S;
|
protected readonly model: S;
|
||||||
protected readonly foreignFactory: ModelFactory<O>;
|
protected readonly foreignFactory: ModelFactory<O>;
|
||||||
protected readonly query: ModelQuery<O>;
|
private readonly query: ModelQuery<O>;
|
||||||
|
protected readonly queryModifiers: QueryModifier<O>[] = [];
|
||||||
protected readonly filters: ModelFilter<O>[] = [];
|
protected readonly filters: ModelFilter<O>[] = [];
|
||||||
protected cachedModels?: R;
|
protected cachedModels?: R;
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ export default abstract class ModelRelation<S extends Model, O extends Model, R
|
|||||||
public abstract clone(): ModelRelation<S, O, R>;
|
public abstract clone(): ModelRelation<S, O, R>;
|
||||||
|
|
||||||
public constraint(queryModifier: QueryModifier<O>): this {
|
public constraint(queryModifier: QueryModifier<O>): this {
|
||||||
queryModifier(this.query);
|
this.queryModifiers.push(queryModifier);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,13 +28,19 @@ export default abstract class ModelRelation<S extends Model, O extends Model, R
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getFinalQuery(): ModelQuery<O> {
|
||||||
|
for (const modifier of this.queryModifiers) modifier(this.query);
|
||||||
|
this.queryModifiers.splice(0, this.queryModifiers.length); // Empty modifier now that they were applied
|
||||||
|
return this.query;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract getModelID(): any;
|
public abstract getModelID(): any;
|
||||||
|
|
||||||
protected abstract async compute(query: ModelQuery<O>): Promise<R>;
|
protected abstract async compute(query: ModelQuery<O>): Promise<R>;
|
||||||
|
|
||||||
public async get(): Promise<R> {
|
public async get(): Promise<R> {
|
||||||
if (this.cachedModels === undefined) {
|
if (this.cachedModels === undefined) {
|
||||||
this.cachedModels = await this.compute(this.query);
|
this.cachedModels = await this.compute(this.getFinalQuery());
|
||||||
}
|
}
|
||||||
return this.cachedModels;
|
return this.cachedModels;
|
||||||
}
|
}
|
||||||
@ -65,7 +72,7 @@ export class OneModelRelation<S extends Model, O extends Model> extends ModelRel
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async compute(query: ModelQuery<O>): Promise<O | null> {
|
protected async compute(query: ModelQuery<O>): Promise<O | null> {
|
||||||
this.query.where(this.dbProperties.foreignKey, this.getModelID());
|
this.getFinalQuery().where(this.dbProperties.foreignKey, this.getModelID());
|
||||||
return await query.first();
|
return await query.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +92,9 @@ export class OneModelRelation<S extends Model, O extends Model> extends ModelRel
|
|||||||
const ids = relations.map(r => r.getModelID()).filter(id => id !== null && id !== undefined);
|
const ids = relations.map(r => r.getModelID()).filter(id => id !== null && id !== undefined);
|
||||||
if (ids.length === 0) return [];
|
if (ids.length === 0) return [];
|
||||||
|
|
||||||
this.query.where(this.dbProperties.foreignKey, ids, WhereTest.IN);
|
const query = this.getFinalQuery();
|
||||||
return await this.query.get();
|
query.where(this.dbProperties.foreignKey, ids, WhereTest.IN);
|
||||||
|
return await query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
||||||
@ -116,7 +124,7 @@ export class ManyModelRelation<S extends Model, O extends Model> extends ModelRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async compute(query: ModelQuery<O>): Promise<O[]> {
|
protected async compute(query: ModelQuery<O>): Promise<O[]> {
|
||||||
this.query.where(this.dbProperties.foreignKey, this.getModelID());
|
this.getFinalQuery().where(this.dbProperties.foreignKey, this.getModelID());
|
||||||
return await query.get();
|
return await query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +146,9 @@ export class ManyModelRelation<S extends Model, O extends Model> extends ModelRe
|
|||||||
const ids = relations.map(r => r.getModelID()).filter(id => id !== null && id !== undefined);
|
const ids = relations.map(r => r.getModelID()).filter(id => id !== null && id !== undefined);
|
||||||
if (ids.length === 0) return [];
|
if (ids.length === 0) return [];
|
||||||
|
|
||||||
this.query.where(this.dbProperties.foreignKey, ids, WhereTest.IN);
|
const query = this.getFinalQuery();
|
||||||
return await this.query.get();
|
query.where(this.dbProperties.foreignKey, ids, WhereTest.IN);
|
||||||
|
return await query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
||||||
@ -154,9 +163,10 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
|
|||||||
constructor(model: S, foreignFactory: ModelFactory<O>, dbProperties: PivotRelationDatabaseProperties) {
|
constructor(model: S, foreignFactory: ModelFactory<O>, dbProperties: PivotRelationDatabaseProperties) {
|
||||||
super(model, foreignFactory);
|
super(model, foreignFactory);
|
||||||
this.dbProperties = dbProperties;
|
this.dbProperties = dbProperties;
|
||||||
this.query
|
this.constraint(query => query
|
||||||
.leftJoin(`${this.dbProperties.pivotTable} as pivot`)
|
.leftJoin(`${this.dbProperties.pivotTable} as pivot`)
|
||||||
.on(`pivot.${this.dbProperties.foreignPivotKey}`, `${this.foreignFactory.table}.${this.dbProperties.foreignKey}`);
|
.on(`pivot.${this.dbProperties.foreignPivotKey}`, `${this.foreignFactory.table}.${this.dbProperties.foreignKey}`)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public clone(): ManyThroughModelRelation<S, O> {
|
public clone(): ManyThroughModelRelation<S, O> {
|
||||||
@ -168,7 +178,7 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async compute(query: ModelQuery<O>): Promise<O[]> {
|
protected async compute(query: ModelQuery<O>): Promise<O[]> {
|
||||||
this.query.where(`pivot.${this.dbProperties.localPivotKey}`, this.getModelID());
|
this.getFinalQuery().where(`pivot.${this.dbProperties.localPivotKey}`, this.getModelID());
|
||||||
return await query.get();
|
return await query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,9 +200,10 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
|
|||||||
const ids = relations.map(r => r.getModelID());
|
const ids = relations.map(r => r.getModelID());
|
||||||
if (ids.length === 0) return [];
|
if (ids.length === 0) return [];
|
||||||
|
|
||||||
this.query.where(`pivot.${this.dbProperties.localPivotKey}`, ids, WhereTest.IN);
|
const query = this.getFinalQuery();
|
||||||
this.query.pivot(`pivot.${this.dbProperties.localPivotKey}`, `pivot.${this.dbProperties.foreignPivotKey}`);
|
query.where(`pivot.${this.dbProperties.localPivotKey}`, ids, WhereTest.IN);
|
||||||
return await this.query.get();
|
query.pivot(`pivot.${this.dbProperties.localPivotKey}`, `pivot.${this.dbProperties.foreignPivotKey}`);
|
||||||
|
return await query.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
public async populate(models: ModelQueryResult<O>): Promise<void> {
|
||||||
|
Loading…
Reference in New Issue
Block a user