Allow Model classes to override primary key fields

This commit is contained in:
Alice Gaudon 2020-09-06 10:23:32 +02:00
parent f6b326f802
commit f07704c6dc
3 changed files with 24 additions and 15 deletions

View File

@ -1,4 +1,5 @@
import User from "./User";
import Model from "../../db/Model";
import {OneModelRelation} from "../../db/ModelRelation";
import ModelFactory from "../../db/ModelFactory";
import {EMAIL_REGEX} from "../../db/Validator";

View File

@ -5,7 +5,7 @@ import ModelComponent from "./ModelComponent";
import {Type} from "../Utils";
import ModelFactory from "./ModelFactory";
import ModelRelation from "./ModelRelation";
import ModelQuery, {ModelQueryResult, SelectFields, SelectFieldValue} from "./ModelQuery";
import ModelQuery, {ModelQueryResult} from "./ModelQuery";
import {Request} from "express";
export default abstract class Model {
@ -16,27 +16,31 @@ export default abstract class Model {
+ 's';
}
public static create<T extends Model>(this: Type<T>, data: any): T {
public static getPrimaryKeyFields(): string[] {
return ['id'];
}
public static create<T extends Model>(this: ModelType<T>, data: any): T {
return ModelFactory.get(this).create(data);
}
public static select<T extends Model>(this: Type<T>, ...fields: string[]): ModelQuery<T> {
public static select<T extends Model>(this: ModelType<T>, ...fields: string[]): ModelQuery<T> {
return ModelFactory.get(this).select(...fields);
}
public static update<T extends Model>(this: Type<T>, data: { [key: string]: any }): ModelQuery<T> {
public static update<T extends Model>(this: ModelType<T>, data: { [key: string]: any }): ModelQuery<T> {
return ModelFactory.get(this).update(data);
}
public static delete<T extends Model>(this: Type<T>): ModelQuery<T> {
public static delete<T extends Model>(this: ModelType<T>): ModelQuery<T> {
return ModelFactory.get(this).delete();
}
public static async getById<T extends Model>(this: Type<T>, ...id: any): Promise<T | null> {
public static async getById<T extends Model>(this: ModelType<T>, ...id: any): Promise<T | null> {
return ModelFactory.get(this).getById(...id);
}
public static async paginate<T extends Model>(this: Type<T>, request: Request, perPage: number = 20, query?: ModelQuery<T>): Promise<ModelQueryResult<T>> {
public static async paginate<T extends Model>(this: ModelType<T>, request: Request, perPage: number = 20, query?: ModelQuery<T>): Promise<ModelQueryResult<T>> {
return ModelFactory.get(this).paginate(request, perPage, query);
}
@ -222,3 +226,9 @@ export default abstract class Model {
});
}
}
export interface ModelType<T extends Model> extends Type<T> {
table: string;
getPrimaryKeyFields(): string[];
}

View File

@ -1,27 +1,26 @@
import ModelComponent from "./ModelComponent";
import Model from "./Model";
import Model, {ModelType} from "./Model";
import ModelQuery, {ModelQueryResult, SelectFields} from "./ModelQuery";
import {Request} from "express";
import {Type} from "../Utils";
export default class ModelFactory<T extends Model> {
private static readonly factories: { [modelType: string]: ModelFactory<any> } = {};
public static register<M extends Model>(modelType: Type<M>) {
public static register<M extends Model>(modelType: ModelType<M>) {
if (this.factories[modelType.name]) throw new Error(`Factory for type ${modelType.name} already defined.`);
this.factories[modelType.name] = new ModelFactory<M>(modelType);
}
public static get<M extends Model>(modelType: Type<M>): ModelFactory<M> {
public static get<M extends Model>(modelType: ModelType<M>): ModelFactory<M> {
const factory = this.factories[modelType.name];
if (!factory) throw new Error(`No factory registered for ${modelType.name}.`);
return factory;
}
private readonly modelType: Type<T>;
private readonly modelType: ModelType<T>;
private readonly components: ModelComponentFactory<T>[] = [];
protected constructor(modelType: Type<T>) {
protected constructor(modelType: ModelType<T>) {
this.modelType = modelType;
}
@ -39,7 +38,6 @@ export default class ModelFactory<T extends Model> {
}
public get table(): string {
// @ts-ignore
return this.modelType.table;
}
@ -56,7 +54,7 @@ export default class ModelFactory<T extends Model> {
}
public getPrimaryKeyFields(): string[] {
return ['id'];
return this.modelType.getPrimaryKeyFields();
}
public getPrimaryKey(modelData: any): any[] {