extendedApi.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. 'use strict';
  2. var utils = require('./utils');
  3. var debug = require('./debug');
  4. var RedisClient = require('../').RedisClient;
  5. var Command = require('./command');
  6. var noop = function () {};
  7. /**********************************************
  8. All documented and exposed API belongs in here
  9. **********************************************/
  10. // Redirect calls to the appropriate function and use to send arbitrary / not supported commands
  11. RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = function (command, args, callback) {
  12. // Throw to fail early instead of relying in order in this case
  13. if (typeof command !== 'string') {
  14. throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name');
  15. }
  16. if (!Array.isArray(args)) {
  17. if (args === undefined || args === null) {
  18. args = [];
  19. } else if (typeof args === 'function' && callback === undefined) {
  20. callback = args;
  21. args = [];
  22. } else {
  23. throw new TypeError('Wrong input type "' + args.constructor.name + '" for args');
  24. }
  25. }
  26. if (typeof callback !== 'function' && callback !== undefined) {
  27. throw new TypeError('Wrong input type "' + (callback !== null ? callback.constructor.name : 'null') + '" for callback function');
  28. }
  29. // Using the raw multi command is only possible with this function
  30. // If the command is not yet added to the client, the internal function should be called right away
  31. // Otherwise we need to redirect the calls to make sure the interal functions don't get skipped
  32. // The internal functions could actually be used for any non hooked function
  33. // but this might change from time to time and at the moment there's no good way to distinguishe them
  34. // from each other, so let's just do it do it this way for the time being
  35. if (command === 'multi' || typeof this[command] !== 'function') {
  36. return this.internal_send_command(new Command(command, args, callback));
  37. }
  38. if (typeof callback === 'function') {
  39. args = args.concat([callback]); // Prevent manipulating the input array
  40. }
  41. return this[command].apply(this, args);
  42. };
  43. RedisClient.prototype.end = function (flush) {
  44. // Flush queue if wanted
  45. if (flush) {
  46. this.flush_and_error({
  47. message: 'Connection forcefully ended and command aborted.',
  48. code: 'NR_CLOSED'
  49. });
  50. } else if (arguments.length === 0) {
  51. this.warn(
  52. 'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' +
  53. 'Please check the doku (https://github.com/NodeRedis/node_redis) and explictly use flush.'
  54. );
  55. }
  56. // Clear retry_timer
  57. if (this.retry_timer) {
  58. clearTimeout(this.retry_timer);
  59. this.retry_timer = null;
  60. }
  61. this.stream.removeAllListeners();
  62. this.stream.on('error', noop);
  63. this.connected = false;
  64. this.ready = false;
  65. this.closing = true;
  66. return this.stream.destroySoon();
  67. };
  68. RedisClient.prototype.unref = function () {
  69. if (this.connected) {
  70. debug("Unref'ing the socket connection");
  71. this.stream.unref();
  72. } else {
  73. debug('Not connected yet, will unref later');
  74. this.once('connect', function () {
  75. this.unref();
  76. });
  77. }
  78. };
  79. RedisClient.prototype.duplicate = function (options, callback) {
  80. if (typeof options === 'function') {
  81. callback = options;
  82. options = null;
  83. }
  84. var existing_options = utils.clone(this.options);
  85. options = utils.clone(options);
  86. for (var elem in options) {
  87. existing_options[elem] = options[elem];
  88. }
  89. var client = new RedisClient(existing_options);
  90. client.selected_db = this.selected_db;
  91. if (typeof callback === 'function') {
  92. var ready_listener = function () {
  93. callback(null, client);
  94. client.removeAllListeners(error_listener);
  95. };
  96. var error_listener = function (err) {
  97. callback(err);
  98. client.end(true);
  99. };
  100. client.once('ready', ready_listener);
  101. client.once('error', error_listener);
  102. return;
  103. }
  104. return client;
  105. };