@resin/pinejs
Version:
Pine.js is a sophisticated rules-driven API engine that enables you to define rules in a structured subset of English. Those rules are used in order for Pine.js to generate a database schema and the associated [OData](http://www.odata.org/) API. This make
177 lines (169 loc) • 8.73 kB
JavaScript
// Generated by CoffeeScript 1.12.7
(function() {
var Promise, _, transactionModel;
_ = require('lodash');
Promise = require('bluebird');
transactionModel = require('./transaction.sbvr');
exports.config = {
models: [
{
apiRoot: 'transaction',
modelText: transactionModel,
customServerCode: exports
}
]
};
exports.setup = function(app, sbvrUtils) {
return exports.addModelHooks = function(modelName) {
var endTransaction;
sbvrUtils.addPureHook('PUT', modelName, 'all', function(arg) {
var id, logger, request, tx, vocab;
tx = arg.tx, request = arg.request;
vocab = request.vocabulary;
logger = sbvrUtils.api[vocab].logger;
id = sbvrUtils.getID(vocab, request);
return tx.executeSql('SELECT NOT EXISTS(\n SELECT 1\n FROM "resource" r\n JOIN "resource-is under-lock" AS rl ON rl."resource" = r."id"\n WHERE r."resource type" = ?\n AND r."resource id" = ?\n) AS result;', [request.resourceName, id])["catch"](function(err) {
logger.error('Unable to check resource locks', err, err.stack);
throw new Error('Unable to check resource locks');
}).then(function(result) {
var ref;
if ((ref = result.rows[0].result) === false || ref === 0 || ref === '0') {
throw new Error('The resource is locked and cannot be edited');
}
});
});
endTransaction = function(transactionID) {
return sbvrUtils.db.transaction(function(tx) {
var getFieldsObject, getLockedRow, placeholders;
placeholders = {};
getLockedRow = function(lockID) {
return tx.executeSql('SELECT "resource"."resource id" AS "resource_id"\nFROM "resource",\n "resource-is under-lock"\nWHERE "resource"."id" = "resource-is under-lock"."resource"\nAND "resource-is under-lock"."lock" = ?;', [lockID]);
};
getFieldsObject = function(conditionalResourceID, clientModel) {
return tx.executeSql('SELECT "conditional field"."field name" AS "field_name", "conditional field"."field value" AS "field_value"\nFROM "conditional field"\nWHERE "conditional field"."conditional resource" = ?;', [conditionalResourceID]).then(function(fields) {
var fieldsObject;
fieldsObject = {};
return Promise.all(fields.rows.map(function(field) {
var fieldName, fieldValue, modelField;
fieldName = field.field_name.replace(clientModel.resourceName + '.', '');
fieldValue = field.field_value;
modelField = _.find(clientModel.fields, {
fieldName: fieldName
});
if (modelField.dataType === 'ForeignKey' && _.isNaN(Number(fieldValue))) {
if (!placeholders.hasOwnProperty(fieldValue)) {
throw new Error('Cannot resolve placeholder' + fieldValue);
} else {
return placeholders[fieldValue].promise.then(function(resolvedID) {
return fieldsObject[fieldName] = resolvedID;
})["catch"](function() {
throw new Error('Placeholder failed' + fieldValue);
});
}
} else {
return fieldsObject[fieldName] = fieldValue;
}
})).then(function() {
return fieldsObject;
});
});
};
return tx.executeSql('SELECT "conditional resource"."id", "conditional resource"."lock", "conditional resource"."resource type" AS "resource_type",\n"conditional resource"."conditional type" AS "conditional_type", "conditional resource"."placeholder"\nFROM "conditional resource"\nWHERE "conditional resource"."transaction" = ?;', [transactionID]).then(function(conditionalResources) {
conditionalResources.rows.forEach(function(conditionalResource) {
var placeholder;
placeholder = conditionalResource.placeholder;
if ((placeholder != null) && placeholder.length > 0) {
placeholders[placeholder] = {};
return placeholders[placeholder].promise = new Promise(function(resolve, reject) {
placeholders[placeholder].resolve = resolve;
return placeholders[placeholder].reject = reject;
});
}
});
return Promise.all(conditionalResources.rows.map(function(conditionalResource) {
var clientModel, doCleanup, lockID, passthrough, placeholder, url;
placeholder = conditionalResource.placeholder;
lockID = conditionalResource.lock;
doCleanup = function() {
return Promise.all([tx.executeSql('DELETE FROM "conditional field" WHERE "conditional resource" = ?;', [conditionalResource.id]), tx.executeSql('DELETE FROM "conditional resource" WHERE "lock" = ?;', [lockID]), tx.executeSql('DELETE FROM "resource-is under-lock" WHERE "lock" = ?;', [lockID]), tx.executeSql('DELETE FROM "lock" WHERE "id" = ?;', [lockID])]);
};
passthrough = {
tx: tx
};
clientModel = clientModels[modelName].resources[conditionalResource.resource_type];
url = modelName + '/' + conditionalResource.resource_type;
switch (conditionalResource.conditional_type) {
case 'DELETE':
return getLockedRow(lockID).then(function(lockedRow) {
lockedRow = lockedRow.rows[0];
url = url + '?$filter=' + clientModel.idField + ' eq ' + lockedRow.resource_id;
return sbvrUtils.PinejsClient.prototype["delete"]({
url: url,
passthrough: passthrough
});
}).then(doCleanup);
case 'EDIT':
return getLockedRow(lockID).then(function(lockedRow) {
lockedRow = lockedRow.rows[0];
return getFieldsObject(conditionalResource.id, clientModel).then(function(body) {
body[clientModel.idField] = lockedRow.resource_id;
return sbvrUtils.PinejsClient.prototype.put({
url: url,
body: body,
passthrough: passthrough
});
});
}).then(doCleanup);
case 'ADD':
return getFieldsObject(conditionalResource.id, clientModel).then(function(body) {
return sbvrUtils.PinejsClient.prototype.post({
url: url,
body: body,
passthrough: passthrough
});
}).then(function(result) {
return placeholders[placeholder].resolve(result.id);
}).then(doCleanup).tapCatch(function(err) {
placeholders[placeholder].reject(err);
});
}
}));
}).then(function(err) {
return tx.executeSql('DELETE FROM "transaction" WHERE "id" = ?;', [transactionID]);
}).then(function(result) {
return sbvrUtils.validateModel(tx, modelName);
});
});
};
app.post('/transaction/execute', function(req, res, next) {
var id;
id = Number(req.body.id);
if (_.isNaN(id)) {
return res.sendStatus(404);
} else {
return endTransaction(id).then(function() {
return res.sendStatus(200);
})["catch"](function(err) {
console.error('Error ending transaction', err, err.stack);
return res.status(404).json(err);
});
}
});
app.get('/transaction', function(req, res, next) {
return res.json({
transactionURI: '/transaction/transaction',
conditionalResourceURI: '/transaction/conditional_resource',
conditionalFieldURI: '/transaction/conditional_field',
lockURI: '/transaction/lock',
transactionLockURI: '/transaction/lock__belongs_to__transaction',
resourceURI: '/transaction/resource',
lockResourceURI: '/transaction/resource__is_under__lock',
exclusiveLockURI: '/transaction/lock__is_exclusive',
commitTransactionURI: '/transaction/execute'
});
});
return app.all('/transaction/*', sbvrUtils.handleODataRequest);
};
};
}).call(this);
//# sourceMappingURL=transactions.js.map