query.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  6. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  7. var __spreadValues = (a, b) => {
  8. for (var prop in b || (b = {}))
  9. if (__hasOwnProp.call(b, prop))
  10. __defNormalProp(a, prop, b[prop]);
  11. if (__getOwnPropSymbols)
  12. for (var prop of __getOwnPropSymbols(b)) {
  13. if (__propIsEnum.call(b, prop))
  14. __defNormalProp(a, prop, b[prop]);
  15. }
  16. return a;
  17. };
  18. const _ = require("lodash");
  19. const SqlString = require("../../sql-string");
  20. const QueryTypes = require("../../query-types");
  21. const Dot = require("dottie");
  22. const deprecations = require("../../utils/deprecations");
  23. const uuid = require("uuid").v4;
  24. const { safeStringifyJson } = require("../../utils.js");
  25. class AbstractQuery {
  26. constructor(connection, sequelize, options) {
  27. this.uuid = uuid();
  28. this.connection = connection;
  29. this.instance = options.instance;
  30. this.model = options.model;
  31. this.sequelize = sequelize;
  32. this.options = __spreadValues({
  33. plain: false,
  34. raw: false,
  35. logging: console.log
  36. }, options);
  37. this.checkLoggingOption();
  38. if (options.rawErrors) {
  39. this.formatError = AbstractQuery.prototype.formatError;
  40. }
  41. }
  42. static formatBindParameters(sql, values, dialect, replacementFunc, options) {
  43. if (!values) {
  44. return [sql, []];
  45. }
  46. options = options || {};
  47. if (typeof replacementFunc !== "function") {
  48. options = replacementFunc || {};
  49. replacementFunc = void 0;
  50. }
  51. if (!replacementFunc) {
  52. if (options.skipValueReplace) {
  53. replacementFunc = (match, key, values2) => {
  54. if (values2[key] !== void 0) {
  55. return match;
  56. }
  57. return void 0;
  58. };
  59. } else {
  60. replacementFunc = (match, key, values2, timeZone2, dialect2) => {
  61. if (values2[key] !== void 0) {
  62. return SqlString.escape(values2[key], timeZone2, dialect2);
  63. }
  64. return void 0;
  65. };
  66. }
  67. } else if (options.skipValueReplace) {
  68. const origReplacementFunc = replacementFunc;
  69. replacementFunc = (match, key, values2, timeZone2, dialect2, options2) => {
  70. if (origReplacementFunc(match, key, values2, timeZone2, dialect2, options2) !== void 0) {
  71. return match;
  72. }
  73. return void 0;
  74. };
  75. }
  76. const timeZone = null;
  77. const list = Array.isArray(values);
  78. sql = sql.replace(/\B\$(\$|\w+)/g, (match, key) => {
  79. if (key === "$") {
  80. return options.skipUnescape ? match : key;
  81. }
  82. let replVal;
  83. if (list) {
  84. if (key.match(/^[1-9]\d*$/)) {
  85. key = key - 1;
  86. replVal = replacementFunc(match, key, values, timeZone, dialect, options);
  87. }
  88. } else if (!key.match(/^\d*$/)) {
  89. replVal = replacementFunc(match, key, values, timeZone, dialect, options);
  90. }
  91. if (replVal === void 0) {
  92. throw new Error(`Named bind parameter "${match}" has no value in the given object.`);
  93. }
  94. return replVal;
  95. });
  96. return [sql, []];
  97. }
  98. formatError(error, errStack) {
  99. error.stack = errStack;
  100. return error;
  101. }
  102. run() {
  103. throw new Error("The run method wasn't overwritten!");
  104. }
  105. checkLoggingOption() {
  106. if (this.options.logging === true) {
  107. deprecations.noTrueLogging();
  108. this.options.logging = console.log;
  109. }
  110. }
  111. getInsertIdField() {
  112. return "insertId";
  113. }
  114. getUniqueConstraintErrorMessage(field) {
  115. let message = field ? `${field} must be unique` : "Must be unique";
  116. if (field && this.model) {
  117. for (const key of Object.keys(this.model.uniqueKeys)) {
  118. if (this.model.uniqueKeys[key].fields.includes(field.replace(/"/g, ""))) {
  119. if (this.model.uniqueKeys[key].msg) {
  120. message = this.model.uniqueKeys[key].msg;
  121. }
  122. }
  123. }
  124. }
  125. return message;
  126. }
  127. isRawQuery() {
  128. return this.options.type === QueryTypes.RAW;
  129. }
  130. isVersionQuery() {
  131. return this.options.type === QueryTypes.VERSION;
  132. }
  133. isUpsertQuery() {
  134. return this.options.type === QueryTypes.UPSERT;
  135. }
  136. isInsertQuery(results, metaData) {
  137. let result = true;
  138. if (this.options.type === QueryTypes.INSERT) {
  139. return true;
  140. }
  141. result = result && this.sql.toLowerCase().startsWith("insert into");
  142. result = result && (!results || Object.prototype.hasOwnProperty.call(results, this.getInsertIdField()));
  143. result = result && (!metaData || Object.prototype.hasOwnProperty.call(metaData, this.getInsertIdField()));
  144. return result;
  145. }
  146. handleInsertQuery(results, metaData) {
  147. if (this.instance) {
  148. const autoIncrementAttribute = this.model.autoIncrementAttribute;
  149. let id = null;
  150. id = id || results && results[this.getInsertIdField()];
  151. id = id || metaData && metaData[this.getInsertIdField()];
  152. this.instance[autoIncrementAttribute] = id;
  153. }
  154. }
  155. isShowTablesQuery() {
  156. return this.options.type === QueryTypes.SHOWTABLES;
  157. }
  158. handleShowTablesQuery(results) {
  159. return _.flatten(results.map((resultSet) => Object.values(resultSet)));
  160. }
  161. isShowIndexesQuery() {
  162. return this.options.type === QueryTypes.SHOWINDEXES;
  163. }
  164. isShowConstraintsQuery() {
  165. return this.options.type === QueryTypes.SHOWCONSTRAINTS;
  166. }
  167. isDescribeQuery() {
  168. return this.options.type === QueryTypes.DESCRIBE;
  169. }
  170. isSelectQuery() {
  171. return this.options.type === QueryTypes.SELECT;
  172. }
  173. isBulkUpdateQuery() {
  174. return this.options.type === QueryTypes.BULKUPDATE;
  175. }
  176. isBulkDeleteQuery() {
  177. return this.options.type === QueryTypes.BULKDELETE;
  178. }
  179. isForeignKeysQuery() {
  180. return this.options.type === QueryTypes.FOREIGNKEYS;
  181. }
  182. isUpdateQuery() {
  183. return this.options.type === QueryTypes.UPDATE;
  184. }
  185. handleSelectQuery(results) {
  186. let result = null;
  187. if (this.options.fieldMap) {
  188. const fieldMap = this.options.fieldMap;
  189. results = results.map((result2) => _.reduce(fieldMap, (result3, name, field) => {
  190. if (result3[field] !== void 0 && name !== field) {
  191. result3[name] = result3[field];
  192. delete result3[field];
  193. }
  194. return result3;
  195. }, result2));
  196. }
  197. if (this.options.raw) {
  198. result = results.map((result2) => {
  199. let o = {};
  200. for (const key in result2) {
  201. if (Object.prototype.hasOwnProperty.call(result2, key)) {
  202. o[key] = result2[key];
  203. }
  204. }
  205. if (this.options.nest) {
  206. o = Dot.transform(o);
  207. }
  208. return o;
  209. });
  210. } else if (this.options.hasJoin === true) {
  211. results = AbstractQuery._groupJoinData(results, {
  212. model: this.model,
  213. includeMap: this.options.includeMap,
  214. includeNames: this.options.includeNames
  215. }, {
  216. checkExisting: this.options.hasMultiAssociation
  217. });
  218. result = this.model.bulkBuild(results, {
  219. isNewRecord: false,
  220. include: this.options.include,
  221. includeNames: this.options.includeNames,
  222. includeMap: this.options.includeMap,
  223. includeValidated: true,
  224. attributes: this.options.originalAttributes || this.options.attributes,
  225. raw: true
  226. });
  227. } else {
  228. result = this.model.bulkBuild(results, {
  229. isNewRecord: false,
  230. raw: true,
  231. attributes: this.options.originalAttributes || this.options.attributes
  232. });
  233. }
  234. if (this.options.plain) {
  235. result = result.length === 0 ? null : result[0];
  236. }
  237. return result;
  238. }
  239. isShowOrDescribeQuery() {
  240. let result = false;
  241. result = result || this.sql.toLowerCase().startsWith("show");
  242. result = result || this.sql.toLowerCase().startsWith("describe");
  243. return result;
  244. }
  245. isCallQuery() {
  246. return this.sql.toLowerCase().startsWith("call");
  247. }
  248. _logQuery(sql, debugContext, parameters) {
  249. const { connection, options } = this;
  250. const benchmark = this.sequelize.options.benchmark || options.benchmark;
  251. const logQueryParameters = this.sequelize.options.logQueryParameters || options.logQueryParameters;
  252. const startTime = Date.now();
  253. let logParameter = "";
  254. if (logQueryParameters && parameters) {
  255. const delimiter = sql.endsWith(";") ? "" : ";";
  256. let paramStr;
  257. if (Array.isArray(parameters)) {
  258. paramStr = parameters.map((p) => safeStringifyJson(p)).join(", ");
  259. } else {
  260. paramStr = safeStringifyJson(parameters);
  261. }
  262. logParameter = `${delimiter} ${paramStr}`;
  263. }
  264. const fmt = `(${connection.uuid || "default"}): ${sql}${logParameter}`;
  265. const msg = `Executing ${fmt}`;
  266. debugContext(msg);
  267. if (!benchmark) {
  268. this.sequelize.log(`Executing ${fmt}`, options);
  269. }
  270. return () => {
  271. const afterMsg = `Executed ${fmt}`;
  272. debugContext(afterMsg);
  273. if (benchmark) {
  274. this.sequelize.log(afterMsg, Date.now() - startTime, options);
  275. }
  276. };
  277. }
  278. static _groupJoinData(rows, includeOptions, options) {
  279. if (!rows.length) {
  280. return [];
  281. }
  282. let i;
  283. let length;
  284. let $i;
  285. let $length;
  286. let rowsI;
  287. let row;
  288. const rowsLength = rows.length;
  289. let keys;
  290. let key;
  291. let keyI;
  292. let keyLength;
  293. let prevKey;
  294. let values;
  295. let topValues;
  296. let topExists;
  297. const checkExisting = options.checkExisting;
  298. let itemHash;
  299. let parentHash;
  300. let topHash;
  301. const results = checkExisting ? [] : new Array(rowsLength);
  302. const resultMap = {};
  303. const includeMap = {};
  304. let $keyPrefix;
  305. let $keyPrefixString;
  306. let $prevKeyPrefixString;
  307. let $prevKeyPrefix;
  308. let $lastKeyPrefix;
  309. let $current;
  310. let $parent;
  311. let previousPiece;
  312. const buildIncludeMap = (piece) => {
  313. if (Object.prototype.hasOwnProperty.call($current.includeMap, piece)) {
  314. includeMap[key] = $current = $current.includeMap[piece];
  315. if (previousPiece) {
  316. previousPiece = `${previousPiece}.${piece}`;
  317. } else {
  318. previousPiece = piece;
  319. }
  320. includeMap[previousPiece] = $current;
  321. }
  322. };
  323. const keyPrefixStringMemo = {};
  324. const keyPrefixString = (key2, memo) => {
  325. if (!Object.prototype.hasOwnProperty.call(memo, key2)) {
  326. memo[key2] = key2.substr(0, key2.lastIndexOf("."));
  327. }
  328. return memo[key2];
  329. };
  330. const removeKeyPrefixMemo = {};
  331. const removeKeyPrefix = (key2) => {
  332. if (!Object.prototype.hasOwnProperty.call(removeKeyPrefixMemo, key2)) {
  333. const index = key2.lastIndexOf(".");
  334. removeKeyPrefixMemo[key2] = key2.substr(index === -1 ? 0 : index + 1);
  335. }
  336. return removeKeyPrefixMemo[key2];
  337. };
  338. const keyPrefixMemo = {};
  339. const keyPrefix = (key2) => {
  340. if (!Object.prototype.hasOwnProperty.call(keyPrefixMemo, key2)) {
  341. const prefixString = keyPrefixString(key2, keyPrefixStringMemo);
  342. if (!Object.prototype.hasOwnProperty.call(keyPrefixMemo, prefixString)) {
  343. keyPrefixMemo[prefixString] = prefixString ? prefixString.split(".") : [];
  344. }
  345. keyPrefixMemo[key2] = keyPrefixMemo[prefixString];
  346. }
  347. return keyPrefixMemo[key2];
  348. };
  349. const lastKeyPrefixMemo = {};
  350. const lastKeyPrefix = (key2) => {
  351. if (!Object.prototype.hasOwnProperty.call(lastKeyPrefixMemo, key2)) {
  352. const prefix2 = keyPrefix(key2);
  353. const length2 = prefix2.length;
  354. lastKeyPrefixMemo[key2] = !length2 ? "" : prefix2[length2 - 1];
  355. }
  356. return lastKeyPrefixMemo[key2];
  357. };
  358. const getUniqueKeyAttributes = (model) => {
  359. let uniqueKeyAttributes2 = _.chain(model.uniqueKeys);
  360. uniqueKeyAttributes2 = uniqueKeyAttributes2.result(`${uniqueKeyAttributes2.findKey()}.fields`).map((field) => _.findKey(model.attributes, (chr) => chr.field === field)).value();
  361. return uniqueKeyAttributes2;
  362. };
  363. const stringify = (obj) => obj instanceof Buffer ? obj.toString("hex") : obj;
  364. let primaryKeyAttributes;
  365. let uniqueKeyAttributes;
  366. let prefix;
  367. for (rowsI = 0; rowsI < rowsLength; rowsI++) {
  368. row = rows[rowsI];
  369. if (rowsI === 0) {
  370. keys = Object.keys(row);
  371. keyLength = keys.length;
  372. }
  373. if (checkExisting) {
  374. topExists = false;
  375. $length = includeOptions.model.primaryKeyAttributes.length;
  376. topHash = "";
  377. if ($length === 1) {
  378. topHash = stringify(row[includeOptions.model.primaryKeyAttributes[0]]);
  379. } else if ($length > 1) {
  380. for ($i = 0; $i < $length; $i++) {
  381. topHash += stringify(row[includeOptions.model.primaryKeyAttributes[$i]]);
  382. }
  383. } else if (!_.isEmpty(includeOptions.model.uniqueKeys)) {
  384. uniqueKeyAttributes = getUniqueKeyAttributes(includeOptions.model);
  385. for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
  386. topHash += row[uniqueKeyAttributes[$i]];
  387. }
  388. }
  389. }
  390. topValues = values = {};
  391. $prevKeyPrefix = void 0;
  392. for (keyI = 0; keyI < keyLength; keyI++) {
  393. key = keys[keyI];
  394. $keyPrefixString = keyPrefixString(key, keyPrefixStringMemo);
  395. $keyPrefix = keyPrefix(key);
  396. if (rowsI === 0 && !Object.prototype.hasOwnProperty.call(includeMap, key)) {
  397. if (!$keyPrefix.length) {
  398. includeMap[key] = includeMap[""] = includeOptions;
  399. } else {
  400. $current = includeOptions;
  401. previousPiece = void 0;
  402. $keyPrefix.forEach(buildIncludeMap);
  403. }
  404. }
  405. if ($prevKeyPrefix !== void 0 && $prevKeyPrefix !== $keyPrefix) {
  406. if (checkExisting) {
  407. length = $prevKeyPrefix.length;
  408. $parent = null;
  409. parentHash = null;
  410. if (length) {
  411. for (i = 0; i < length; i++) {
  412. prefix = $parent ? `${$parent}.${$prevKeyPrefix[i]}` : $prevKeyPrefix[i];
  413. primaryKeyAttributes = includeMap[prefix].model.primaryKeyAttributes;
  414. $length = primaryKeyAttributes.length;
  415. itemHash = prefix;
  416. if ($length === 1) {
  417. itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[0]}`]);
  418. } else if ($length > 1) {
  419. for ($i = 0; $i < $length; $i++) {
  420. itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[$i]}`]);
  421. }
  422. } else if (!_.isEmpty(includeMap[prefix].model.uniqueKeys)) {
  423. uniqueKeyAttributes = getUniqueKeyAttributes(includeMap[prefix].model);
  424. for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
  425. itemHash += row[`${prefix}.${uniqueKeyAttributes[$i]}`];
  426. }
  427. }
  428. if (!parentHash) {
  429. parentHash = topHash;
  430. }
  431. itemHash = parentHash + itemHash;
  432. $parent = prefix;
  433. if (i < length - 1) {
  434. parentHash = itemHash;
  435. }
  436. }
  437. } else {
  438. itemHash = topHash;
  439. }
  440. if (itemHash === topHash) {
  441. if (!resultMap[itemHash]) {
  442. resultMap[itemHash] = values;
  443. } else {
  444. topExists = true;
  445. }
  446. } else if (!resultMap[itemHash]) {
  447. $parent = resultMap[parentHash];
  448. $lastKeyPrefix = lastKeyPrefix(prevKey);
  449. if (includeMap[prevKey].association.isSingleAssociation) {
  450. if ($parent) {
  451. $parent[$lastKeyPrefix] = resultMap[itemHash] = values;
  452. }
  453. } else {
  454. if (!$parent[$lastKeyPrefix]) {
  455. $parent[$lastKeyPrefix] = [];
  456. }
  457. $parent[$lastKeyPrefix].push(resultMap[itemHash] = values);
  458. }
  459. }
  460. values = {};
  461. } else {
  462. $current = topValues;
  463. length = $keyPrefix.length;
  464. if (length) {
  465. for (i = 0; i < length; i++) {
  466. if (i === length - 1) {
  467. values = $current[$keyPrefix[i]] = {};
  468. }
  469. $current = $current[$keyPrefix[i]] || {};
  470. }
  471. }
  472. }
  473. }
  474. values[removeKeyPrefix(key)] = row[key];
  475. prevKey = key;
  476. $prevKeyPrefix = $keyPrefix;
  477. $prevKeyPrefixString = $keyPrefixString;
  478. }
  479. if (checkExisting) {
  480. length = $prevKeyPrefix.length;
  481. $parent = null;
  482. parentHash = null;
  483. if (length) {
  484. for (i = 0; i < length; i++) {
  485. prefix = $parent ? `${$parent}.${$prevKeyPrefix[i]}` : $prevKeyPrefix[i];
  486. primaryKeyAttributes = includeMap[prefix].model.primaryKeyAttributes;
  487. $length = primaryKeyAttributes.length;
  488. itemHash = prefix;
  489. if ($length === 1) {
  490. itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[0]}`]);
  491. } else if ($length > 0) {
  492. for ($i = 0; $i < $length; $i++) {
  493. itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[$i]}`]);
  494. }
  495. } else if (!_.isEmpty(includeMap[prefix].model.uniqueKeys)) {
  496. uniqueKeyAttributes = getUniqueKeyAttributes(includeMap[prefix].model);
  497. for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
  498. itemHash += row[`${prefix}.${uniqueKeyAttributes[$i]}`];
  499. }
  500. }
  501. if (!parentHash) {
  502. parentHash = topHash;
  503. }
  504. itemHash = parentHash + itemHash;
  505. $parent = prefix;
  506. if (i < length - 1) {
  507. parentHash = itemHash;
  508. }
  509. }
  510. } else {
  511. itemHash = topHash;
  512. }
  513. if (itemHash === topHash) {
  514. if (!resultMap[itemHash]) {
  515. resultMap[itemHash] = values;
  516. } else {
  517. topExists = true;
  518. }
  519. } else if (!resultMap[itemHash]) {
  520. $parent = resultMap[parentHash];
  521. $lastKeyPrefix = lastKeyPrefix(prevKey);
  522. if (includeMap[prevKey].association.isSingleAssociation) {
  523. if ($parent) {
  524. $parent[$lastKeyPrefix] = resultMap[itemHash] = values;
  525. }
  526. } else {
  527. if (!$parent[$lastKeyPrefix]) {
  528. $parent[$lastKeyPrefix] = [];
  529. }
  530. $parent[$lastKeyPrefix].push(resultMap[itemHash] = values);
  531. }
  532. }
  533. if (!topExists) {
  534. results.push(topValues);
  535. }
  536. } else {
  537. results[rowsI] = topValues;
  538. }
  539. }
  540. return results;
  541. }
  542. }
  543. module.exports = AbstractQuery;
  544. module.exports.AbstractQuery = AbstractQuery;
  545. module.exports.default = AbstractQuery;
  546. //# sourceMappingURL=query.js.map