transaction.js 3.7 KB

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