feat: soft delete database entities

This commit is contained in:
Ali BARIN
2022-09-28 21:39:21 +02:00
parent 038b38879f
commit 8be352765e
2 changed files with 51 additions and 2 deletions

View File

@@ -2,9 +2,15 @@ import { AjvValidator, Model, snakeCaseMappers } from 'objection';
import type { QueryContext, ModelOptions, ColumnNameMappers } from 'objection';
import addFormats from 'ajv-formats';
import ExtendedQueryBuilder from './query-builder';
class Base extends Model {
createdAt!: string;
updatedAt!: string;
deletedAt: string;
QueryBuilderType!: ExtendedQueryBuilder<this>;
static QueryBuilder = ExtendedQueryBuilder;
static get columnNameMappers(): ColumnNameMappers {
return snakeCaseMappers();
@@ -30,10 +36,10 @@ class Base extends Model {
this.updatedAt = new Date().toISOString();
}
async $beforeUpdate(opt: ModelOptions, queryContext: QueryContext): Promise<void> {
async $beforeUpdate(opts: ModelOptions, queryContext: QueryContext): Promise<void> {
this.updatedAt = new Date().toISOString();
await super.$beforeUpdate(opt, queryContext);
await super.$beforeUpdate(opts, queryContext);
}
}

View File

@@ -0,0 +1,43 @@
import { Model, Page, PartialModelObject, ForClassMethod, AnyQueryBuilder } from "objection";
const DELETED_COLUMN_NAME = 'deleted_at';
const buildQueryBuidlerForClass = (): ForClassMethod => {
return (modelClass) => {
const qb: AnyQueryBuilder = Model.QueryBuilder.forClass.call(ExtendedQueryBuilder, modelClass);
qb.onBuild((builder) => {
if (!builder.context().withSoftDeleted) {
builder.whereNull(`${qb.modelClass().tableName}.${DELETED_COLUMN_NAME}`);
}
});
return qb;
};
};
class ExtendedQueryBuilder<M extends Model, R = M[]> extends Model.QueryBuilder<M, R> {
ArrayQueryBuilderType!: ExtendedQueryBuilder<M, M[]>;
SingleQueryBuilderType!: ExtendedQueryBuilder<M, M>;
MaybeSingleQueryBuilderType!: ExtendedQueryBuilder<M, M | undefined>;
NumberQueryBuilderType!: ExtendedQueryBuilder<M, number>;
PageQueryBuilderType!: ExtendedQueryBuilder<M, Page<M>>;
static forClass: ForClassMethod = buildQueryBuidlerForClass();
delete() {
return this.patch({
[DELETED_COLUMN_NAME]: (new Date()).toISOString(),
} as unknown as PartialModelObject<M>);
}
hardDelete() {
return super.delete();
}
restore() {
return this.patch({
[DELETED_COLUMN_NAME]: null,
} as unknown as PartialModelObject<M>);
}
}
export default ExtendedQueryBuilder;