connection.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. 'use strict';
  2. const EventEmitter = require('events').EventEmitter;
  3. const PromisePreparedStatementInfo = require('./prepared_statement_info.js');
  4. const {
  5. captureStackHolder,
  6. applyCapturedStack,
  7. } = require('./capture_local_err.js');
  8. const makeDoneCb = require('./make_done_cb.js');
  9. const inheritEvents = require('./inherit_events.js');
  10. const BaseConnection = require('../base/connection.js');
  11. class PromiseConnection extends EventEmitter {
  12. constructor(connection, promiseImpl) {
  13. super();
  14. this.connection = connection;
  15. this.Promise = promiseImpl || Promise;
  16. inheritEvents(connection, this, [
  17. 'error',
  18. 'drain',
  19. 'connect',
  20. 'end',
  21. 'enqueue',
  22. ]);
  23. }
  24. release() {
  25. this.connection.release();
  26. }
  27. query(query, params) {
  28. const c = this.connection;
  29. const stackHolder = captureStackHolder(PromiseConnection.prototype.query);
  30. if (typeof params === 'function') {
  31. throw new Error(
  32. 'Callback function is not available with promise clients.'
  33. );
  34. }
  35. return new this.Promise((resolve, reject) => {
  36. const done = makeDoneCb(resolve, reject, stackHolder);
  37. if (params !== undefined) {
  38. c.query(query, params, done);
  39. } else {
  40. c.query(query, done);
  41. }
  42. });
  43. }
  44. execute(query, params) {
  45. const c = this.connection;
  46. const stackHolder = captureStackHolder(PromiseConnection.prototype.execute);
  47. if (typeof params === 'function') {
  48. throw new Error(
  49. 'Callback function is not available with promise clients.'
  50. );
  51. }
  52. return new this.Promise((resolve, reject) => {
  53. const done = makeDoneCb(resolve, reject, stackHolder);
  54. if (params !== undefined) {
  55. c.execute(query, params, done);
  56. } else {
  57. c.execute(query, done);
  58. }
  59. });
  60. }
  61. end() {
  62. return new this.Promise((resolve) => {
  63. this.connection.end(resolve);
  64. });
  65. }
  66. async [Symbol.asyncDispose]() {
  67. if (!this.connection._closing) {
  68. await this.end();
  69. }
  70. }
  71. beginTransaction() {
  72. const c = this.connection;
  73. const stackHolder = captureStackHolder(
  74. PromiseConnection.prototype.beginTransaction
  75. );
  76. return new this.Promise((resolve, reject) => {
  77. const done = makeDoneCb(resolve, reject, stackHolder);
  78. c.beginTransaction(done);
  79. });
  80. }
  81. commit() {
  82. const c = this.connection;
  83. const stackHolder = captureStackHolder(PromiseConnection.prototype.commit);
  84. return new this.Promise((resolve, reject) => {
  85. const done = makeDoneCb(resolve, reject, stackHolder);
  86. c.commit(done);
  87. });
  88. }
  89. rollback() {
  90. const c = this.connection;
  91. const stackHolder = captureStackHolder(
  92. PromiseConnection.prototype.rollback
  93. );
  94. return new this.Promise((resolve, reject) => {
  95. const done = makeDoneCb(resolve, reject, stackHolder);
  96. c.rollback(done);
  97. });
  98. }
  99. ping() {
  100. const c = this.connection;
  101. const stackHolder = captureStackHolder(PromiseConnection.prototype.ping);
  102. return new this.Promise((resolve, reject) => {
  103. c.ping((err) => {
  104. if (err) {
  105. applyCapturedStack(err, stackHolder);
  106. reject(err);
  107. } else {
  108. resolve(true);
  109. }
  110. });
  111. });
  112. }
  113. reset() {
  114. const c = this.connection;
  115. const stackHolder = captureStackHolder(PromiseConnection.prototype.reset);
  116. return new this.Promise((resolve, reject) => {
  117. c.reset((err) => {
  118. if (err) {
  119. applyCapturedStack(err, stackHolder);
  120. reject(err);
  121. } else {
  122. resolve();
  123. }
  124. });
  125. });
  126. }
  127. connect() {
  128. const c = this.connection;
  129. const stackHolder = captureStackHolder(PromiseConnection.prototype.connect);
  130. return new this.Promise((resolve, reject) => {
  131. c.connect((err, param) => {
  132. if (err) {
  133. applyCapturedStack(err, stackHolder);
  134. reject(err);
  135. } else {
  136. resolve(param);
  137. }
  138. });
  139. });
  140. }
  141. prepare(options) {
  142. const c = this.connection;
  143. const promiseImpl = this.Promise;
  144. const stackHolder = captureStackHolder(PromiseConnection.prototype.prepare);
  145. return new this.Promise((resolve, reject) => {
  146. c.prepare(options, (err, statement) => {
  147. if (err) {
  148. applyCapturedStack(err, stackHolder);
  149. reject(err);
  150. } else {
  151. const wrappedStatement = new PromisePreparedStatementInfo(
  152. statement,
  153. promiseImpl
  154. );
  155. resolve(wrappedStatement);
  156. }
  157. });
  158. });
  159. }
  160. changeUser(options) {
  161. const c = this.connection;
  162. const stackHolder = captureStackHolder(
  163. PromiseConnection.prototype.changeUser
  164. );
  165. return new this.Promise((resolve, reject) => {
  166. c.changeUser(options, (err) => {
  167. if (err) {
  168. applyCapturedStack(err, stackHolder);
  169. reject(err);
  170. } else {
  171. resolve();
  172. }
  173. });
  174. });
  175. }
  176. get config() {
  177. return this.connection.config;
  178. }
  179. get threadId() {
  180. return this.connection.threadId;
  181. }
  182. }
  183. // patching PromiseConnection
  184. // create facade functions for prototype functions on "Connection" that are not yet
  185. // implemented with PromiseConnection
  186. // proxy synchronous functions only
  187. (function (functionsToWrap) {
  188. for (let i = 0; functionsToWrap && i < functionsToWrap.length; i++) {
  189. const func = functionsToWrap[i];
  190. if (
  191. typeof BaseConnection.prototype[func] === 'function' &&
  192. PromiseConnection.prototype[func] === undefined
  193. ) {
  194. PromiseConnection.prototype[func] = (function factory(funcName) {
  195. return function () {
  196. return BaseConnection.prototype[funcName].apply(
  197. this.connection,
  198. arguments
  199. );
  200. };
  201. })(func);
  202. }
  203. }
  204. })([
  205. // synchronous functions
  206. 'close',
  207. 'createBinlogStream',
  208. 'destroy',
  209. 'escape',
  210. 'escapeId',
  211. 'format',
  212. 'pause',
  213. 'pipe',
  214. 'resume',
  215. 'unprepare',
  216. ]);
  217. module.exports = PromiseConnection;