123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // ██████╗ ██╗ ██╗███╗ ██╗ ██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗
- // ██╔══██╗██║ ██║████╗ ██║ ██╔═══██╗██║ ██║██╔════╝██╔══██╗╚██╗ ██╔╝
- // ██████╔╝██║ ██║██╔██╗ ██║ ██║ ██║██║ ██║█████╗ ██████╔╝ ╚████╔╝
- // ██╔══██╗██║ ██║██║╚██╗██║ ██║▄▄ ██║██║ ██║██╔══╝ ██╔══██╗ ╚██╔╝
- // ██║ ██║╚██████╔╝██║ ╚████║ ╚██████╔╝╚██████╔╝███████╗██║ ██║ ██║
- // ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚══▀▀═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝
- //
- // Send a Native Query to the datastore and gracefully handle errors.
- var _ = require('@sailshq/lodash');
- var MySQL = require('machinepack-mysql');
- var releaseConnection = require('../connection/release-connection');
- module.exports = function runQuery(options, cb) {
- // ╦ ╦╔═╗╦ ╦╔╦╗╔═╗╔╦╗╔═╗ ┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐
- // ╚╗╔╝╠═╣║ ║ ║║╠═╣ ║ ║╣ │ │├─┘ │ ││ ││││└─┐
- // ╚╝ ╩ ╩╩═╝╩═╩╝╩ ╩ ╩ ╚═╝ └─┘┴ ┴ ┴└─┘┘└┘└─┘
- if (_.isUndefined(options) || !_.isPlainObject(options)) {
- throw new Error('Invalid options argument. Options must contain: connection, nativeQuery, and leased.');
- }
- if (!_.has(options, 'connection') || !_.isObject(options.connection)) {
- throw new Error('Invalid option used in options argument. Missing or invalid connection.');
- }
- if (!_.has(options, 'nativeQuery')) {
- throw new Error('Invalid option used in options argument. Missing or invalid nativeQuery.');
- }
- // ╦═╗╦ ╦╔╗╔ ┌┐┌┌─┐┌┬┐┬┬ ┬┌─┐ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
- // ╠╦╝║ ║║║║ │││├─┤ │ │└┐┌┘├┤ │─┼┐│ │├┤ ├┬┘└┬┘
- // ╩╚═╚═╝╝╚╝ ┘└┘┴ ┴ ┴ ┴ └┘ └─┘ └─┘└└─┘└─┘┴└─ ┴
- MySQL.sendNativeQuery({
- connection: options.connection,
- nativeQuery: options.nativeQuery,
- valuesToEscape: options.valuesToEscape,
- meta: options.meta
- })
- .switch({
- // If there was an error, check if the connection should be
- // released back into the pool automatically.
- error: function error(err) {
- if (!options.disconnectOnError) {
- return cb(err);
- }
- releaseConnection(options.connection, options.leased, function releaseConnectionCb(err) {
- return cb(err);
- });
- },
- // If the query failed, try and parse it into a normalized format and
- // release the connection if needed.
- queryFailed: function queryFailed(report) {
- // Parse the native query error into a normalized format
- var parsedError;
- try {
- parsedError = MySQL.parseNativeQueryError({
- nativeQueryError: report.error
- }).execSync();
- } catch (e) {
- if (!options.disconnectOnError) {
- return cb(e);
- }
- releaseConnection(options.connection, function releaseConnectionCb() {
- return cb(e);
- });
- return;
- }
- // If the catch all error was used, return an error instance instead of
- // the footprint.
- var catchAllError = false;
- if (parsedError.footprint.identity === 'catchall') {
- catchAllError = true;
- }
- // If this shouldn't disconnect the connection, just return the normalized
- // error with the footprint.
- if (!options.disconnectOnError) {
- if (catchAllError) {
- return cb(report.error);
- }
- return cb(parsedError);
- }
- releaseConnection(options.connection, false, function releaseConnectionCb() {
- if (catchAllError) {
- return cb(report.error);
- }
- return cb(parsedError);
- });
- },
- success: function success(report) {
- // If a custom primary key was used and the record has an `insert` query
- // type, build a manual insert report because we don't have the actual
- // value that was used.
- if (options.customPrimaryKey) {
- return cb(null, {
- result: {
- inserted: options.customPrimaryKey
- }
- });
- }
- // ╔═╗╔═╗╦═╗╔═╗╔═╗ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬ ┬─┐┌─┐┌─┐┬ ┬┬ ┌┬┐┌─┐
- // ╠═╝╠═╣╠╦╝╚═╗║╣ │─┼┐│ │├┤ ├┬┘└┬┘ ├┬┘├┤ └─┐│ ││ │ └─┐
- // ╩ ╩ ╩╩╚═╚═╝╚═╝ └─┘└└─┘└─┘┴└─ ┴ ┴└─└─┘└─┘└─┘┴─┘┴ └─┘
- // If there was a query type given, parse the results.
- var queryResults = report.result;
- if (options.queryType) {
- try {
- queryResults = MySQL.parseNativeQueryResult({
- queryType: options.queryType,
- nativeQueryResult: report.result
- }).execSync();
- } catch (e) {
- return cb(e);
- }
- }
- return cb(null, queryResults);
- }
- });
- };
|