request.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _events = require("events");
  7. var _dataType = require("./data-type");
  8. var _errors = require("./errors");
  9. class Request extends _events.EventEmitter {
  10. constructor(sqlTextOrProcedure, callback) {
  11. super();
  12. this.sqlTextOrProcedure = sqlTextOrProcedure;
  13. this.parameters = [];
  14. this.parametersByName = {};
  15. this.originalParameters = [];
  16. this.preparing = false;
  17. this.handle = undefined;
  18. this.canceled = false;
  19. this.paused = false;
  20. this.error = undefined;
  21. this.connection = undefined;
  22. this.timeout = undefined;
  23. this.userCallback = callback;
  24. this.callback = function (err, rowCount, rows) {
  25. if (this.preparing) {
  26. this.preparing = false;
  27. if (err) {
  28. this.emit('error', err);
  29. } else {
  30. this.emit('prepared');
  31. }
  32. } else {
  33. this.userCallback(err, rowCount, rows);
  34. this.emit('requestCompleted');
  35. }
  36. };
  37. } // TODO: `type` must be a valid TDS value type
  38. addParameter(name, type, value, options) {
  39. if (options == null) {
  40. options = {};
  41. }
  42. const _options = options,
  43. _options$output = _options.output,
  44. output = _options$output === void 0 ? false : _options$output,
  45. length = _options.length,
  46. precision = _options.precision,
  47. scale = _options.scale;
  48. const parameter = {
  49. type: type,
  50. name: name,
  51. value: value,
  52. output: output,
  53. length: length,
  54. precision: precision,
  55. scale: scale
  56. };
  57. this.parameters.push(parameter);
  58. this.parametersByName[name] = parameter;
  59. } // TODO: `type` must be a valid TDS value type
  60. addOutputParameter(name, type, value, options) {
  61. if (options == null) {
  62. options = {};
  63. }
  64. options.output = true;
  65. this.addParameter(name, type, value, options);
  66. }
  67. makeParamsParameter(parameters) {
  68. let paramsParameter = '';
  69. for (let i = 0, len = parameters.length; i < len; i++) {
  70. const parameter = parameters[i];
  71. if (paramsParameter.length > 0) {
  72. paramsParameter += ', ';
  73. }
  74. paramsParameter += '@' + parameter.name + ' ';
  75. paramsParameter += parameter.type.declaration(parameter);
  76. if (parameter.output) {
  77. paramsParameter += ' OUTPUT';
  78. }
  79. }
  80. return paramsParameter;
  81. }
  82. transformIntoExecuteSqlRpc() {
  83. if (this.validateParameters()) {
  84. return;
  85. }
  86. this.originalParameters = this.parameters;
  87. this.parameters = [];
  88. this.addParameter('statement', _dataType.typeByName.NVarChar, this.sqlTextOrProcedure);
  89. if (this.originalParameters.length) {
  90. this.addParameter('params', _dataType.typeByName.NVarChar, this.makeParamsParameter(this.originalParameters));
  91. }
  92. for (let i = 0, len = this.originalParameters.length; i < len; i++) {
  93. const parameter = this.originalParameters[i];
  94. this.parameters.push(parameter);
  95. }
  96. this.sqlTextOrProcedure = 'sp_executesql';
  97. }
  98. transformIntoPrepareRpc() {
  99. this.originalParameters = this.parameters;
  100. this.parameters = [];
  101. this.addOutputParameter('handle', _dataType.typeByName.Int, undefined);
  102. this.addParameter('params', _dataType.typeByName.NVarChar, this.makeParamsParameter(this.originalParameters));
  103. this.addParameter('stmt', _dataType.typeByName.NVarChar, this.sqlTextOrProcedure);
  104. this.sqlTextOrProcedure = 'sp_prepare';
  105. this.preparing = true;
  106. this.on('returnValue', (name, value) => {
  107. if (name === 'handle') {
  108. this.handle = value;
  109. } else {
  110. this.error = (0, _errors.RequestError)(`Tedious > Unexpected output parameter ${name} from sp_prepare`);
  111. }
  112. });
  113. }
  114. transformIntoUnprepareRpc() {
  115. this.parameters = [];
  116. this.addParameter('handle', _dataType.typeByName.Int, this.handle);
  117. this.sqlTextOrProcedure = 'sp_unprepare';
  118. }
  119. transformIntoExecuteRpc(parameters) {
  120. this.parameters = [];
  121. this.addParameter('handle', _dataType.typeByName.Int, this.handle);
  122. for (let i = 0, len = this.originalParameters.length; i < len; i++) {
  123. const parameter = this.originalParameters[i];
  124. parameter.value = parameters[parameter.name];
  125. this.parameters.push(parameter);
  126. }
  127. if (this.validateParameters()) {
  128. return;
  129. }
  130. this.sqlTextOrProcedure = 'sp_execute';
  131. }
  132. validateParameters() {
  133. for (let i = 0, len = this.parameters.length; i < len; i++) {
  134. const parameter = this.parameters[i];
  135. const value = parameter.type.validate(parameter.value);
  136. if (value instanceof TypeError) {
  137. return this.error = new _errors.RequestError('Validation failed for parameter \'' + parameter.name + '\'. ' + value.message, 'EPARAM');
  138. }
  139. parameter.value = value;
  140. }
  141. return null;
  142. } // Temporarily suspends the flow of data from the database.
  143. // No more 'row' events will be emitted until resume() is called.
  144. pause() {
  145. if (this.paused) {
  146. return;
  147. }
  148. this.paused = true;
  149. if (this.connection) {
  150. this.connection.pauseRequest(this);
  151. }
  152. } // Resumes the flow of data from the database.
  153. resume() {
  154. if (!this.paused) {
  155. return;
  156. }
  157. this.paused = false;
  158. if (this.connection) {
  159. this.connection.resumeRequest(this);
  160. }
  161. }
  162. cancel() {
  163. if (this.canceled) {
  164. return;
  165. }
  166. this.canceled = true;
  167. this.emit('cancel');
  168. }
  169. setTimeout(timeout) {
  170. this.timeout = timeout;
  171. }
  172. }
  173. var _default = Request;
  174. exports.default = _default;
  175. module.exports = Request;