connection-manager.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. "use strict";
  2. const AbstractConnectionManager = require("../abstract/connection-manager");
  3. const AsyncQueue = require("./async-queue").default;
  4. const { logger } = require("../../utils/logger");
  5. const sequelizeErrors = require("../../errors");
  6. const DataTypes = require("../../data-types").mssql;
  7. const parserStore = require("../parserStore")("mssql");
  8. const debug = logger.debugContext("connection:mssql");
  9. const debugTedious = logger.debugContext("connection:mssql:tedious");
  10. class ConnectionManager extends AbstractConnectionManager {
  11. constructor(dialect, sequelize) {
  12. sequelize.config.port = sequelize.config.port || 1433;
  13. super(dialect, sequelize);
  14. this.lib = this._loadDialectModule("tedious");
  15. this.refreshTypeParser(DataTypes);
  16. }
  17. _refreshTypeParser(dataType) {
  18. parserStore.refresh(dataType);
  19. }
  20. _clearTypeParser() {
  21. parserStore.clear();
  22. }
  23. async connect(config) {
  24. const connectionConfig = {
  25. server: config.host,
  26. authentication: {
  27. type: "default",
  28. options: {
  29. userName: config.username || void 0,
  30. password: config.password || void 0
  31. }
  32. },
  33. options: {
  34. port: parseInt(config.port, 10),
  35. database: config.database,
  36. trustServerCertificate: true
  37. }
  38. };
  39. if (config.dialectOptions) {
  40. if (config.dialectOptions.options && config.dialectOptions.options.instanceName) {
  41. delete connectionConfig.options.port;
  42. }
  43. if (config.dialectOptions.authentication) {
  44. Object.assign(connectionConfig.authentication, config.dialectOptions.authentication);
  45. }
  46. Object.assign(connectionConfig.options, config.dialectOptions.options);
  47. }
  48. try {
  49. return await new Promise((resolve, reject) => {
  50. const connection = new this.lib.Connection(connectionConfig);
  51. if (connection.state === connection.STATE.INITIALIZED) {
  52. connection.connect();
  53. }
  54. connection.queue = new AsyncQueue();
  55. connection.lib = this.lib;
  56. const connectHandler = (error) => {
  57. connection.removeListener("end", endHandler);
  58. connection.removeListener("error", errorHandler);
  59. if (error)
  60. return reject(error);
  61. debug("connection acquired");
  62. resolve(connection);
  63. };
  64. const endHandler = () => {
  65. connection.removeListener("connect", connectHandler);
  66. connection.removeListener("error", errorHandler);
  67. reject(new Error("Connection was closed by remote server"));
  68. };
  69. const errorHandler = (error) => {
  70. connection.removeListener("connect", connectHandler);
  71. connection.removeListener("end", endHandler);
  72. reject(error);
  73. };
  74. connection.once("error", errorHandler);
  75. connection.once("end", endHandler);
  76. connection.once("connect", connectHandler);
  77. connection.on("error", (error) => {
  78. switch (error.code) {
  79. case "ESOCKET":
  80. case "ECONNRESET":
  81. this.pool.destroy(connection);
  82. }
  83. });
  84. if (config.dialectOptions && config.dialectOptions.debug) {
  85. connection.on("debug", debugTedious.log.bind(debugTedious));
  86. }
  87. });
  88. } catch (error) {
  89. if (!error.code) {
  90. throw new sequelizeErrors.ConnectionError(error);
  91. }
  92. switch (error.code) {
  93. case "ESOCKET":
  94. if (error.message.includes("connect EHOSTUNREACH")) {
  95. throw new sequelizeErrors.HostNotReachableError(error);
  96. }
  97. if (error.message.includes("connect ENETUNREACH")) {
  98. throw new sequelizeErrors.HostNotReachableError(error);
  99. }
  100. if (error.message.includes("connect EADDRNOTAVAIL")) {
  101. throw new sequelizeErrors.HostNotReachableError(error);
  102. }
  103. if (error.message.includes("connect EAFNOSUPPORT")) {
  104. throw new sequelizeErrors.HostNotReachableError(error);
  105. }
  106. if (error.message.includes("getaddrinfo ENOTFOUND")) {
  107. throw new sequelizeErrors.HostNotFoundError(error);
  108. }
  109. if (error.message.includes("connect ECONNREFUSED")) {
  110. throw new sequelizeErrors.ConnectionRefusedError(error);
  111. }
  112. throw new sequelizeErrors.ConnectionError(error);
  113. case "ER_ACCESS_DENIED_ERROR":
  114. case "ELOGIN":
  115. throw new sequelizeErrors.AccessDeniedError(error);
  116. case "EINVAL":
  117. throw new sequelizeErrors.InvalidConnectionError(error);
  118. default:
  119. throw new sequelizeErrors.ConnectionError(error);
  120. }
  121. }
  122. }
  123. async disconnect(connection) {
  124. if (connection.closed) {
  125. return;
  126. }
  127. connection.queue.close();
  128. return new Promise((resolve) => {
  129. connection.on("end", resolve);
  130. connection.close();
  131. debug("connection closed");
  132. });
  133. }
  134. validate(connection) {
  135. return connection && (connection.loggedIn || connection.state.name === "LoggedIn");
  136. }
  137. }
  138. module.exports = ConnectionManager;
  139. module.exports.ConnectionManager = ConnectionManager;
  140. module.exports.default = ConnectionManager;
  141. //# sourceMappingURL=connection-manager.js.map