Skip to content

Commit

Permalink
Support soft delete
Browse files Browse the repository at this point in the history
  • Loading branch information
nhat-phan committed Jan 13, 2018
1 parent 35aeebe commit ce34041
Show file tree
Hide file tree
Showing 26 changed files with 1,145 additions and 141 deletions.
17 changes: 17 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"recommendations": [
"eg2.tslint",
"k--kato.intellij-idea-keybindings",
"steoates.autoimport",
"esbenp.prettier-vscode",
"streetsidesoftware.code-spell-checker",
"msjsdiag.debugger-for-chrome",
"PeterJausovec.vscode-docker",
"alefragnani.bookmarks",
"donjayamanne.githistory",
"xabikos.javascriptsnippets",
"Shan.code-settings-sync",
"robertohuertasm.vscode-icons",
"wayou.vscode-todo-highlight"
]
}
31 changes: 31 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"editor.tabSize": 2,
"editor.codeLens": false,
"editor.formatOnSave": true,
"editor.rulers": [
120
],
"editor.tabCompletion": true,
"typescript.referencesCodeLens.enabled": true,
"tslint.ignoreDefinitionFiles": false,
"tslint.autoFixOnSave": true,
"tslint.exclude": "**/node_modules/**/*",
"emmet.showExpandedAbbreviation": "never",
"prettier.semi": false,
"prettier.singleQuote": true,
"prettier.tabWidth": 2,
"prettier.printWidth": 120,
"prettier.ignorePath": ".prettierignore",
"terminal.integrated.fontFamily": "Meslo LG M for Powerline",
"terminal.integrated.fontSize": 12,
"cSpell.words": [
"najs",
"autoload",
"overridable",
"Mailjet",
"Queueable",
"deserialize",
"timestamps",
"mutators"
]
}
25 changes: 25 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"label": "Build",
"type": "npm",
"group": "build",
"command": "build"
},
{
"label": "Test",
"type": "shell",
"group": "test",
"command": "npm run build && npm test"
},
{
"label": "Coverage",
"type": "shell",
"command": "npm run coverage"
}
]
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ User.where('first_name', 'tony')
.where('last_name', 'stark')
.get() // -> { first_name: 'tony', last_name: 'stark' }

// Using .where() with operator 'not-in'
// Using .where() with operator 'not'
await User.where('first_name', 'tony')
.where('last_name', '!=', 'stark')
.get() // -> { first_name: 'tony', last_name: { $not: 'stark' } }
.get() // -> { first_name: 'tony', last_name: { $ne: 'stark' } }
```

#### OR conditions
Expand Down
14 changes: 11 additions & 3 deletions dist/lib/eloquent/EloquentMongoose.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EloquentBase } from './EloquentBase';
import { EloquentBase, EloquentSoftDelete } from './EloquentBase';
import { OrderDirection, SubCondition } from '../interfaces/IBasicQueryGrammar';
import { MongooseQueryBuilder } from '../query-builders/MongooseQueryBuilder';
import { Document, Schema, Model, Mongoose } from 'mongoose';
Expand All @@ -12,7 +12,7 @@ export declare abstract class EloquentMongoose<T> extends EloquentBase<Document
setId(value: any): any;
static Class(): any;
getModelName(): string;
protected initializeModelIfNeeded(): void;
protected initializeModelIfNeeded(softDeletes: boolean | EloquentSoftDelete): void;
protected initialize(data: Document & T | Object | undefined): EloquentMongoose<T>;
protected getMongoose(): Mongoose;
protected isNativeRecord(data: Document & T | Object | undefined): boolean;
Expand All @@ -22,7 +22,7 @@ export declare abstract class EloquentMongoose<T> extends EloquentBase<Document
protected getReservedPropertiesList(): string[];
getAttribute(name: string): any;
setAttribute(name: string, value: any): boolean;
newQuery(): any;
newQuery(softDeletes?: boolean | EloquentSoftDelete): any;
newInstance(document?: Document & T | Object): EloquentMongoose<T>;
newCollection(dataset: Array<Document & T>): Collection<EloquentMongoose<T>>;
toObject(): Object;
Expand Down Expand Up @@ -55,6 +55,12 @@ export declare abstract class EloquentMongoose<T> extends EloquentBase<Document
static whereNotIn(field: string, values: Array<any>): MongooseQueryBuilder;
static orWhereIn(field: string, values: Array<any>): MongooseQueryBuilder;
static orWhereNotIn(field: string, values: Array<any>): MongooseQueryBuilder;
static whereNull(field: string): any;
static whereNotNull(field: string): any;
static orWhereNull(field: string): any;
static orWhereNotNull(field: string): any;
static withTrash(): any;
static onlyTrash(): any;
static all(): Promise<any>;
static get(): Promise<any>;
static get(field: string): Promise<any>;
Expand All @@ -63,6 +69,8 @@ export declare abstract class EloquentMongoose<T> extends EloquentBase<Document
static find(id: any): Promise<any>;
static pluck(value: string): Promise<Object>;
static pluck(value: string, key: string): Promise<Object>;
static count(): Promise<number>;
static native(handler: (native: any) => any): Promise<any>;
static findById(id: any): Promise<any>;
static findOrFail(id: any): Promise<any>;
}
82 changes: 59 additions & 23 deletions dist/lib/eloquent/EloquentMongoose.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ const mongoose_1 = require("mongoose");
const collect_js_1 = require("collect.js");
const najs_1 = require("najs");
const NotFoundError_1 = require("../errors/NotFoundError");
const SoftDelete_1 = require("./mongoose/SoftDelete");
mongoose_1.Schema.prototype['setupTimestamp'] = require('./mongoose/setupTimestamp').setupTimestamp;
const DEFAULT_TIMESTAMPS = {
createdAt: 'created_at',
updatedAt: 'updated_at'
};
const DEFAULT_SOFT_DELETES = {
deletedAt: 'deleted_at',
overrideMethods: false
};
class EloquentMongoose extends EloquentBase_1.EloquentBase {
getId() {
return this.attributes._id;
Expand All @@ -33,7 +38,7 @@ class EloquentMongoose extends EloquentBase_1.EloquentBase {
return this.getClassName();
}
// -------------------------------------------------------------------------------------------------------------------
initializeModelIfNeeded() {
initializeModelIfNeeded(softDeletes) {
const modelName = this.getModelName();
const mongoose = this.getMongoose();
if (mongoose.modelNames().indexOf(modelName) === -1) {
Expand All @@ -42,11 +47,14 @@ class EloquentMongoose extends EloquentBase_1.EloquentBase {
if (timestampsSettings) {
schema.set('timestamps', timestampsSettings === true ? DEFAULT_TIMESTAMPS : timestampsSettings);
}
if (softDeletes) {
schema.plugin(SoftDelete_1.SoftDelete, softDeletes === true ? DEFAULT_SOFT_DELETES : softDeletes);
}
mongoose_1.model(modelName, schema);
}
}
initialize(data) {
this.initializeModelIfNeeded();
this.initializeModelIfNeeded(Object.getPrototypeOf(this).constructor.softDeletes);
this.model = this.getMongoose().model(this.getModelName());
this.schema = this.model.schema;
return super.initialize(data);
Expand Down Expand Up @@ -79,9 +87,10 @@ class EloquentMongoose extends EloquentBase_1.EloquentBase {
this.attributes[name] = value;
return true;
}
newQuery() {
this.initializeModelIfNeeded();
return new MongooseQueryBuilder_1.MongooseQueryBuilder(this.getModelName());
newQuery(softDeletes) {
const softDeleteSettings = softDeletes || Object.getPrototypeOf(this).constructor.softDeletes;
this.initializeModelIfNeeded(softDeleteSettings);
return new MongooseQueryBuilder_1.MongooseQueryBuilder(this.getModelName(), softDeleteSettings === true ? DEFAULT_SOFT_DELETES : softDeleteSettings);
}
newInstance(document) {
const instance = najs_1.make(this.getClassName());
Expand Down Expand Up @@ -118,6 +127,9 @@ class EloquentMongoose extends EloquentBase_1.EloquentBase {
}
delete() {
return __awaiter(this, void 0, void 0, function* () {
if (Object.getPrototypeOf(this).constructor.softDeletes) {
return this.attributes['delete']();
}
return this.attributes.remove();
});
}
Expand All @@ -138,62 +150,86 @@ class EloquentMongoose extends EloquentBase_1.EloquentBase {
}
// -------------------------------------------------------------------------------------------------------------------
static queryName(name) {
return this.prototype.newQuery().queryName(name);
return this.prototype.newQuery(this.softDeletes).queryName(name);
}
static select(...fields) {
return this.prototype.newQuery().select(...fields);
return this.prototype.newQuery(this.softDeletes).select(...fields);
}
static distinct(...fields) {
return this.prototype.newQuery().distinct(...fields);
return this.prototype.newQuery(this.softDeletes).distinct(...fields);
}
static orderBy(field, direction = 'asc') {
return this.prototype.newQuery().orderBy(field, direction);
return this.prototype.newQuery(this.softDeletes).orderBy(field, direction);
}
static orderByAsc(field) {
return this.prototype.newQuery().orderByAsc(field);
return this.prototype.newQuery(this.softDeletes).orderByAsc(field);
}
static orderByDesc(field) {
return this.prototype.newQuery().orderByDesc(field);
return this.prototype.newQuery(this.softDeletes).orderByDesc(field);
}
static limit(records) {
return this.prototype.newQuery().limit(records);
return this.prototype.newQuery(this.softDeletes).limit(records);
}
static where(arg0, arg1, arg2) {
return this.prototype.newQuery().where(arg0, arg1, arg2);
return this.prototype.newQuery(this.softDeletes).where(arg0, arg1, arg2);
}
static orWhere(arg0, arg1, arg2) {
return this.prototype.newQuery().orWhere(arg0, arg1, arg2);
return this.prototype.newQuery(this.softDeletes).orWhere(arg0, arg1, arg2);
}
static whereIn(field, values) {
return this.prototype.newQuery().whereIn(field, values);
return this.prototype.newQuery(this.softDeletes).whereIn(field, values);
}
static whereNotIn(field, values) {
return this.prototype.newQuery().whereNotIn(field, values);
return this.prototype.newQuery(this.softDeletes).whereNotIn(field, values);
}
static orWhereIn(field, values) {
return this.prototype.newQuery().orWhereIn(field, values);
return this.prototype.newQuery(this.softDeletes).orWhereIn(field, values);
}
static orWhereNotIn(field, values) {
return this.prototype.newQuery().orWhereNotIn(field, values);
return this.prototype.newQuery(this.softDeletes).orWhereNotIn(field, values);
}
static whereNull(field) {
return this.prototype.newQuery(this.softDeletes).whereNull(field);
}
static whereNotNull(field) {
return this.prototype.newQuery(this.softDeletes).whereNotNull(field);
}
static orWhereNull(field) {
return this.prototype.newQuery(this.softDeletes).orWhereNull(field);
}
static orWhereNotNull(field) {
return this.prototype.newQuery(this.softDeletes).orWhereNotNull(field);
}
static withTrash() {
return this.prototype.newQuery(this.softDeletes).withTrash();
}
static onlyTrash() {
return this.prototype.newQuery(this.softDeletes).onlyTrash();
}
static all() {
return this.prototype.newQuery().all();
return this.prototype.newQuery(this.softDeletes).all();
}
static get(...fields) {
return this.prototype
.newQuery()
.newQuery(this.softDeletes)
.select(...fields)
.get();
}
static find(id) {
if (typeof id !== 'undefined') {
const query = this.prototype.newQuery();
const query = this.prototype.newQuery(this.softDeletes);
return query.where(query.getPrimaryKey(), id).find();
}
return this.prototype.newQuery().find();
return this.prototype.newQuery(this.softDeletes).find();
}
static pluck(value, key) {
return this.prototype.newQuery().pluck(value, key);
return this.prototype.newQuery(this.softDeletes).pluck(value, key);
}
static count() {
return this.prototype.newQuery(this.softDeletes).count();
}
static native(handler) {
return this.prototype.newQuery(this.softDeletes).native(handler);
}
static findById(id) {
return this.find(id);
Expand Down
2 changes: 1 addition & 1 deletion dist/lib/query-builders/MongodbConditionConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class MongodbConditionConverter {
return lodash_1.set({}, condition.field, condition.value);
case '!=':
case '<>':
return lodash_1.set({}, condition.field, { $not: condition.value });
return lodash_1.set({}, condition.field, { $ne: condition.value });
case '<':
return lodash_1.set({}, condition.field, { $lt: condition.value });
case '<=':
Expand Down
6 changes: 4 additions & 2 deletions dist/lib/query-builders/MongooseQueryBuilder.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MongooseQuery } from './MongooseQueryBuilder';
import { QueryBuilder } from './QueryBuilder';
import { QueryBuilder, QueryBuilderSoftDelete } from './QueryBuilder';
import { IBasicQueryGrammar } from '../interfaces/IBasicQueryGrammar';
import { IQueryFetchResult } from '../interfaces/IQueryFetchResult';
import { Collection } from 'collect.js';
Expand All @@ -10,7 +10,9 @@ export declare class MongooseQueryBuilder<T = {}> extends QueryBuilder implement
protected mongooseQuery: MongooseQuery<T>;
protected hasMongooseQuery: boolean;
protected primaryKey: string;
constructor(modelName: string, primaryKey?: string);
constructor(modelName: string);
constructor(modelName: string, softDelete: QueryBuilderSoftDelete);
constructor(modelName: string, softDelete: QueryBuilderSoftDelete | undefined, primaryKey: string);
protected getMongoose(): Mongoose;
protected getQuery(isFindOne?: boolean): MongooseQuery<T>;
protected passDataToMongooseQuery(query: MongooseQuery<T>): MongooseQuery<T>;
Expand Down
4 changes: 2 additions & 2 deletions dist/lib/query-builders/MongooseQueryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const najs_1 = require("najs");
const lodash_1 = require("lodash");
const collect_js_1 = require("collect.js");
class MongooseQueryBuilder extends QueryBuilder_1.QueryBuilder {
constructor(modelName, primaryKey = '_id') {
super();
constructor(modelName, softDelete, primaryKey = '_id') {
super(softDelete);
this.primaryKey = primaryKey;
const mongoose = this.getMongoose();
if (mongoose.modelNames().indexOf(modelName) === -1) {
Expand Down
14 changes: 13 additions & 1 deletion dist/lib/query-builders/QueryBuilder.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { QueryCondition } from './QueryConditionBuilder';
import { OrderDirection, SubCondition, Operator } from '../interfaces/IBasicQueryGrammar';
export declare type QueryBuilderSoftDelete = {
deletedAt: string;
};
export declare class QueryBuilder {
protected name: string;
protected selectedFields: string[];
Expand All @@ -8,8 +11,11 @@ export declare class QueryBuilder {
protected limitNumber: number;
protected conditions: QueryCondition[];
protected isUsed: boolean;
constructor();
protected softDelete?: QueryBuilderSoftDelete;
protected addSoftDeleteCondition: boolean;
constructor(softDelete?: QueryBuilderSoftDelete);
protected getFieldByName(name: any): any;
protected getNullValue(name: any): null;
protected _flatten_and_assign_to(name: string, fields: Array<string | string[]>): this;
protected getConditions(): Object[];
queryName(name: string): this;
Expand All @@ -34,4 +40,10 @@ export declare class QueryBuilder {
whereNotIn(field: string, values: Array<any>): this;
orWhereIn(field: string, values: Array<any>): this;
orWhereNotIn(field: string, values: Array<any>): this;
whereNull(field: string): this;
whereNotNull(field: string): this;
orWhereNull(field: string): this;
orWhereNotNull(field: string): this;
withTrash(): this;
onlyTrash(): this;
}
Loading

0 comments on commit ce34041

Please sign in to comment.