2016-05-03 22:50:21 +00:00
|
|
|
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
|
|
|
// Node module: loopback
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2014-01-26 22:02:56 +00:00
|
|
|
/**
|
|
|
|
* Module Dependencies.
|
|
|
|
*/
|
|
|
|
|
2014-10-13 09:45:06 +00:00
|
|
|
var assert = require('assert');
|
2014-01-26 22:02:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Checkpoint list entry.
|
|
|
|
*
|
|
|
|
* @property id {Number} the sequencial identifier of a checkpoint
|
|
|
|
* @property time {Number} the time when the checkpoint was created
|
|
|
|
* @property sourceId {String} the source identifier
|
2014-10-13 09:45:06 +00:00
|
|
|
*
|
|
|
|
* @class Checkpoint
|
2014-06-05 07:45:09 +00:00
|
|
|
* @inherits {PersistedModel}
|
2014-01-26 22:02:56 +00:00
|
|
|
*/
|
|
|
|
|
2014-10-13 09:45:06 +00:00
|
|
|
module.exports = function(Checkpoint) {
|
|
|
|
// Workaround for https://github.com/strongloop/loopback/issues/292
|
|
|
|
Checkpoint.definition.rawProperties.time.default =
|
|
|
|
Checkpoint.definition.properties.time.default = function() {
|
|
|
|
return new Date();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the current checkpoint id
|
|
|
|
* @callback {Function} callback
|
|
|
|
* @param {Error} err
|
2015-12-17 17:02:35 +00:00
|
|
|
* @param {Number} checkpoint The current checkpoint seq
|
2014-10-13 09:45:06 +00:00
|
|
|
*/
|
|
|
|
Checkpoint.current = function(cb) {
|
|
|
|
var Checkpoint = this;
|
2015-12-17 17:02:35 +00:00
|
|
|
Checkpoint._getSingleton(function(err, cp) {
|
|
|
|
cb(err, cp.seq);
|
2014-05-10 00:19:32 +00:00
|
|
|
});
|
2014-11-04 12:52:49 +00:00
|
|
|
};
|
2014-05-10 00:19:32 +00:00
|
|
|
|
2015-12-17 17:02:35 +00:00
|
|
|
Checkpoint._getSingleton = function(cb) {
|
2016-04-01 09:14:26 +00:00
|
|
|
var query = { limit: 1 }; // match all instances, return only one
|
|
|
|
var initialData = { seq: 1 };
|
2015-12-17 17:02:35 +00:00
|
|
|
this.findOrCreate(query, initialData, cb);
|
|
|
|
};
|
2015-03-02 12:09:14 +00:00
|
|
|
|
2015-12-17 17:02:35 +00:00
|
|
|
/**
|
|
|
|
* Increase the current checkpoint if it already exists otherwise initialize it
|
|
|
|
* @callback {Function} callback
|
|
|
|
* @param {Error} err
|
|
|
|
* @param {Object} checkpoint The current checkpoint
|
|
|
|
*/
|
|
|
|
Checkpoint.bumpLastSeq = function(cb) {
|
|
|
|
var Checkpoint = this;
|
|
|
|
Checkpoint._getSingleton(function(err, cp) {
|
|
|
|
if (err) return cb(err);
|
|
|
|
var originalSeq = cp.seq;
|
|
|
|
cp.seq++;
|
|
|
|
// Update the checkpoint but only if it was not changed under our hands
|
2016-04-01 09:14:26 +00:00
|
|
|
Checkpoint.updateAll({ id: cp.id, seq: originalSeq }, { seq: cp.seq }, function(err, info) {
|
2015-12-17 17:02:35 +00:00
|
|
|
if (err) return cb(err);
|
|
|
|
// possible outcomes
|
|
|
|
// 1) seq was updated to seq+1 - exactly what we wanted!
|
|
|
|
// 2) somebody else already updated seq to seq+1 and our call was a no-op.
|
|
|
|
// That should be ok, checkpoints are time based, so we reuse the one created just now
|
|
|
|
// 3) seq was bumped more than once, so we will be using a value that is behind the latest seq.
|
|
|
|
// @bajtos is not entirely sure if this is ok, but since it wasn't handled by the current implementation either,
|
|
|
|
// he thinks we can keep it this way.
|
|
|
|
cb(null, cp);
|
2014-10-13 09:45:06 +00:00
|
|
|
});
|
2015-12-17 17:02:35 +00:00
|
|
|
});
|
|
|
|
};
|
2014-10-13 09:45:06 +00:00
|
|
|
};
|