File: platform/plugins/Users/classes/Users/Vote.js
/**
* Class representing vote rows.
*
* @module Users
*/
var Q = require('Q');
var Db = Q.require('Db');
/**
* Class representing 'Vote' rows in the 'Users' database
* <br/>Represents a vote by a user for something
* @namespace Users
* @class Vote
* @extends Base.Users.Vote
* @constructor
* @param fields {object} The fields values to initialize table row as
* an associative array of `{column: value}` pairs
*/
function Users_Vote (fields) {
// Run constructors of mixed in objects
Users_Vote.constructors.apply(this, arguments);
/*
* Add any other methods to the model class by assigning them to this.
* * * */
var _cache = null;
function _afterHandler (query, error, result) {
if (!error && _cache) {
_cache.save(false, true, function (err) {
if (err) {
// rollback
_cache.beforeRetrieveExecute = function (query) {
return query.rollback().execute();
};
_cache.retrieve(function () {
_cache = null;
query.resume(err);
});
} else {
_cache = null;
query.resume(error, result);
}
});
return true;
}
}
function _rollback (obj, str) {
obj.beforeRetrieveExecute = function (query) {
return query.rollback();
};
obj.retrieve(function () {
throw new Error(str);
});
}
/**
* Update total votes in Users.Total when saving new vote
* @method beforeSaveExecute
* @param query {Db.Query.Mysql}
* The query being excecuted
* @param modifiedFields {object}
* The fields which are modified by query
*/
this.beforeSaveExecute = function (query, modifiedFields) {
var self = this;
var total = new Users.Total({forId: this.forId});
total.retrieve('*', true, true, function(err, total_res) {
if (!err) {
if (!total_res.length) {
total.weightTotal = 0;
total.voteCount = 0;
total.value = 0;
} else {
total = total_res[0];
}
var weightTotal = total.weightTotal;
var vote = new Users.Vote({userId: modifiedFields.userId, forId: modifiedFields.forId});
vote.retrieve('*', true, function (err, vote_res) {
if (!err) {
if (!vote_res.length) {
total.weightTotal += modifiedFields.weight;
total.voteCount += 1;
total.value = (total.value * weightTotal + modifiedFields.value * modifiedFields.weight) / (total.weightTotal);
} else {
vote = vote_res[0];
if (!total.voteCount) {
// something is wrong
total.voteCount = 1;
}
total.weightTotal += (modifiedFields.weight - vote.weight);
if (!total.weightTotal) {
_rollback(total, self.className + ".beforeSaveExecute(): total.weight = 0!");
}
total.value =
(total.value * weightTotal
- vote.value * vote.weight
+ modifiedFields.value * modifiedFields.weight) / (total.weightTotal);
}
_cache = total;
query.resume();
} else console.log(err);
});
} else console.log(err);
}).begin().lock().resume();
if (this.prototype.beforeSaveExecute) {
return this.prototype.beforeSaveExecute(query, modifiedFields);
}
};
/**
* Commit or rollback transaction when saving new vote
* @method afterSaveExecute
* @param query {Db.Query.Mysql}
* The query being excecuted
* @param result {object}
* The result of the query
* @param error {Error}
* Error object if any
*/
this.afterSaveExecute = _afterHandler;
/**
* Update total votes in Users.Total when removing a vote
* @method beforeRemoveExecute
* @param query {Db.Query.Mysql}
* The query being excecuted
*/
this.beforeRemoveExecute = function (query) {
var self = this;
var vote = new Users.Vote({userId: this.userId, forId: this.forId});
vote.retrieve('*', true, true, function(err, vote_res) {
if (!err) {
if (vote_res.length) {
vote = vote_res[0];
var total = new Users.Total({forId: vote.forId});
total.retrieve('*', true, true, function (err, total_res) {
if (!err) {
if (!total_res.length) {
// something is wrong ... if there are votes, there should have been a total
total.weightTotal = 0;
total.voteCount = 0;
total.value = 0;
} else {
total = total_res[0];
var weightTotal = total.weightTotal;
total.weightTotal -= vote.weight;
if (!total.weightTotal) {
total.value = 0;
} else {
total.value =
(total.value * weightTotal - vote.value * vote.weight) / (total.weightTotal);
}
total.voteCount -= 1;
}
_cache = total;
query.resume();
} else console.log(err);
}).lock().resume();
} else query.resume();
} else console.log(err);
}).begin().resume();
};
/**
* Commit or rollback transaction when deleting a vote
* @method afterRemoveExecute
* @param query {Db.Query.Mysql}
* The query being excecuted
* @param result {object}
* The result of the query
* @param error {Error}
* Error object if any
*/
this.afterRemoveExecute = _afterHandler;
/* * * */
}
Q.mixin(Users_Vote, Q.require('Base/Users/Vote'));
/**
* The setUp() method is called the first time
* an object of this class is constructed.
* @method setUp
*/
Users_Vote.prototype.setUp = function () {
// put any code here
// overrides the Base class
};
module.exports = Users_Vote;