promise.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. 'use strict';
  2. const SqlString = require('sql-escaper');
  3. const EventEmitter = require('events').EventEmitter;
  4. const parserCache = require('./lib/parsers/parser_cache.js');
  5. const PoolCluster = require('./lib/pool_cluster.js');
  6. const createConnection = require('./lib/create_connection.js');
  7. const createPool = require('./lib/create_pool.js');
  8. const createPoolCluster = require('./lib/create_pool_cluster.js');
  9. const PromiseConnection = require('./lib/promise/connection.js');
  10. const PromisePool = require('./lib/promise/pool.js');
  11. const {
  12. captureStackHolder,
  13. applyCapturedStack,
  14. } = require('./lib/promise/capture_local_err.js');
  15. const makeDoneCb = require('./lib/promise/make_done_cb.js');
  16. const PromisePoolConnection = require('./lib/promise/pool_connection.js');
  17. const inheritEvents = require('./lib/promise/inherit_events.js');
  18. const PromisePoolNamespace = require('./lib/promise/pool_cluster');
  19. function createConnectionPromise(opts) {
  20. const coreConnection = createConnection(opts);
  21. const stackHolder = captureStackHolder(createConnectionPromise);
  22. const thePromise = opts.Promise || Promise;
  23. if (!thePromise) {
  24. throw new Error(
  25. 'no Promise implementation available.' +
  26. 'Use promise-enabled node version or pass userland Promise' +
  27. " implementation as parameter, for example: { Promise: require('bluebird') }"
  28. );
  29. }
  30. return new thePromise((resolve, reject) => {
  31. coreConnection.once('connect', () => {
  32. resolve(new PromiseConnection(coreConnection, thePromise));
  33. });
  34. coreConnection.once('error', (err) => {
  35. applyCapturedStack(err, stackHolder);
  36. reject(err);
  37. });
  38. });
  39. }
  40. // note: the callback of "changeUser" is not called on success
  41. // hence there is no possibility to call "resolve"
  42. function createPromisePool(opts) {
  43. const corePool = createPool(opts);
  44. const thePromise = opts.Promise || Promise;
  45. if (!thePromise) {
  46. throw new Error(
  47. 'no Promise implementation available.' +
  48. 'Use promise-enabled node version or pass userland Promise' +
  49. " implementation as parameter, for example: { Promise: require('bluebird') }"
  50. );
  51. }
  52. return new PromisePool(corePool, thePromise);
  53. }
  54. class PromisePoolCluster extends EventEmitter {
  55. constructor(poolCluster, thePromise) {
  56. super();
  57. this.poolCluster = poolCluster;
  58. this.Promise = thePromise || Promise;
  59. inheritEvents(poolCluster, this, ['warn', 'remove', 'online', 'offline']);
  60. }
  61. getConnection(pattern, selector) {
  62. const corePoolCluster = this.poolCluster;
  63. return new this.Promise((resolve, reject) => {
  64. corePoolCluster.getConnection(
  65. pattern,
  66. selector,
  67. (err, coreConnection) => {
  68. if (err) {
  69. reject(err);
  70. } else {
  71. resolve(new PromisePoolConnection(coreConnection, this.Promise));
  72. }
  73. }
  74. );
  75. });
  76. }
  77. query(sql, args) {
  78. const corePoolCluster = this.poolCluster;
  79. const stackHolder = captureStackHolder(PromisePoolCluster.prototype.query);
  80. if (typeof args === 'function') {
  81. throw new Error(
  82. 'Callback function is not available with promise clients.'
  83. );
  84. }
  85. return new this.Promise((resolve, reject) => {
  86. const done = makeDoneCb(resolve, reject, stackHolder);
  87. corePoolCluster.query(sql, args, done);
  88. });
  89. }
  90. execute(sql, args) {
  91. const corePoolCluster = this.poolCluster;
  92. const stackHolder = captureStackHolder(
  93. PromisePoolCluster.prototype.execute
  94. );
  95. if (typeof args === 'function') {
  96. throw new Error(
  97. 'Callback function is not available with promise clients.'
  98. );
  99. }
  100. return new this.Promise((resolve, reject) => {
  101. const done = makeDoneCb(resolve, reject, stackHolder);
  102. corePoolCluster.execute(sql, args, done);
  103. });
  104. }
  105. of(pattern, selector) {
  106. return new PromisePoolNamespace(
  107. this.poolCluster.of(pattern, selector),
  108. this.Promise
  109. );
  110. }
  111. end() {
  112. const corePoolCluster = this.poolCluster;
  113. const stackHolder = captureStackHolder(PromisePoolCluster.prototype.end);
  114. return new this.Promise((resolve, reject) => {
  115. corePoolCluster.end((err) => {
  116. if (err) {
  117. applyCapturedStack(err, stackHolder);
  118. reject(err);
  119. } else {
  120. resolve();
  121. }
  122. });
  123. });
  124. }
  125. async [Symbol.asyncDispose]() {
  126. if (!this.poolCluster._closed) {
  127. await this.end();
  128. }
  129. }
  130. }
  131. /**
  132. * proxy poolCluster synchronous functions
  133. */
  134. (function (functionsToWrap) {
  135. for (let i = 0; functionsToWrap && i < functionsToWrap.length; i++) {
  136. const func = functionsToWrap[i];
  137. if (
  138. typeof PoolCluster.prototype[func] === 'function' &&
  139. PromisePoolCluster.prototype[func] === undefined
  140. ) {
  141. PromisePoolCluster.prototype[func] = (function factory(funcName) {
  142. return function () {
  143. return PoolCluster.prototype[funcName].apply(
  144. this.poolCluster,
  145. arguments
  146. );
  147. };
  148. })(func);
  149. }
  150. }
  151. })(['add', 'remove']);
  152. function createPromisePoolCluster(opts) {
  153. const corePoolCluster = createPoolCluster(opts);
  154. const thePromise = (opts && opts.Promise) || Promise;
  155. if (!thePromise) {
  156. throw new Error(
  157. 'no Promise implementation available.' +
  158. 'Use promise-enabled node version or pass userland Promise' +
  159. " implementation as parameter, for example: { Promise: require('bluebird') }"
  160. );
  161. }
  162. return new PromisePoolCluster(corePoolCluster, thePromise);
  163. }
  164. exports.createConnection = createConnectionPromise;
  165. exports.createPool = createPromisePool;
  166. exports.createPoolCluster = createPromisePoolCluster;
  167. exports.escape = SqlString.escape;
  168. exports.escapeId = SqlString.escapeId;
  169. exports.format = SqlString.format;
  170. exports.raw = SqlString.raw;
  171. exports.Connection = PromiseConnection;
  172. exports.PoolConnection = PromisePoolConnection;
  173. exports.PromisePool = PromisePool;
  174. exports.PromiseConnection = PromiseConnection;
  175. exports.PromisePoolConnection = PromisePoolConnection;
  176. exports.__defineGetter__('Types', () => require('./lib/constants/types.js'));
  177. exports.__defineGetter__('Charsets', () =>
  178. require('./lib/constants/charsets.js')
  179. );
  180. exports.__defineGetter__('CharsetToEncoding', () =>
  181. require('./lib/constants/charset_encodings.js')
  182. );
  183. exports.setMaxParserCache = function (max) {
  184. parserCache.setMaxCache(max);
  185. };
  186. exports.clearParserCache = function () {
  187. parserCache.clearCache();
  188. };