You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.3 KiB

11 months ago
  1. const mssql = require("mssql");
  2. const UrlPattern = require("url-pattern");
  3. class MSSQLConnector {
  4. #connected = false;
  5. database_id = "";
  6. connectionConfig = {
  7. user: null,
  8. password: null,
  9. database: null,
  10. server: null,
  11. port: null,
  12. pool: {
  13. max: 10,
  14. min: 0,
  15. idleTimeoutMillis: 30000,
  16. },
  17. options: {
  18. encrypt: false,
  19. trustServerCertificate: true,
  20. },
  21. };
  22. constructor(
  23. config = {
  24. // we will force into RFC-3986 from DB
  25. // eg: mssql://user:password@server:port/database?{...opts}
  26. connectionString: null, // we will force into RFC-3986
  27. }
  28. ) {
  29. this.connectionString = config.connectionString;
  30. this._client = null;
  31. this.#parseDatabase();
  32. }
  33. #parseDatabase() {
  34. const connectionPattern = new UrlPattern(
  35. "mssql\\://:username\\::password@*\\::port/:database*"
  36. );
  37. const match = connectionPattern.match(this.connectionString);
  38. this.database_id = match?.database;
  39. this.connectionConfig = {
  40. ...this.connectionConfig,
  41. user: match?.username,
  42. password: match?.password,
  43. database: match?.database,
  44. server: match?._[0],
  45. port: match?.port ? Number(match.port) : null,
  46. };
  47. }
  48. async connect() {
  49. this._client = await mssql.connect(this.connectionConfig);
  50. this.#connected = true;
  51. return this._client;
  52. }
  53. /**
  54. *
  55. * @param {string} queryString the SQL query to be run
  56. * @returns {import(".").QueryResult}
  57. */
  58. async runQuery(queryString = "") {
  59. const result = { rows: [], count: 0, error: null };
  60. try {
  61. if (!this.#connected) await this.connect();
  62. const query = await this._client.query(queryString);
  63. result.rows = query.recordset;
  64. result.count = query.rowsAffected.reduce((sum, a) => sum + a, 0);
  65. } catch (err) {
  66. console.log(this.constructor.name, err);
  67. result.error = err.message;
  68. } finally {
  69. await this._client.close();
  70. this.#connected = false;
  71. }
  72. return result;
  73. }
  74. getTablesSql() {
  75. return `SELECT name FROM sysobjects WHERE xtype='U';`;
  76. }
  77. getTableSchemaSql(table_name) {
  78. return `SELECT COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='${table_name}'`;
  79. }
  80. }
  81. module.exports.MSSQLConnector = MSSQLConnector;