'use strict'; var assert = require('assert'); var uuid = require('node-uuid'); var jobStatus = require('../job_status'); var validStatusTransitions = require('./job_status_transitions'); var mandatoryProperties = [ 'job_id', 'status', 'query', 'created_at', 'updated_at', 'user' ]; var finalStatus = [ jobStatus.CANCELLED, jobStatus.DONE, jobStatus.FAILED, jobStatus.UNKNOWN ]; function JobBase(data) { var now = new Date().toISOString(); this.data = data; if (!this.data.job_id) { this.data.job_id = uuid.v4(); } if (!this.data.created_at) { this.data.created_at = now; } if (!this.data.updated_at) { this.data.updated_at = now; } } module.exports = JobBase; JobBase.prototype.isValidStatusTransition = function (initialStatus, finalStatus) { var transition = [ initialStatus, finalStatus ]; for (var i = 0; i < validStatusTransitions.length; i++) { try { assert.deepEqual(transition, validStatusTransitions[i]); return true; } catch (e) { continue; } } return false; }; JobBase.prototype.isFinalStatus = function (status) { return finalStatus.indexOf(status) !== -1; }; // should be implemented by childs JobBase.prototype.getNextQuery = function () { throw new Error('Unimplemented method'); }; JobBase.prototype.hasNextQuery = function () { return !!this.getNextQuery(); }; JobBase.prototype.isPending = function () { return this.data.status === jobStatus.PENDING; }; JobBase.prototype.isRunning = function () { return this.data.status === jobStatus.RUNNING; }; JobBase.prototype.isDone = function () { return this.data.status === jobStatus.DONE; }; JobBase.prototype.isCancelled = function () { return this.data.status === jobStatus.CANCELLED; }; JobBase.prototype.isFailed = function () { return this.data.status === jobStatus.FAILED; }; JobBase.prototype.isUnknown = function () { return this.data.status === jobStatus.UNKNOWN; }; JobBase.prototype.setQuery = function (query) { var now = new Date().toISOString(); if (!this.isPending()) { throw new Error('Job is not pending, it cannot be updated'); } this.data.updated_at = now; this.data.query = query; }; JobBase.prototype.setStatus = function (finalStatus, errorMesssage) { var now = new Date().toISOString(); var initialStatus = this.data.status; var isValid = this.isValidStatusTransition(initialStatus, finalStatus); if (!isValid) { throw new Error('Cannot set status from ' + initialStatus + ' to ' + finalStatus); } this.data.updated_at = now; this.data.status = finalStatus; if (finalStatus === jobStatus.FAILED && errorMesssage) { this.data.failed_reason = errorMesssage; } }; JobBase.prototype.validate = function () { for (var i = 0; i < mandatoryProperties.length; i++) { if (!this.data[mandatoryProperties[i]]) { throw new Error('property "' + mandatoryProperties[i] + '" is mandatory'); } } }; JobBase.prototype.serialize = function () { var data = JSON.parse(JSON.stringify(this.data)); delete data.host; return data; };