UNPKG

@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
// 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