Skip to content

Commit

Permalink
perf: add an ability to merge specific versions (#46)
Browse files Browse the repository at this point in the history
* refactor: remove updatedAt field from diff doc

* feat: add startVersion & endVersion args to mergeDiffs method

* test: cover mergeDiffs methods with additional cases

Co-authored-by: Valeriy Borodayev <[email protected]>
  • Loading branch information
borodayev and Valeriy Borodayev committed Aug 9, 2020
1 parent a015b75 commit 2ba707c
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 41 deletions.
32 changes: 24 additions & 8 deletions __fixtures__/Post.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-await-in-loop */
// @flow
/* eslint-disable no-param-reassign, func-names */

Expand All @@ -7,6 +8,16 @@ import DB from './db';

DB.init();

export interface IPostDoc extends Document {
title: string;
subjects: Array<{ name: string }>;
}

interface IPostModel extends Model<IPostDoc> {
diffModel(): IDiffModel;
createDifferentSubjects(findObj: string, count: number): Promise<void>;
}

export const PostSchema: Schema<IPostDoc> = new mongoose.Schema(
{
title: {
Expand Down Expand Up @@ -34,14 +45,19 @@ export const PostSchema: Schema<IPostDoc> = new mongoose.Schema(
}
);

export interface IPostDoc extends Document {
title: string;
subjects: Array<{ name: string }>;
}

interface IPostModel extends Model<IPostDoc> {
diffModel(): IDiffModel;
}
// for test purposes
PostSchema.statics.createDifferentSubjects = async function (
title: string,
count: number
): Promise<void> {
for (let i = 1; i <= count; i += 1) {
const post: IPostDoc = await this.findOne({ title }).exec();
if (post) {
post.subjects.push({ name: `name_${i}` });
await post.save();
}
}
};

PostSchema.plugin(DiffPlugin);

Expand Down
57 changes: 48 additions & 9 deletions src/DiffModel.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/* eslint-disable func-names */
import { Schema, Connection } from 'mongoose';
import { IDiffModel, ObjectId, RawChangeT, ChangeDoc, IDiffDoc } from './types';
import {
IDiffModel,
ObjectId,
RawChangeT,
ChangeDoc,
IDiffDoc,
MergedDiffsOptsT,
} from './types';
import MHD, { revertChanges } from './diff';

export default function (
mongooseConnection: Connection,
collectionName: string
): IDiffModel {
if (!mongooseConnection) throw new Error(`'mongooseConection' is required`);
if (!mongooseConnection) throw new Error(`'mongooseConnection' is required`);
if (!collectionName) throw new Error(`'collectionName' is required`);

const ItemSchema = new Schema(
Expand Down Expand Up @@ -49,7 +56,11 @@ export default function (
c: [ChangeSchema],
v: Number,
},
{ versionKey: false, timestamps: true, collection: collectionName }
{
versionKey: false,
timestamps: { createdAt: true, updatedAt: false },
collection: collectionName,
}
);
DiffSchema.index({ docId: 1, path: 1 });

Expand Down Expand Up @@ -103,12 +114,40 @@ export default function (
return revertChanges(doc, changes);
};

DiffSchema.statics.mergeDiffs = async function (doc: {
toObject: Function;
}): Promise<Array<RawChangeT>> {
const currentDoc = { ...doc.toObject() };
const initialDoc = await this.revertToVersion(currentDoc, 1);
if (!initialDoc) return [];
DiffSchema.statics.mergeDiffs = async function (
doc: {
toObject: Function;
},
opts?: MergedDiffsOptsT
): Promise<Array<RawChangeT>> {
const { startVersion, endVersion } = opts || {};

if (typeof startVersion === 'number' && startVersion < 1)
throw new Error(
`"startVersion" argument should be >= 1, but got: ${startVersion}`
);

if (typeof endVersion === 'number' && endVersion < 1)
throw new Error(
`"endVersion" argument should be >= 1, but got: ${endVersion}`
);

let initialDoc = null;
let currentDoc = { ...doc.toObject() };

if (startVersion && endVersion) {
initialDoc = await this.revertToVersion(currentDoc, startVersion);
currentDoc = await this.revertToVersion(currentDoc, endVersion);
} else if (startVersion) {
initialDoc = await this.revertToVersion(currentDoc, startVersion);
} else if (endVersion) {
initialDoc = await this.revertToVersion(currentDoc, 1);
currentDoc = await this.revertToVersion(currentDoc, endVersion);
} else {
initialDoc = await this.revertToVersion(currentDoc, 1);
}

if (!initialDoc || !currentDoc) return [];
return MHD.findDiff(initialDoc, currentDoc);
};

Expand Down
Loading

0 comments on commit 2ba707c

Please sign in to comment.