connection.js 5.6 KB

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