transaction.js 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const utils_1 = require("./utils");
  4. const standard_as_callback_1 = require("standard-as-callback");
  5. const pipeline_1 = require("./pipeline");
  6. function addTransactionSupport(redis) {
  7. redis.pipeline = function (commands) {
  8. const pipeline = new pipeline_1.default(this);
  9. if (Array.isArray(commands)) {
  10. pipeline.addBatch(commands);
  11. }
  12. return pipeline;
  13. };
  14. const { multi } = redis;
  15. redis.multi = function (commands, options) {
  16. if (typeof options === "undefined" && !Array.isArray(commands)) {
  17. options = commands;
  18. commands = null;
  19. }
  20. if (options && options.pipeline === false) {
  21. return multi.call(this);
  22. }
  23. const pipeline = new pipeline_1.default(this);
  24. pipeline.multi();
  25. if (Array.isArray(commands)) {
  26. pipeline.addBatch(commands);
  27. }
  28. const exec = pipeline.exec;
  29. pipeline.exec = function (callback) {
  30. // Wait for the cluster to be connected, since we need nodes information before continuing
  31. if (this.isCluster && !this.redis.slots.length) {
  32. if (this.redis.status === "wait")
  33. this.redis.connect().catch(utils_1.noop);
  34. return standard_as_callback_1.default(new Promise((resolve, reject) => {
  35. this.redis.delayUntilReady((err) => {
  36. if (err) {
  37. reject(err);
  38. return;
  39. }
  40. this.exec(pipeline).then(resolve, reject);
  41. });
  42. }), callback);
  43. }
  44. if (this._transactions > 0) {
  45. exec.call(pipeline);
  46. }
  47. // Returns directly when the pipeline
  48. // has been called multiple times (retries).
  49. if (this.nodeifiedPromise) {
  50. return exec.call(pipeline);
  51. }
  52. const promise = exec.call(pipeline);
  53. return standard_as_callback_1.default(promise.then(function (result) {
  54. const execResult = result[result.length - 1];
  55. if (typeof execResult === "undefined") {
  56. throw new Error("Pipeline cannot be used to send any commands when the `exec()` has been called on it.");
  57. }
  58. if (execResult[0]) {
  59. execResult[0].previousErrors = [];
  60. for (let i = 0; i < result.length - 1; ++i) {
  61. if (result[i][0]) {
  62. execResult[0].previousErrors.push(result[i][0]);
  63. }
  64. }
  65. throw execResult[0];
  66. }
  67. return utils_1.wrapMultiResult(execResult[1]);
  68. }), callback);
  69. };
  70. const { execBuffer } = pipeline;
  71. pipeline.execBuffer = function (callback) {
  72. if (this._transactions > 0) {
  73. execBuffer.call(pipeline);
  74. }
  75. return pipeline.exec(callback);
  76. };
  77. return pipeline;
  78. };
  79. const { exec } = redis;
  80. redis.exec = function (callback) {
  81. return standard_as_callback_1.default(exec.call(this).then(function (results) {
  82. if (Array.isArray(results)) {
  83. results = utils_1.wrapMultiResult(results);
  84. }
  85. return results;
  86. }), callback);
  87. };
  88. }
  89. exports.addTransactionSupport = addTransactionSupport;