compiler.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _keys = require('babel-runtime/core-js/object/keys');
  4. var _keys2 = _interopRequireDefault(_keys);
  5. var _typeof2 = require('babel-runtime/helpers/typeof');
  6. var _typeof3 = _interopRequireDefault(_typeof2);
  7. var _reduce2 = require('lodash/reduce');
  8. var _reduce3 = _interopRequireDefault(_reduce2);
  9. var _omitBy2 = require('lodash/omitBy');
  10. var _omitBy3 = _interopRequireDefault(_omitBy2);
  11. var _map2 = require('lodash/map');
  12. var _map3 = _interopRequireDefault(_map2);
  13. var _isUndefined2 = require('lodash/isUndefined');
  14. var _isUndefined3 = _interopRequireDefault(_isUndefined2);
  15. var _isString2 = require('lodash/isString');
  16. var _isString3 = _interopRequireDefault(_isString2);
  17. var _isEmpty2 = require('lodash/isEmpty');
  18. var _isEmpty3 = _interopRequireDefault(_isEmpty2);
  19. var _groupBy2 = require('lodash/groupBy');
  20. var _groupBy3 = _interopRequireDefault(_groupBy2);
  21. var _compact2 = require('lodash/compact');
  22. var _compact3 = _interopRequireDefault(_compact2);
  23. var _bind2 = require('lodash/bind');
  24. var _bind3 = _interopRequireDefault(_bind2);
  25. var _assign2 = require('lodash/assign');
  26. var _assign3 = _interopRequireDefault(_assign2);
  27. var _helpers = require('../helpers');
  28. var helpers = _interopRequireWildcard(_helpers);
  29. var _raw = require('../raw');
  30. var _raw2 = _interopRequireDefault(_raw);
  31. var _joinclause = require('./joinclause');
  32. var _joinclause2 = _interopRequireDefault(_joinclause);
  33. var _debug = require('debug');
  34. var _debug2 = _interopRequireDefault(_debug);
  35. var _uuid = require('uuid');
  36. var _uuid2 = _interopRequireDefault(_uuid);
  37. 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; } }
  38. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  39. var debugBindings = (0, _debug2.default)('knex:bindings');
  40. // The "QueryCompiler" takes all of the query statements which
  41. // have been gathered in the "QueryBuilder" and turns them into a
  42. // properly formatted / bound query string.
  43. // Query Compiler
  44. // -------
  45. function QueryCompiler(client, builder) {
  46. this.client = client;
  47. this.method = builder._method || 'select';
  48. this.options = builder._options;
  49. this.single = builder._single;
  50. this.timeout = builder._timeout || false;
  51. this.cancelOnTimeout = builder._cancelOnTimeout || false;
  52. this.grouped = (0, _groupBy3.default)(builder._statements, 'grouping');
  53. this.formatter = client.formatter();
  54. }
  55. var components = ['columns', 'join', 'where', 'union', 'group', 'having', 'order', 'limit', 'offset', 'lock'];
  56. (0, _assign3.default)(QueryCompiler.prototype, {
  57. // Used when the insert call is empty.
  58. _emptyInsertValue: 'default values',
  59. // Collapse the builder into a single object
  60. toSQL: function toSQL(method, tz) {
  61. this._undefinedInWhereClause = false;
  62. method = method || this.method;
  63. var val = this[method]();
  64. var defaults = {
  65. method: method,
  66. options: (0, _reduce3.default)(this.options, _assign3.default, {}),
  67. timeout: this.timeout,
  68. cancelOnTimeout: this.cancelOnTimeout,
  69. bindings: this.formatter.bindings,
  70. __knexQueryUid: _uuid2.default.v4()
  71. };
  72. if ((0, _isString3.default)(val)) {
  73. val = { sql: val };
  74. }
  75. defaults.bindings = defaults.bindings || [];
  76. if (method === 'select' || method === 'first') {
  77. if (this.single.as) {
  78. defaults.as = this.single.as;
  79. }
  80. }
  81. if (this._undefinedInWhereClause) {
  82. debugBindings(defaults.bindings);
  83. throw new Error('Undefined binding(s) detected when compiling ' + (method.toUpperCase() + ' query: ' + val.sql));
  84. }
  85. return (0, _assign3.default)(defaults, val);
  86. },
  87. // Compiles the `select` statement, or nested sub-selects by calling each of
  88. // the component compilers, trimming out the empties, and returning a
  89. // generated query string.
  90. select: function select() {
  91. var _this = this;
  92. var sql = this.with();
  93. var statements = components.map(function (component) {
  94. return _this[component](_this);
  95. });
  96. sql += (0, _compact3.default)(statements).join(' ');
  97. return sql;
  98. },
  99. pluck: function pluck() {
  100. var toPluck = this.single.pluck;
  101. if (toPluck.indexOf('.') !== -1) {
  102. toPluck = toPluck.split('.').slice(-1)[0];
  103. }
  104. return {
  105. sql: this.select(),
  106. pluck: toPluck
  107. };
  108. },
  109. // Compiles an "insert" query, allowing for multiple
  110. // inserts using a single query statement.
  111. insert: function insert() {
  112. var insertValues = this.single.insert || [];
  113. var sql = this.with() + ('insert into ' + this.tableName + ' ');
  114. if (Array.isArray(insertValues)) {
  115. if (insertValues.length === 0) {
  116. return '';
  117. }
  118. } else if ((typeof insertValues === 'undefined' ? 'undefined' : (0, _typeof3.default)(insertValues)) === 'object' && (0, _isEmpty3.default)(insertValues)) {
  119. return sql + this._emptyInsertValue;
  120. }
  121. var insertData = this._prepInsert(insertValues);
  122. if (typeof insertData === 'string') {
  123. sql += insertData;
  124. } else {
  125. if (insertData.columns.length) {
  126. sql += '(' + this.formatter.columnize(insertData.columns);
  127. sql += ') values (';
  128. var i = -1;
  129. while (++i < insertData.values.length) {
  130. if (i !== 0) sql += '), (';
  131. sql += this.formatter.parameterize(insertData.values[i], this.client.valueForUndefined);
  132. }
  133. sql += ')';
  134. } else if (insertValues.length === 1 && insertValues[0]) {
  135. sql += this._emptyInsertValue;
  136. } else {
  137. sql = '';
  138. }
  139. }
  140. return sql;
  141. },
  142. // Compiles the "update" query.
  143. update: function update() {
  144. // Make sure tableName is processed by the formatter first.
  145. var tableName = this.tableName;
  146. var updateData = this._prepUpdate(this.single.update);
  147. var wheres = this.where();
  148. return this.with() + ('update ' + (this.single.only ? 'only ' : '') + tableName) + ' set ' + updateData.join(', ') + (wheres ? ' ' + wheres : '');
  149. },
  150. // Compiles the columns in the query, specifying if an item was distinct.
  151. columns: function columns() {
  152. var distinct = false;
  153. if (this.onlyUnions()) return '';
  154. var columns = this.grouped.columns || [];
  155. var i = -1,
  156. sql = [];
  157. if (columns) {
  158. while (++i < columns.length) {
  159. var stmt = columns[i];
  160. if (stmt.distinct) distinct = true;
  161. if (stmt.type === 'aggregate') {
  162. sql.push(this.aggregate(stmt));
  163. } else if (stmt.value && stmt.value.length > 0) {
  164. sql.push(this.formatter.columnize(stmt.value));
  165. }
  166. }
  167. }
  168. if (sql.length === 0) sql = ['*'];
  169. return 'select ' + (distinct ? 'distinct ' : '') + sql.join(', ') + (this.tableName ? ' from ' + (this.single.only ? 'only ' : '') + this.tableName : '');
  170. },
  171. aggregate: function aggregate(stmt) {
  172. var val = stmt.value;
  173. var splitOn = val.toLowerCase().indexOf(' as ');
  174. var distinct = stmt.aggregateDistinct ? 'distinct ' : '';
  175. // Allows us to speciy an alias for the aggregate types.
  176. if (splitOn !== -1) {
  177. var col = val.slice(0, splitOn);
  178. var alias = val.slice(splitOn + 4);
  179. return stmt.method + '(' + (distinct + this.formatter.wrap(col)) + ') ' + ('as ' + this.formatter.wrap(alias));
  180. }
  181. return stmt.method + '(' + (distinct + this.formatter.wrap(val)) + ')';
  182. },
  183. // Compiles all each of the `join` clauses on the query,
  184. // including any nested join queries.
  185. join: function join() {
  186. var sql = '';
  187. var i = -1;
  188. var joins = this.grouped.join;
  189. if (!joins) return '';
  190. while (++i < joins.length) {
  191. var join = joins[i];
  192. var table = join.schema ? join.schema + '.' + join.table : join.table;
  193. if (i > 0) sql += ' ';
  194. if (join.joinType === 'raw') {
  195. sql += this.formatter.unwrapRaw(join.table);
  196. } else {
  197. sql += join.joinType + ' join ' + this.formatter.wrap(table);
  198. var ii = -1;
  199. while (++ii < join.clauses.length) {
  200. var clause = join.clauses[ii];
  201. if (ii > 0) {
  202. sql += ' ' + clause.bool + ' ';
  203. } else {
  204. sql += ' ' + (clause.type === 'onUsing' ? 'using' : 'on') + ' ';
  205. }
  206. var val = this[clause.type].call(this, clause);
  207. if (val) {
  208. sql += val;
  209. }
  210. }
  211. }
  212. }
  213. return sql;
  214. },
  215. onBetween: function onBetween(statement) {
  216. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'between') + ' ' + (0, _map3.default)(statement.value, (0, _bind3.default)(this.formatter.parameter, this.formatter)).join(' and ');
  217. },
  218. onNull: function onNull(statement) {
  219. return this.formatter.wrap(statement.column) + ' is ' + this._not(statement, 'null');
  220. },
  221. onExists: function onExists(statement) {
  222. return this._not(statement, 'exists') + ' (' + this.formatter.rawOrFn(statement.value) + ')';
  223. },
  224. onIn: function onIn(statement) {
  225. if (Array.isArray(statement.column)) return this.multiOnIn(statement);
  226. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'in ') + this.wrap(this.formatter.parameterize(statement.value));
  227. },
  228. multiOnIn: function multiOnIn(statement) {
  229. var i = -1,
  230. sql = '(' + this.formatter.columnize(statement.column) + ') ';
  231. sql += this._not(statement, 'in ') + '((';
  232. while (++i < statement.value.length) {
  233. if (i !== 0) sql += '),(';
  234. sql += this.formatter.parameterize(statement.value[i]);
  235. }
  236. return sql + '))';
  237. },
  238. // Compiles all `where` statements on the query.
  239. where: function where() {
  240. var wheres = this.grouped.where;
  241. if (!wheres) return;
  242. var sql = [];
  243. var i = -1;
  244. while (++i < wheres.length) {
  245. var stmt = wheres[i];
  246. if (stmt.hasOwnProperty('value') && helpers.containsUndefined(stmt.value)) {
  247. this._undefinedInWhereClause = true;
  248. }
  249. var val = this[stmt.type](stmt);
  250. if (val) {
  251. if (sql.length === 0) {
  252. sql[0] = 'where';
  253. } else {
  254. sql.push(stmt.bool);
  255. }
  256. sql.push(val);
  257. }
  258. }
  259. return sql.length > 1 ? sql.join(' ') : '';
  260. },
  261. group: function group() {
  262. return this._groupsOrders('group');
  263. },
  264. order: function order() {
  265. return this._groupsOrders('order');
  266. },
  267. // Compiles the `having` statements.
  268. having: function having() {
  269. var havings = this.grouped.having;
  270. if (!havings) return '';
  271. var sql = ['having'];
  272. for (var i = 0, l = havings.length; i < l; i++) {
  273. var s = havings[i];
  274. var val = this[s.type](s);
  275. if (val) {
  276. if (sql.length === 0) {
  277. sql[0] = 'where';
  278. }
  279. if (sql.length > 1 || sql.length === 1 && sql[0] !== 'having') {
  280. sql.push(s.bool);
  281. }
  282. sql.push(val);
  283. }
  284. }
  285. return sql.length > 1 ? sql.join(' ') : '';
  286. },
  287. havingRaw: function havingRaw(statement) {
  288. return this._not(statement, '') + this.formatter.unwrapRaw(statement.value);
  289. },
  290. havingWrapped: function havingWrapped(statement) {
  291. var val = this.formatter.rawOrFn(statement.value, 'where');
  292. return val && this._not(statement, '') + '(' + val.slice(6) + ')' || '';
  293. },
  294. havingBasic: function havingBasic(statement) {
  295. return this._not(statement, '') + this.formatter.wrap(statement.column) + ' ' + this.formatter.operator(statement.operator) + ' ' + this.formatter.parameter(statement.value);
  296. },
  297. havingNull: function havingNull(statement) {
  298. return this.formatter.wrap(statement.column) + ' is ' + this._not(statement, 'null');
  299. },
  300. havingExists: function havingExists(statement) {
  301. return this._not(statement, 'exists') + ' (' + this.formatter.rawOrFn(statement.value) + ')';
  302. },
  303. havingBetween: function havingBetween(statement) {
  304. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'between') + ' ' + (0, _map3.default)(statement.value, (0, _bind3.default)(this.formatter.parameter, this.formatter)).join(' and ');
  305. },
  306. havingIn: function havingIn(statement) {
  307. if (Array.isArray(statement.column)) return this.multiHavingIn(statement);
  308. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'in ') + this.wrap(this.formatter.parameterize(statement.value));
  309. },
  310. multiHavingIn: function multiHavingIn(statement) {
  311. var i = -1,
  312. sql = '(' + this.formatter.columnize(statement.column) + ') ';
  313. sql += this._not(statement, 'in ') + '((';
  314. while (++i < statement.value.length) {
  315. if (i !== 0) sql += '),(';
  316. sql += this.formatter.parameterize(statement.value[i]);
  317. }
  318. return sql + '))';
  319. },
  320. // Compile the "union" queries attached to the main query.
  321. union: function union() {
  322. var onlyUnions = this.onlyUnions();
  323. var unions = this.grouped.union;
  324. if (!unions) return '';
  325. var sql = '';
  326. for (var i = 0, l = unions.length; i < l; i++) {
  327. var union = unions[i];
  328. if (i > 0) sql += ' ';
  329. if (i > 0 || !onlyUnions) sql += union.clause + ' ';
  330. var statement = this.formatter.rawOrFn(union.value);
  331. if (statement) {
  332. if (union.wrap) sql += '(';
  333. sql += statement;
  334. if (union.wrap) sql += ')';
  335. }
  336. }
  337. return sql;
  338. },
  339. // If we haven't specified any columns or a `tableName`, we're assuming this
  340. // is only being used for unions.
  341. onlyUnions: function onlyUnions() {
  342. return !this.grouped.columns && this.grouped.union && !this.tableName;
  343. },
  344. limit: function limit() {
  345. var noLimit = !this.single.limit && this.single.limit !== 0;
  346. if (noLimit) return '';
  347. return 'limit ' + this.formatter.parameter(this.single.limit);
  348. },
  349. offset: function offset() {
  350. if (!this.single.offset) return '';
  351. return 'offset ' + this.formatter.parameter(this.single.offset);
  352. },
  353. // Compiles a `delete` query.
  354. del: function del() {
  355. // Make sure tableName is processed by the formatter first.
  356. var tableName = this.tableName;
  357. var wheres = this.where();
  358. return this.with() + ('delete from ' + (this.single.only ? 'only ' : '') + tableName) + (wheres ? ' ' + wheres : '');
  359. },
  360. // Compiles a `truncate` query.
  361. truncate: function truncate() {
  362. return 'truncate ' + this.tableName;
  363. },
  364. // Compiles the "locks".
  365. lock: function lock() {
  366. if (this.single.lock) {
  367. if (!this.client.transacting) {
  368. helpers.warn('You are attempting to perform a "lock" command outside of a transaction.');
  369. } else {
  370. return this[this.single.lock]();
  371. }
  372. }
  373. },
  374. // Compile the "counter".
  375. counter: function counter() {
  376. var counter = this.single.counter;
  377. var toUpdate = {};
  378. toUpdate[counter.column] = this.client.raw(this.formatter.wrap(counter.column) + ' ' + (counter.symbol || '+') + ' ' + counter.amount);
  379. this.single.update = toUpdate;
  380. return this.update();
  381. },
  382. // On Clause
  383. // ------
  384. onWrapped: function onWrapped(clause) {
  385. var self = this;
  386. var wrapJoin = new _joinclause2.default();
  387. clause.value.call(wrapJoin, wrapJoin);
  388. var sql = '';
  389. wrapJoin.clauses.forEach(function (wrapClause, ii) {
  390. if (ii > 0) {
  391. sql += ' ' + wrapClause.bool + ' ';
  392. }
  393. var val = self[wrapClause.type](wrapClause);
  394. if (val) {
  395. sql += val;
  396. }
  397. });
  398. if (sql.length) {
  399. return '(' + sql + ')';
  400. }
  401. return '';
  402. },
  403. onBasic: function onBasic(clause) {
  404. return this.formatter.wrap(clause.column) + ' ' + this.formatter.operator(clause.operator) + ' ' + this.formatter.wrap(clause.value);
  405. },
  406. onRaw: function onRaw(clause) {
  407. return this.formatter.unwrapRaw(clause.value);
  408. },
  409. onUsing: function onUsing(clause) {
  410. return this.formatter.wrap(clause.column);
  411. },
  412. // Where Clause
  413. // ------
  414. whereIn: function whereIn(statement) {
  415. if (Array.isArray(statement.column)) return this.multiWhereIn(statement);
  416. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'in ') + this.wrap(this.formatter.parameterize(statement.value));
  417. },
  418. multiWhereIn: function multiWhereIn(statement) {
  419. var i = -1,
  420. sql = '(' + this.formatter.columnize(statement.column) + ') ';
  421. sql += this._not(statement, 'in ') + '((';
  422. while (++i < statement.value.length) {
  423. if (i !== 0) sql += '),(';
  424. sql += this.formatter.parameterize(statement.value[i]);
  425. }
  426. return sql + '))';
  427. },
  428. whereNull: function whereNull(statement) {
  429. return this.formatter.wrap(statement.column) + ' is ' + this._not(statement, 'null');
  430. },
  431. // Compiles a basic "where" clause.
  432. whereBasic: function whereBasic(statement) {
  433. return this._not(statement, '') + this.formatter.wrap(statement.column) + ' ' + this.formatter.operator(statement.operator) + ' ' + this.formatter.parameter(statement.value);
  434. },
  435. whereExists: function whereExists(statement) {
  436. return this._not(statement, 'exists') + ' (' + this.formatter.rawOrFn(statement.value) + ')';
  437. },
  438. whereWrapped: function whereWrapped(statement) {
  439. var val = this.formatter.rawOrFn(statement.value, 'where');
  440. return val && this._not(statement, '') + '(' + val.slice(6) + ')' || '';
  441. },
  442. whereBetween: function whereBetween(statement) {
  443. return this.formatter.wrap(statement.column) + ' ' + this._not(statement, 'between') + ' ' + (0, _map3.default)(statement.value, (0, _bind3.default)(this.formatter.parameter, this.formatter)).join(' and ');
  444. },
  445. // Compiles a "whereRaw" query.
  446. whereRaw: function whereRaw(statement) {
  447. return this._not(statement, '') + this.formatter.unwrapRaw(statement.value);
  448. },
  449. wrap: function wrap(str) {
  450. if (str.charAt(0) !== '(') return '(' + str + ')';
  451. return str;
  452. },
  453. // Compiles all `with` statements on the query.
  454. with: function _with() {
  455. if (!this.grouped.with || !this.grouped.with.length) {
  456. return '';
  457. }
  458. var withs = this.grouped.with;
  459. if (!withs) return;
  460. var sql = [];
  461. var i = -1;
  462. while (++i < withs.length) {
  463. var stmt = withs[i];
  464. var val = this[stmt.type](stmt);
  465. sql.push(val);
  466. }
  467. return 'with ' + sql.join(', ') + ' ';
  468. },
  469. withWrapped: function withWrapped(statement) {
  470. var val = this.formatter.rawOrFn(statement.value);
  471. return val && this.formatter.columnize(statement.alias) + ' as (' + val + ')' || '';
  472. },
  473. withRaw: function withRaw(statement) {
  474. return this.formatter.columnize(statement.alias) + ' as (' + this.formatter.unwrapRaw(statement.value) + ')';
  475. },
  476. // Determines whether to add a "not" prefix to the where clause.
  477. _not: function _not(statement, str) {
  478. if (statement.not) return 'not ' + str;
  479. return str;
  480. },
  481. _prepInsert: function _prepInsert(data) {
  482. var isRaw = this.formatter.rawOrFn(data);
  483. if (isRaw) return isRaw;
  484. var columns = [];
  485. var values = [];
  486. if (!Array.isArray(data)) data = data ? [data] : [];
  487. var i = -1;
  488. while (++i < data.length) {
  489. if (data[i] == null) break;
  490. if (i === 0) columns = (0, _keys2.default)(data[i]).sort();
  491. var row = new Array(columns.length);
  492. var keys = (0, _keys2.default)(data[i]);
  493. var j = -1;
  494. while (++j < keys.length) {
  495. var key = keys[j];
  496. var idx = columns.indexOf(key);
  497. if (idx === -1) {
  498. columns = columns.concat(key).sort();
  499. idx = columns.indexOf(key);
  500. var k = -1;
  501. while (++k < values.length) {
  502. values[k].splice(idx, 0, undefined);
  503. }
  504. row.splice(idx, 0, undefined);
  505. }
  506. row[idx] = data[i][key];
  507. }
  508. values.push(row);
  509. }
  510. return {
  511. columns: columns,
  512. values: values
  513. };
  514. },
  515. // "Preps" the update.
  516. _prepUpdate: function _prepUpdate(data) {
  517. data = (0, _omitBy3.default)(data, _isUndefined3.default);
  518. var vals = [];
  519. var sorted = (0, _keys2.default)(data).sort();
  520. var i = -1;
  521. while (++i < sorted.length) {
  522. vals.push(this.formatter.wrap(sorted[i]) + ' = ' + this.formatter.parameter(data[sorted[i]]));
  523. }
  524. return vals;
  525. },
  526. // Compiles the `order by` statements.
  527. _groupsOrders: function _groupsOrders(type) {
  528. var items = this.grouped[type];
  529. if (!items) return '';
  530. var formatter = this.formatter;
  531. var sql = items.map(function (item) {
  532. var column = item.value instanceof _raw2.default ? formatter.unwrapRaw(item.value) : formatter.columnize(item.value);
  533. var direction = type === 'order' && item.type !== 'orderByRaw' ? ' ' + formatter.direction(item.direction) : '';
  534. return column + direction;
  535. });
  536. return sql.length ? type + ' by ' + sql.join(', ') : '';
  537. }
  538. });
  539. QueryCompiler.prototype.first = QueryCompiler.prototype.select;
  540. // Get the table name, wrapping it if necessary.
  541. // Implemented as a property to prevent ordering issues as described in #704.
  542. Object.defineProperty(QueryCompiler.prototype, 'tableName', {
  543. get: function get() {
  544. if (!this._tableName) {
  545. // Only call this.formatter.wrap() the first time this property is accessed.
  546. var tableName = this.single.table;
  547. var schemaName = this.single.schema;
  548. if (tableName && schemaName) tableName = schemaName + '.' + tableName;
  549. this._tableName = tableName ? this.formatter.wrap(tableName) : '';
  550. }
  551. return this._tableName;
  552. }
  553. });
  554. exports.default = QueryCompiler;
  555. module.exports = exports['default'];