Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions lib/sequence.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Sequence = function(schema, options) {
Sequence.getInstance = function(schema, options) {
var sequence = new Sequence(schema, options),
id = sequence.getId();

if(sequenceArchive.existsSequence(id)){
throw new Error('Counter already defined for field "'+id+'"');
}
Expand Down Expand Up @@ -119,7 +119,6 @@ Sequence.prototype._getCounterReferenceField = function(doc) {
reference.push(JSON.stringify(doc[this._options.reference_fields[i]]));
}
}

return reference;
};

Expand Down Expand Up @@ -180,6 +179,8 @@ Sequence.prototype._createCounterModel = function() {
* @method _setHooks
*/
Sequence.prototype._setHooks = function() {
var _this = this;

this._schema.pre('save', true, (function(sequence){
return function(next, done) {
var doc = this;
Expand All @@ -194,6 +195,52 @@ Sequence.prototype._setHooks = function() {
}.bind(doc));
};
})(this));

this._schema.pre('findOneAndUpdate', function(next) {
// jscs:disable
var _thisquery = this,
referenceValue;

// jscs:enable

this.model.findOne(_thisquery._conditions, function(err, obj) {
if (err) return next();
if (obj) return next();
else {
referenceValue = _this._getCounterReferenceField(_thisquery._update);
_this._setNextCounterByReference(_this.getId(), referenceValue, function(err, seq) {
if (err) return next();
_thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {};
_thisquery._update['$setOnInsert'][_this._options.inc_field] = seq;
next();
});
}
});
});


this._schema.pre('update', function(next, done) {
// jscs:disable
var _thisquery = this,
referenceValue;

// jscs:enable


this.model.findOne(_thisquery._conditions, function(err, obj) {
if (err) return next();
if (obj) return next();
else {
referenceValue = _this._getCounterReferenceField(_thisquery._update.$set);
_this._setNextCounterByReference(_this.getId(), referenceValue, function(err, seq) {
if (err) return next();
_thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {};
_thisquery._update['$setOnInsert'][_this._options.inc_field] = seq;
next();
});
}
});
});
};

/**
Expand All @@ -215,7 +262,6 @@ Sequence.prototype._setMethods = function() {
if (_.isNull(sequence)) {
return callback(new Error('Trying to increment a wrong sequence using the id ' + id));
}
// sequence = sequence.sequence;

sequence._setNextCounter(this, function(err, seq) {
if (err) return callback(err);
Expand All @@ -235,7 +281,11 @@ Sequence.prototype._setMethods = function() {
*/
Sequence.prototype._setNextCounter = function(doc, callback) {
var id = this.getId();
var referenceValue = this._getCounterReferenceField(doc);
var referenceValue = this._getCounterReferenceField(doc);
this._setNextCounterByReference(id, referenceValue, callback);
};

Sequence.prototype._setNextCounterByReference = function(id, referenceValue, callback) {
this._counterModel.findOneAndUpdate(
{ id: id, reference_value: referenceValue },
{ $inc: { seq: 1 } },
Expand Down
154 changes: 152 additions & 2 deletions test/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,156 @@ describe('Basic => ', function() {

});

describe('hook', function(){
describe('simple counters', function(){
before(function(done) {
var SimpleFieldSchema = new Schema({
id: Number,
val: String,
tag: String
});
var wrapper = function(schema, options) {
var instance = AutoIncrement(schema, options);
this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference');
return instance;
}.bind(this);
SimpleFieldSchema.plugin(wrapper, {id: 'id_hook_test', inc_field: 'id'});
this.SimpleField = mongoose.model('SimpleFieldHookTest', SimpleFieldSchema);
this.SimpleField.create({val: 'existing'}, function(err){
this.setNextCounterSpy.reset();
done(err);
}.bind(this));
});

afterEach(function(){
this.setNextCounterSpy.reset();
});

it('is called when saving a new document', function(done){
var t = new this.SimpleField({val: 'a'});
t.save(function(err){
sinon.assert.calledOnce(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('is not called when saving an existing document', function(done){
var t = new this.SimpleField({val: 'a'});
t.isNew = false;
t.save(function(err){
sinon.assert.notCalled(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('is called when upserting in an update and result in an insert', function(done){
this.SimpleField.update({val: '1234'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){
sinon.assert.calledOnce(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('is not called when upserting in an update and not result in an insert', function(done){
this.SimpleField.update({val: 'existing'}, {tag: 'update'}, {upsert: true}, function(err, doc){
sinon.assert.notCalled(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){
this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){
sinon.assert.calledOnce(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){
this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'findOneAndUpdate'}, {upsert: true}, function(err, doc){
sinon.assert.notCalled(this.setNextCounterSpy);
done(err);
}.bind(this));
});
});

describe('referenced counters', function() {
before(function(done) {
var SimpleFieldSchema = new Schema({
same_tag_members: Number,
val: String,
tag: String
});
var wrapper = function(schema, options) {
var instance = AutoIncrement(schema, options);
this.instance = instance;
this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference');
return instance;
}.bind(this);
SimpleFieldSchema.plugin(wrapper, {
id: 'id_hook_test_referenced',
inc_field: 'same_tag_members',
reference_fields: ['tag']}
);
this.SimpleField = mongoose.model('SimpleFieldHookTestReferenced', SimpleFieldSchema);
this.SimpleField.create({val: 'existing'}, function(err){
this.setNextCounterSpy.reset();
done(err);
}.bind(this));
});

afterEach(function(){
this.setNextCounterSpy.reset();
});

it('are called when saving a new document', function(done){
var t = new this.SimpleField({val: 'a', tag: 'red'});
t.save(function(err){
sinon.assert.calledWith(
this.setNextCounterSpy,
'id_hook_test_referenced',
this.instance._getCounterReferenceField(t)
);
done(err);
}.bind(this));
});

it('are called when upserting in an update and result in an insert', function(done){
this.SimpleField.update({val: '1234'}, {tag: 'blue'}, {upsert: true}, function(err, doc){
sinon.assert.calledWith(
this.setNextCounterSpy,
'id_hook_test_referenced',
this.instance._getCounterReferenceField({tag:'blue'})
);
done(err);
}.bind(this));
});

it('are not called when upserting in an update and not result in an insert', function(done){
this.SimpleField.update({val: 'existing'}, {tag: 'green'}, {upsert: true}, function(err, doc){
sinon.assert.notCalled(this.setNextCounterSpy);
done(err);
}.bind(this));
});

it('are called when upserting in an findOneAndUpdate and result in an insert', function(done){
this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'pink'}, {upsert: true}, function(err, doc){
sinon.assert.calledWith(
this.setNextCounterSpy,
'id_hook_test_referenced',
this.instance._getCounterReferenceField({tag:'pink'})
);
done(err);
}.bind(this));
});

it('are not called when upserting in an findOneAndUpdate and not result in an insert', function(done){
this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'yellow'}, {upsert: true}, function(err, doc){
sinon.assert.notCalled(this.setNextCounterSpy);
done(err);
}.bind(this));
});
});
});

describe('a manual increment field => ', function() {

before(function(done) {
Expand Down Expand Up @@ -342,7 +492,7 @@ describe('Basic => ', function() {
assert.throws(function(){
UnusedSchema.plugin(AutoIncrement, {inc_field: 'inhabitant', reference_fields: ['country', 'city'], disable_hooks: true});
}, Error);

});
});

Expand Down Expand Up @@ -427,7 +577,7 @@ describe('Basic => ', function() {
});
});
});
});
});

});
});