Skip to content

Commit 64aaf4a

Browse files
authored
feat: rollback without saving
1 parent e462d00 commit 64aaf4a

File tree

5 files changed

+78
-8
lines changed

5 files changed

+78
-8
lines changed

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ Post.create({ title: 'JSON patches' })
9292

9393
### Rollback to a specific patch
9494

95+
```javascript
96+
rollback(ObjectId, data, save)
97+
```
98+
9599
Documents have a `rollback` method that accepts the _ObjectId_ of a patch doc and sets the document to the state of that patch, adding a new patch to the history.
96100

97101
```javascript
@@ -112,6 +116,36 @@ Post.create({ title: 'First version' })
112116
// }
113117
```
114118

119+
#### Injecting data
120+
121+
Further the `rollback` method accepts a _data_ object which is injected into the document.
122+
123+
```javascript
124+
post.rollback(patches[1].id, { name: 'merged' })
125+
126+
// {
127+
// _id: ObjectId('4edd40c86762e0fb12000006'),
128+
// title: 'Second version',
129+
// name: 'merged',
130+
// __v: 0
131+
// }
132+
```
133+
134+
#### Rollback without saving
135+
136+
To `rollback` the document to a specific patch but without saving it back to the database call the method with an empty _data_ object and the save flag set to false.
137+
138+
```javascript
139+
post.rollback(patches[1].id, {}, false)
140+
141+
// Returns the document without saving it back to the db.
142+
// {
143+
// _id: ObjectId('4edd40c86762e0fb12000006'),
144+
// title: 'Second version',
145+
// __v: 0
146+
// }
147+
```
148+
115149
The `rollback` method will throw an Error when invoked with an ObjectId that is
116150

117151
* not a patch of the document
@@ -196,7 +230,7 @@ Post.create({
196230
})
197231
```
198232
199-
In case of a rollback in this scenario, the `rollback` method accepts an object as its second parameter where additional data can be injected:
233+
In case of a rollback in this scenario, the `rollback` method accepts an [object as its second parameter](https://github.com/codepunkt/mongoose-patch-history#injecting-data) where additional data can be injected:
200234
201235
```javascript
202236
Post.create({ title: 'v1', user: mongoose.Types.ObjectId() })

lib/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ exports.default = function (schema, opts) {
3838
schema.methods.rollback = function (patchId, data) {
3939
var _this = this;
4040

41+
var save = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
42+
4143
return this.patches.find({ ref: this.id }).sort({ date: 1 }).exec().then(function (patches) {
4244
return new _bluebird2.default(function (resolve, reject) {
4345
// patch doesn't exist
@@ -62,8 +64,13 @@ exports.default = function (schema, opts) {
6264
_fastJsonPatch2.default.applyPatch(state, patch.ops, true);
6365
});
6466

65-
// save new state and resolve with the resulting document
66-
_this.set((0, _lodash.merge)(data, state)).save().then(resolve).catch(reject);
67+
// set new state
68+
_this.set((0, _lodash.merge)(data, state));
69+
70+
// in case of save, save it back to the db and resolve
71+
if (save) {
72+
_this.save().then(resolve).catch(reject);
73+
} else resolve(_this);
6774
});
6875
});
6976
};

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
{
1313
"name": "Brett Ausmeier",
1414
"email": "[email protected]"
15+
},
16+
{
17+
"name": "Ava Johnson"
1518
}
1619
],
1720
"license": "MIT",

src/index.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export default function(schema, opts) {
8989
}
9090

9191
// roll the document back to the state of a given patch id()
92-
schema.methods.rollback = function(patchId, data) {
92+
schema.methods.rollback = function (patchId, data, save = true) {
9393
return this.patches
9494
.find({ ref: this.id })
9595
.sort({ date: 1 })
@@ -117,11 +117,13 @@ export default function(schema, opts) {
117117
jsonpatch.applyPatch(state, patch.ops, true)
118118
})
119119

120-
// save new state and resolve with the resulting document
120+
// set new state
121121
this.set(merge(data, state))
122-
.save()
123-
.then(resolve)
124-
.catch(reject)
122+
123+
// in case of save, save it back to the db and resolve
124+
if (save) {
125+
this.save().then(resolve).catch(reject)
126+
} else resolve(this)
125127
})
126128
)
127129
}

test/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,30 @@ describe('mongoose-patch-history', () => {
570570
.then(done)
571571
.catch(done)
572572
})
573+
574+
it("updates but doesn't save the document", done => {
575+
Comment.create({ text: 'comm 1', user: ObjectId() })
576+
.then(c => Comment.findOne({ _id: c.id }))
577+
.then(c => c.set({ text: 'comm 2', user: ObjectId() }).save())
578+
.then(c => Comment.findOne({ _id: c.id }))
579+
.then(c => c.set({ text: 'comm 3', user: ObjectId() }).save())
580+
.then(c => Comment.findOne({ _id: c.id }))
581+
.then(c => join(c, c.patches.find({ ref: c.id })))
582+
.then(([c, patches]) =>
583+
c.rollback(patches[1].id, { user: ObjectId() }, false)
584+
)
585+
.then(c => {
586+
assert.equal(c.text, 'comm 2')
587+
return Comment.findOne({ _id: c.id })
588+
})
589+
.then(c => {
590+
assert.equal(c.text, 'comm 3')
591+
return c.patches.find({ ref: c.id })
592+
})
593+
.then(patches => assert.equal(patches.length, 3))
594+
.then(done)
595+
.catch(done)
596+
})
573597
})
574598

575599
describe('model and collection names', () => {

0 commit comments

Comments
 (0)