Source: ogmneo-operation-executer.js

  1. 'use strict';
  2. const { OGMNeoOperation } = require('./ogmneo-operation');
  3. const OGMNeo = require('./ogmneo');
  4. const Printer = require('./ogmneo-printer');
  5. const _ = require('lodash');
  6. /**
  7. * @class OGMNeoOperationExecuter
  8. */
  9. class OGMNeoOperationExecuter {
  10. /**
  11. * Batches an array of READ operations in a single transaction and returns the results.
  12. *
  13. * @static
  14. * @param {array} operations - The array of operations that should be executed.
  15. * @returns {Promise.<object|Error>} Result(Parsed or not) of the executed opertion or some error if rejected.
  16. */
  17. static batchReadOperations(operations) {
  18. try {
  19. this._validateOperations(operations, OGMNeoOperation.READ);
  20. if (_.isEmpty(operations)) {
  21. return Promise.resolve([]);
  22. }
  23. return this.read((transaction) => {
  24. return Promise.all(operations.map(operation => this.execute(operation, transaction)));
  25. });
  26. } catch (error) {
  27. return Promise.reject(error);
  28. }
  29. }
  30. /**
  31. * Batches an array of WRITE operations in a single transaction and returns the results.
  32. *
  33. * @static
  34. * @param {array} operations - The array of operations that should be executed.
  35. * @returns {Promise.<object|Error>} Result(Parsed or not) of the executed opertion or some error if rejected.
  36. */
  37. static batchWriteOperations(operations) {
  38. try {
  39. this._validateOperations(operations, OGMNeoOperation.WRITE);
  40. if (_.isEmpty(operations)) {
  41. return Promise.resolve([]);
  42. }
  43. return this.write((transaction) => {
  44. return Promise.all(operations.map(operation => this.execute(operation, transaction)));
  45. });
  46. } catch (error) {
  47. return Promise.reject(error);
  48. }
  49. }
  50. /**
  51. * Opens a read transaction of neo4j driver and returns a result.
  52. *
  53. * @static
  54. * @param {function} transactional - A function with the transaction parameter that you must return a promise of your operations on this transaction.
  55. * @returns {Promise.<object|Error>} Result(Parsed or not) of the executed opertion or some error if rejected.
  56. */
  57. static read(transactional) {
  58. return new Promise((resolve, reject) => {
  59. let session = OGMNeo.session();
  60. return session.readTransaction((transaction) => {
  61. return transactional(transaction);
  62. }).then((result) => {
  63. session.close();
  64. resolve(result);
  65. }).catch((error)=> {
  66. reject(error);
  67. });
  68. });
  69. }
  70. /**
  71. * Opens a write transaction of neo4j drive and returns a result.
  72. *
  73. * @static
  74. * @param {function} transactional - A function with the transaction parameter that you must return a promise of your operations on this transaction.
  75. * @returns {Promise.<object|Error>} Result(Parsed or not) of the executed opertion or some error if rejected.
  76. */
  77. static write(transactional) {
  78. return new Promise((resolve, reject) => {
  79. let session = OGMNeo.session();
  80. return session.writeTransaction((transaction) => {
  81. return transactional(transaction);
  82. }).then((result) => {
  83. session.close();
  84. resolve(result);
  85. }).catch((error)=> {
  86. reject(error);
  87. });
  88. });
  89. }
  90. /**
  91. * Executes an READ or WRITE ogmneo.Operation and returns a result.
  92. *
  93. * @static
  94. * @param {OGMNeoOperation} operation - ogmneo.Operation object to be executed.
  95. * @param {object} transaction - Transaction created on read or write methods or transaction created on neo4j driver.
  96. * @returns {Promise.<object|Error>} Result(Parsed or not) of the executed opertion or some error if rejected.
  97. */
  98. static execute(operation, transaction = null) {
  99. if (operation instanceof OGMNeoOperation) {
  100. if (operation.isReadType) {
  101. return this._executeRead(operation, transaction);
  102. } else {
  103. return this._executeWrite(operation, transaction);
  104. }
  105. } else {
  106. return Promise.reject(new Error('The operation must be a instance of ogmneo.Operation'));
  107. }
  108. }
  109. // Private API
  110. static _executeRead(operation, transaction) {
  111. return new Promise((resolve, reject) => {
  112. if (transaction != null) {
  113. let promise = this.runInTransaction(operation, transaction);
  114. this._handleSingleResultPromise(null, operation, promise, resolve, reject);
  115. } else {
  116. let session = OGMNeo.session();
  117. session.readTransaction((transaction) => {
  118. let promise = this.runInTransaction(operation, transaction);
  119. this._handleSingleResultPromise(session, operation, promise, resolve, reject);
  120. });
  121. }
  122. });
  123. }
  124. static _executeWrite(operation, transaction) {
  125. return new Promise((resolve, reject) => {
  126. if (transaction != null) {
  127. let promise = this.runInTransaction(operation, transaction);
  128. this._handleSingleResultPromise(null, operation, promise, resolve, reject);
  129. } else {
  130. let session = OGMNeo.session();
  131. let promise = session.writeTransaction((transaction) => {
  132. return this.runInTransaction(operation, transaction);
  133. });
  134. this._handleSingleResultPromise(session, operation, promise, resolve, reject);
  135. }
  136. });
  137. }
  138. static runInTransaction(operation, transaction) {
  139. Printer.printCypherIfEnabled(operation.cypher);
  140. if (operation.object != null) {
  141. return transaction.run(operation.cypher, operation.object);
  142. } else {
  143. return transaction.run(operation.cypher);
  144. }
  145. }
  146. static _handleSingleResultPromise(session, operation, promise, resolve, reject) {
  147. promise.then((result) => {
  148. if (session != null) {
  149. session.close();
  150. }
  151. resolve(this._parseResultForOperation(operation, result));
  152. }).catch((error) => {
  153. reject(error);
  154. });
  155. }
  156. static _parseResultForOperation(operation, driverResult) {
  157. if (operation.then != null) {
  158. return operation.then(driverResult);
  159. } else {
  160. return driverResult;
  161. }
  162. }
  163. static _validateOperations(operations, type=null) {
  164. if (_.isArray(operations)) {
  165. for (let op of operations) {
  166. if ((op instanceof OGMNeoOperation) == false) {
  167. throw new Error('The parameter operations must be an array that contains only instances of ogmneo.Operation');
  168. } else if (type != null && op.type != type) {
  169. throw new Error(`The parameter operations must be an array that contains only instances of ogmneo.Operation that have type : ${type}`);
  170. }
  171. }
  172. } else {
  173. throw new Error('The parameter operations must be an array');
  174. }
  175. }
  176. }
  177. module.exports = OGMNeoOperationExecuter;