raw.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _isNumber2 = require('lodash/isNumber');
  4. var _isNumber3 = _interopRequireDefault(_isNumber2);
  5. var _isUndefined2 = require('lodash/isUndefined');
  6. var _isUndefined3 = _interopRequireDefault(_isUndefined2);
  7. var _isObject2 = require('lodash/isObject');
  8. var _isObject3 = _interopRequireDefault(_isObject2);
  9. var _isPlainObject2 = require('lodash/isPlainObject');
  10. var _isPlainObject3 = _interopRequireDefault(_isPlainObject2);
  11. var _reduce2 = require('lodash/reduce');
  12. var _reduce3 = _interopRequireDefault(_reduce2);
  13. var _assign2 = require('lodash/assign');
  14. var _assign3 = _interopRequireDefault(_assign2);
  15. var _inherits = require('inherits');
  16. var _inherits2 = _interopRequireDefault(_inherits);
  17. var _helpers = require('./helpers');
  18. var helpers = _interopRequireWildcard(_helpers);
  19. var _events = require('events');
  20. var _debug = require('debug');
  21. var _debug2 = _interopRequireDefault(_debug);
  22. var _formatter = require('./formatter');
  23. var _formatter2 = _interopRequireDefault(_formatter);
  24. var _uuid = require('uuid');
  25. var _uuid2 = _interopRequireDefault(_uuid);
  26. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  27. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  28. // Raw
  29. // -------
  30. var debugBindings = (0, _debug2.default)('knex:bindings');
  31. var fakeClient = {
  32. formatter: function formatter() {
  33. return new _formatter2.default(fakeClient);
  34. }
  35. };
  36. function Raw() {
  37. var client = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : fakeClient;
  38. this.client = client;
  39. this.sql = '';
  40. this.bindings = [];
  41. // Todo: Deprecate
  42. this._wrappedBefore = undefined;
  43. this._wrappedAfter = undefined;
  44. this._debug = client && client.config && client.config.debug;
  45. }
  46. (0, _inherits2.default)(Raw, _events.EventEmitter);
  47. (0, _assign3.default)(Raw.prototype, {
  48. set: function set(sql, bindings) {
  49. this.sql = sql;
  50. this.bindings = (0, _isObject3.default)(bindings) && !bindings.toSQL || (0, _isUndefined3.default)(bindings) ? bindings : [bindings];
  51. return this;
  52. },
  53. timeout: function timeout(ms) {
  54. var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
  55. cancel = _ref.cancel;
  56. if ((0, _isNumber3.default)(ms) && ms > 0) {
  57. this._timeout = ms;
  58. if (cancel) {
  59. this.client.assertCanCancelQuery();
  60. this._cancelOnTimeout = true;
  61. }
  62. }
  63. return this;
  64. },
  65. // Wraps the current sql with `before` and `after`.
  66. wrap: function wrap(before, after) {
  67. this._wrappedBefore = before;
  68. this._wrappedAfter = after;
  69. return this;
  70. },
  71. // Calls `toString` on the Knex object.
  72. toString: function toString() {
  73. return this.toQuery();
  74. },
  75. // Returns the raw sql for the query.
  76. toSQL: function toSQL(method, tz) {
  77. var obj = void 0;
  78. var formatter = this.client.formatter();
  79. if (Array.isArray(this.bindings)) {
  80. obj = replaceRawArrBindings(this, formatter);
  81. } else if (this.bindings && (0, _isPlainObject3.default)(this.bindings)) {
  82. obj = replaceKeyBindings(this, formatter);
  83. } else {
  84. obj = {
  85. method: 'raw',
  86. sql: this.sql,
  87. bindings: (0, _isUndefined3.default)(this.bindings) ? [] : [this.bindings]
  88. };
  89. }
  90. if (this._wrappedBefore) {
  91. obj.sql = this._wrappedBefore + obj.sql;
  92. }
  93. if (this._wrappedAfter) {
  94. obj.sql = obj.sql + this._wrappedAfter;
  95. }
  96. obj.options = (0, _reduce3.default)(this._options, _assign3.default, {});
  97. if (this._timeout) {
  98. obj.timeout = this._timeout;
  99. if (this._cancelOnTimeout) {
  100. obj.cancelOnTimeout = this._cancelOnTimeout;
  101. }
  102. }
  103. obj.bindings = obj.bindings || [];
  104. if (helpers.containsUndefined(obj.bindings)) {
  105. debugBindings(obj.bindings);
  106. throw new Error('Undefined binding(s) detected when compiling RAW query: ' + obj.sql);
  107. }
  108. obj.__knexQueryUid = _uuid2.default.v4();
  109. return obj;
  110. }
  111. });
  112. function replaceRawArrBindings(raw, formatter) {
  113. var expectedBindings = raw.bindings.length;
  114. var values = raw.bindings;
  115. var index = 0;
  116. var sql = raw.sql.replace(/\\?\?\??/g, function (match) {
  117. if (match === '\\?') {
  118. return match;
  119. }
  120. var value = values[index++];
  121. if (match === '??') {
  122. return formatter.columnize(value);
  123. }
  124. return formatter.parameter(value);
  125. });
  126. if (expectedBindings !== index) {
  127. throw new Error('Expected ' + expectedBindings + ' bindings, saw ' + index);
  128. }
  129. return {
  130. method: 'raw',
  131. sql: sql,
  132. bindings: formatter.bindings
  133. };
  134. }
  135. function replaceKeyBindings(raw, formatter) {
  136. var values = raw.bindings;
  137. var sql = raw.sql;
  138. var regex = /\\?(:(\w+):(?=::)|:(\w+):(?!:)|:(\w+))/g;
  139. sql = raw.sql.replace(regex, function (match, p1, p2, p3, p4) {
  140. if (match !== p1) {
  141. return p1;
  142. }
  143. var part = p2 || p3 || p4;
  144. var key = match.trim();
  145. var isIdentifier = key[key.length - 1] === ':';
  146. var value = values[part];
  147. if (value === undefined) {
  148. if (values.hasOwnProperty(part)) {
  149. formatter.bindings.push(value);
  150. }
  151. return match;
  152. }
  153. if (isIdentifier) {
  154. return match.replace(p1, formatter.columnize(value));
  155. }
  156. return match.replace(p1, formatter.parameter(value));
  157. });
  158. return {
  159. method: 'raw',
  160. sql: sql,
  161. bindings: formatter.bindings
  162. };
  163. }
  164. // Allow the `Raw` object to be utilized with full access to the relevant
  165. // promise API.
  166. require('./interface')(Raw);
  167. exports.default = Raw;
  168. module.exports = exports['default'];