From 1fe1f523767f83189499430704f6e98ce5cdf0c0 Mon Sep 17 00:00:00 2001 From: EbenSantuy <50954825+EbenSantuy@users.noreply.github.com> Date: Tue, 13 Aug 2019 22:05:51 +0700 Subject: [PATCH] updated mysql-async Updated mysql-async --- mysql-async/.editorconfig | 13 + mysql-async/.gitignore | 4 + mysql-async/LICENSE | 2 +- mysql-async/README.md | 55 +- mysql-async/__resource.lua | 21 + mysql-async/mysql-async-client.js | 219 ++++ mysql-async/mysql-async.js | 1843 ++++++++++++++--------------- 7 files changed, 1212 insertions(+), 945 deletions(-) create mode 100644 mysql-async/.editorconfig create mode 100644 mysql-async/.gitignore create mode 100644 mysql-async/mysql-async-client.js diff --git a/mysql-async/.editorconfig b/mysql-async/.editorconfig new file mode 100644 index 00000000..3fa23bc3 --- /dev/null +++ b/mysql-async/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[**.js] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = null + +[**.md] +trim_trailing_whitespace = false diff --git a/mysql-async/.gitignore b/mysql-async/.gitignore new file mode 100644 index 00000000..33f41cdb --- /dev/null +++ b/mysql-async/.gitignore @@ -0,0 +1,4 @@ +src/node_modules +src/package-lock.json + +.idea diff --git a/mysql-async/LICENSE b/mysql-async/LICENSE index 64b7d3ac..8971eee6 100644 --- a/mysql-async/LICENSE +++ b/mysql-async/LICENSE @@ -1,4 +1,4 @@ -Copyright © 2017, Joel Wurtz; © 2018 Matthias Mandelartz +Copyright © 2017, Joel Wurtz; © 2018 - 2019 Matthias Mandelartz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the diff --git a/mysql-async/README.md b/mysql-async/README.md index cc2d6ae7..4bfab6e2 100644 --- a/mysql-async/README.md +++ b/mysql-async/README.md @@ -1,13 +1,16 @@ -# MySQL Async Library for FiveM +# mysql-async Library for FiveM -This library intends to provide function to connect to a MySQL library in a Sync and Async Way. +This library intends to provide function to connect to a MySQL library in a Sync and Async way. -## Disclaimer +## Table of Contents +* [Installation](#installation) +* [Configuration](#configuration) + * [keepAlive](#keepalive) + * [ConVars](#convars) +* [GUI](#gui) +* [Usage](#usage) +* [Features](#features) -This mod does not replace EssentialMode, it offers instead a way of connecting to MySQL from lua-scripts, but -it will never contain any gameplay logic. It will remain a simple wrapper around MySQL functions. - -All feedback is appreciated in order to deliver a stable release. ## Installation @@ -20,19 +23,32 @@ Once installed, you will need to add this line of code in the resource file of e server_script '@mysql-async/lib/MySQL.lua' ``` -### Warning - -On Linux servers, users need to stick with the old mysql-async 2.x at least for the moment, due to some issues the linux server has with v8/javascript. - -It can be downloaded from https://github.com/brouznouf/fivem-mysql-async/tree/2.0 or the release section. Note that the connection_string is different for 3.0.0 and 2.x. - ## Configuration Add this convar to your server configuration and change the values according to your MySQL installation: -`set mysql_connection_string "mysql://username:password@host/database?dateStrings=true"` +`set mysql_connection_string "server=localhost;uid=mysqluser;password=password;database=fivem"` -Further options can be found under https://github.com/mysqljs/mysql#connection-options +Alternatively an url-like connection string can be used: + +`set mysql_connection_string "mysql://username:password@host/database"` + +Further options can be found under https://github.com/mysqljs/mysql#connection-options for the mysql.js connection string, they can be added on both: the semicolon seperated string or the url-like string. + +### keepAlive + +For people, having issues with the connection being interrupted for usually a bad network configuration, but have no way of figuring out what is wrong, there is an option to enable keep alive queries. This will execute a query on the given interval. To enable those keep alive queries, append e.g. `keepAlive=60` to your connection string, seperated with a semicolon, to ensure that a keep alive query is fired every 60s. + +### ConVars + +The following ConVars are available in the `server.cfg` which you execute. These have also to be set before `start mysql-async` +* `set mysql_debug 1`: Prints out the actual consumed query. +* `set mysql_debug_output "console"`: Select where to output the log, accepts `console`, `file`, and `both`. In case of `both` and `file` a file named `mysql-async.log` in your main server folder will be created. +* `set mysql_slow_query_warning 200`: Sets a limit in ms, queries slower than this limit will be displayed with a warning at the specified location of `mysql_debug_output`, see above. + +## GUI + +Since the newest version, anyone with ace admin rights can open the GUI by typing `mysql` in the F8 console. This opens a profiling view of the data collected by this middleware, that might help you optimize resources and queries. You can disable the viewing of certain data by clicking on the respective entry in the legends, and can browse a table of the 21 slowest performing queries. ## Usage @@ -115,12 +131,7 @@ local countPlayer = MySQL.Sync.fetchScalar("SELECT COUNT(1) FROM players") ## Features - * Async / Sync + * Async / Sync. * It uses the https://github.com/mysqljs/mysql library to provide a connection to your mysql server. * Create and close a connection for each query, the underlying library use a connection pool so only the -mysql auth is done each time, old tcp connections are keeped in memory for performance reasons - -## Credits - -Some parts of this library, and also my understanding were directly inspired by "Essential Mode", thanks to -them to have begin to work on this, which allows guy like me to not start from scratch every time... +mysql auth is done each time, old tcp connections are keeped in memory for performance reasons. diff --git a/mysql-async/__resource.lua b/mysql-async/__resource.lua index df3f8118..ad95aa37 100644 --- a/mysql-async/__resource.lua +++ b/mysql-async/__resource.lua @@ -1,3 +1,24 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +version '3.2.0' + server_script 'mysql-async.js' +client_script 'mysql-async-client.js' + +files { + 'ui/index.html', + 'ui/app.js', + 'ui/app.css', + 'ui/fonts/fira-sans-v9-latin-700.woff', + 'ui/fonts/fira-sans-v9-latin-700.woff2', + 'ui/fonts/fira-sans-v9-latin-italic.woff', + 'ui/fonts/fira-sans-v9-latin-italic.woff2', + 'ui/fonts/fira-sans-v9-latin-regular.woff', + 'ui/fonts/fira-sans-v9-latin-regular.woff2', + 'ui/fonts/MaterialIcons-Regular.eot', + 'ui/fonts/MaterialIcons-Regular.ttf', + 'ui/fonts/MaterialIcons-Regular.woff', + 'ui/fonts/MaterialIcons-Regular.woff2', +} + +ui_page 'ui/index.html' diff --git a/mysql-async/mysql-async-client.js b/mysql-async/mysql-async-client.js new file mode 100644 index 00000000..db0e98bd --- /dev/null +++ b/mysql-async/mysql-async-client.js @@ -0,0 +1,219 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +let isNuiActive = false; + +function NuiMessage(msg) { + window.SendNuiMessage(JSON.stringify(msg)); +} + +function NuiCallback(name, callback) { + window.RegisterNuiCallbackType(name); + window.on(`__cfx_nui:${name}`, (data, cb) => { + callback(data); + cb('ok'); + }); +} + +function setNuiActive(boolean = true) { + if (boolean !== isNuiActive) { + if (boolean) { + window.emitNet('mysql-async:request-data'); + } + isNuiActive = boolean; + NuiMessage({ type: 'onToggleShow' }); + window.SetNuiFocus(boolean, boolean); + } +} + +window.RegisterCommand('mysql', () => { + setNuiActive(); +}, true); + +NuiCallback('close-explorer', () => { + setNuiActive(false); +}); + +window.setInterval(() => { + if (isNuiActive) { + window.emitNet('mysql-async:request-data'); + } +}, 300000); + +window.onNet('mysql-async:update-resource-data', (resourceData) => { + let arrayToSortAndMap = []; + const resources = Object.keys(resourceData); + for (let i = 0; i < resources.length; i += 1) { + if (Object.prototype.hasOwnProperty.call(resourceData, resources[i])) { + if (Object.prototype.hasOwnProperty.call(resourceData[resources[i]], 'totalExecutionTime')) { + arrayToSortAndMap.push({ + resource: resources[i], + queryTime: resourceData[resources[i]].totalExecutionTime, + count: resourceData[resources[i]].queryCount, + }); + } + } + } + if (arrayToSortAndMap.length > 0) { + arrayToSortAndMap.sort((a, b) => a.queryTime - b.queryTime); + const len = arrayToSortAndMap.length; + arrayToSortAndMap = arrayToSortAndMap.filter((_, index) => index > len - 31); + arrayToSortAndMap.sort((a, b) => { + const resourceA = a.resource.toLowerCase(); + const resourceB = b.resource.toLowerCase(); + let result = 0; + if (resourceA < resourceB) { + result = -1; + } else if (resourceA > resourceB) { + result = 1; + } + return result; + }); + NuiMessage({ + type: 'onResourceLabels', + resourceLabels: arrayToSortAndMap.map(el => el.resource), + }); + NuiMessage({ + type: 'onResourceData', + resourceData: [ + { + data: arrayToSortAndMap.map(el => el.queryTime), + }, + { + data: arrayToSortAndMap.map(el => ((el.count > 0) ? el.queryTime / el.count : 0)), + }, + { + data: arrayToSortAndMap.map(el => el.count), + }, + ], + }); + } +}); + +window.onNet('mysql-async:update-time-data', (timeData) => { + let timeArray = []; + if (Array.isArray(timeData)) { + const len = timeData.length; + timeArray = timeData.filter((_, index) => index > len - 31); + } + if (timeArray.length > 0) { + NuiMessage({ + type: 'onTimeData', + timeData: [ + { + data: timeArray.map(el => el.totalExecutionTime), + }, + { + data: timeArray.map(el => ((el.queryCount > 0) ? el.totalExecutionTime / el.queryCount + : 0)), + }, + { + data: timeArray.map(el => el.queryCount), + }, + ], + }); + } +}); + +window.onNet('mysql-async:update-slow-queries', (slowQueryData) => { + const slowQueries = slowQueryData.map((el) => { + const element = el; + element.queryTime = Math.round(el.queryTime * 100) / 100; + return element; + }); + NuiMessage({ + type: 'onSlowQueryData', + slowQueries, + }); +}); + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/mysql-async/mysql-async.js b/mysql-async/mysql-async.js index c55ebec6..2a6c37cd 100644 --- a/mysql-async/mysql-async.js +++ b/mysql-async/mysql-async.js @@ -81,7 +81,7 @@ /******/ /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 30); +/******/ return __webpack_require__(__webpack_require__.s = 31); /******/ }) /************************************************************************/ /******/ ([ @@ -95,7 +95,7 @@ module.exports = require("util"); /***/ (function(module, exports, __webpack_require__) { /* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(39) +var buffer = __webpack_require__(41) var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers @@ -162,28 +162,28 @@ SafeBuffer.allocUnsafeSlow = function (size) { /* 2 */ /***/ (function(module, exports, __webpack_require__) { -exports.AuthSwitchRequestPacket = __webpack_require__(43); -exports.AuthSwitchResponsePacket = __webpack_require__(44); -exports.ClientAuthenticationPacket = __webpack_require__(45); -exports.ComChangeUserPacket = __webpack_require__(46); -exports.ComPingPacket = __webpack_require__(47); -exports.ComQueryPacket = __webpack_require__(48); -exports.ComQuitPacket = __webpack_require__(49); -exports.ComStatisticsPacket = __webpack_require__(50); -exports.EmptyPacket = __webpack_require__(51); -exports.EofPacket = __webpack_require__(52); -exports.ErrorPacket = __webpack_require__(53); +exports.AuthSwitchRequestPacket = __webpack_require__(45); +exports.AuthSwitchResponsePacket = __webpack_require__(46); +exports.ClientAuthenticationPacket = __webpack_require__(47); +exports.ComChangeUserPacket = __webpack_require__(48); +exports.ComPingPacket = __webpack_require__(49); +exports.ComQueryPacket = __webpack_require__(50); +exports.ComQuitPacket = __webpack_require__(51); +exports.ComStatisticsPacket = __webpack_require__(52); +exports.EmptyPacket = __webpack_require__(53); +exports.EofPacket = __webpack_require__(54); +exports.ErrorPacket = __webpack_require__(55); exports.Field = __webpack_require__(17); -exports.FieldPacket = __webpack_require__(54); -exports.HandshakeInitializationPacket = __webpack_require__(55); -exports.LocalDataFilePacket = __webpack_require__(56); -exports.OkPacket = __webpack_require__(57); -exports.OldPasswordPacket = __webpack_require__(58); -exports.ResultSetHeaderPacket = __webpack_require__(59); -exports.RowDataPacket = __webpack_require__(60); -exports.SSLRequestPacket = __webpack_require__(61); -exports.StatisticsPacket = __webpack_require__(62); -exports.UseOldPasswordPacket = __webpack_require__(63); +exports.FieldPacket = __webpack_require__(56); +exports.HandshakeInitializationPacket = __webpack_require__(57); +exports.LocalDataFilePacket = __webpack_require__(58); +exports.OkPacket = __webpack_require__(59); +exports.OldPasswordPacket = __webpack_require__(60); +exports.ResultSetHeaderPacket = __webpack_require__(61); +exports.RowDataPacket = __webpack_require__(62); +exports.SSLRequestPacket = __webpack_require__(63); +exports.StatisticsPacket = __webpack_require__(64); +exports.UseOldPasswordPacket = __webpack_require__(65); /***/ }), @@ -193,8 +193,7 @@ exports.UseOldPasswordPacket = __webpack_require__(63); var Util = __webpack_require__(0); var EventEmitter = __webpack_require__(4).EventEmitter; var Packets = __webpack_require__(2); -var ErrorConstants = __webpack_require__(64); -var Timer = __webpack_require__(65); +var ErrorConstants = __webpack_require__(66); // istanbul ignore next: Node.js < 0.10 not covered var listenerCount = EventEmitter.listenerCount @@ -218,7 +217,13 @@ function Sequence(options, callback) { this._callSite = null; this._ended = false; this._timeout = options.timeout; - this._timer = new Timer(this); + + // For Timers + this._idleNext = null; + this._idlePrev = null; + this._idleStart = null; + this._idleTimeout = -1; + this._repeat = null; } Sequence.determinePacket = function(byte) { @@ -358,7 +363,7 @@ module.exports = require("events"); /**/ -var pna = __webpack_require__(10); +var processNextTick = __webpack_require__(11); /**/ /**/ @@ -377,18 +382,15 @@ var util = __webpack_require__(6); util.inherits = __webpack_require__(7); /**/ -var Readable = __webpack_require__(20); -var Writable = __webpack_require__(23); +var Readable = __webpack_require__(21); +var Writable = __webpack_require__(24); util.inherits(Duplex, Readable); -{ - // avoid scope creep, the keys array can then be collected - var keys = objectKeys(Writable.prototype); - for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; - } +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; } function Duplex(options) { @@ -407,16 +409,6 @@ function Duplex(options) { this.once('end', onend); } -Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._writableState.highWaterMark; - } -}); - // the no-half-open enforcer function onend() { // if we allow half-open state, or if the writable side ended, @@ -425,7 +417,7 @@ function onend() { // no more data can be written. // But allow more writes to happen in this tick. - pna.nextTick(onEndNT, this); + processNextTick(onEndNT, this); } function onEndNT(self) { @@ -457,9 +449,15 @@ Duplex.prototype._destroy = function (err, cb) { this.push(null); this.end(); - pna.nextTick(cb, err); + processNextTick(cb, err); }; +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + /***/ }), /* 6 */ /***/ (function(module, exports) { @@ -582,7 +580,7 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(74); + module.exports = __webpack_require__(73); } @@ -592,11 +590,11 @@ try { var Crypto = __webpack_require__(15); var Events = __webpack_require__(4); -var Net = __webpack_require__(31); -var tls = __webpack_require__(32); -var ConnectionConfig = __webpack_require__(11); -var Protocol = __webpack_require__(35); -var SqlString = __webpack_require__(26); +var Net = __webpack_require__(33); +var tls = __webpack_require__(34); +var ConnectionConfig = __webpack_require__(9); +var Protocol = __webpack_require__(37); +var SqlString = __webpack_require__(27); var Query = __webpack_require__(19); var Util = __webpack_require__(0); @@ -614,16 +612,28 @@ function Connection(options) { this.threadId = null; } +function bindToCurrentDomain(callback) { + if (!callback) { + return undefined; + } + + var domain = process.domain; + + return domain + ? domain.bind(callback) + : callback; +} + Connection.createQuery = function createQuery(sql, values, callback) { if (sql instanceof Query) { return sql; } - var cb = wrapCallbackInDomain(null, callback); + var cb = bindToCurrentDomain(callback); var options = {}; if (typeof sql === 'function') { - cb = wrapCallbackInDomain(null, sql); + cb = bindToCurrentDomain(sql); return new Query(options, cb); } @@ -633,7 +643,7 @@ Connection.createQuery = function createQuery(sql, values, callback) { } if (typeof values === 'function') { - cb = wrapCallbackInDomain(null, values); + cb = bindToCurrentDomain(values); } else if (values !== undefined) { options.values = values; } @@ -645,7 +655,7 @@ Connection.createQuery = function createQuery(sql, values, callback) { options.values = values; if (typeof values === 'function') { - cb = wrapCallbackInDomain(null, values); + cb = bindToCurrentDomain(values); options.values = undefined; } @@ -679,15 +689,15 @@ Connection.prototype.connect = function connect(options, callback) { this._protocol.on('data', function(data) { connection._socket.write(data); }); - this._socket.on('data', wrapToDomain(connection, function (data) { + this._socket.on('data', function(data) { connection._protocol.write(data); - })); + }); this._protocol.on('end', function() { connection._socket.end(); }); - this._socket.on('end', wrapToDomain(connection, function () { + this._socket.on('end', function() { connection._protocol.end(); - })); + }); this._socket.on('error', this._handleNetworkError.bind(this)); this._socket.on('connect', this._handleProtocolConnect.bind(this)); @@ -707,7 +717,7 @@ Connection.prototype.connect = function connect(options, callback) { } } - this._protocol.handshake(options, wrapCallbackInDomain(this, callback)); + this._protocol.handshake(options, bindToCurrentDomain(callback)); }; Connection.prototype.changeUser = function changeUser(options, callback) { @@ -729,7 +739,7 @@ Connection.prototype.changeUser = function changeUser(options, callback) { timeout : options.timeout, charsetNumber : charsetNumber, currentConfig : this.config - }, wrapCallbackInDomain(this, callback)); + }, bindToCurrentDomain(callback)); }; Connection.prototype.beginTransaction = function beginTransaction(options, callback) { @@ -783,10 +793,6 @@ Connection.prototype.query = function query(sql, values, cb) { query.sql = this.format(query.sql, query.values); } - if (query._callback) { - query._callback = wrapCallbackInDomain(this, query._callback); - } - this._implyConnect(); return this._protocol._enqueue(query); @@ -799,7 +805,7 @@ Connection.prototype.ping = function ping(options, callback) { } this._implyConnect(); - this._protocol.ping(options, wrapCallbackInDomain(this, callback)); + this._protocol.ping(options, bindToCurrentDomain(callback)); }; Connection.prototype.statistics = function statistics(options, callback) { @@ -809,7 +815,7 @@ Connection.prototype.statistics = function statistics(options, callback) { } this._implyConnect(); - this._protocol.stats(options, wrapCallbackInDomain(this, callback)); + this._protocol.stats(options, bindToCurrentDomain(callback)); }; Connection.prototype.end = function end(options, callback) { @@ -830,7 +836,7 @@ Connection.prototype.end = function end(options, callback) { } this._implyConnect(); - this._protocol.quit(opts, wrapCallbackInDomain(this, cb)); + this._protocol.quit(opts, bindToCurrentDomain(cb)); }; Connection.prototype.destroy = function() { @@ -1046,146 +1052,13 @@ Connection.prototype._implyConnect = function() { } }; -function unwrapFromDomain(fn) { - return function () { - var domains = []; - var ret; - - while (process.domain) { - domains.shift(process.domain); - process.domain.exit(); - } - - try { - ret = fn.apply(this, arguments); - } finally { - for (var i = 0; i < domains.length; i++) { - domains[i].enter(); - } - } - - return ret; - }; -} - -function wrapCallbackInDomain(ee, fn) { - if (typeof fn !== 'function' || fn.domain) { - return fn; - } - - var domain = process.domain; - - if (domain) { - return domain.bind(fn); - } else if (ee) { - return unwrapFromDomain(wrapToDomain(ee, fn)); - } else { - return fn; - } -} - -function wrapToDomain(ee, fn) { - return function () { - if (Events.usingDomains && ee.domain) { - ee.domain.enter(); - fn.apply(this, arguments); - ee.domain.exit(); - } else { - fn.apply(this, arguments); - } - }; -} - /***/ }), /* 9 */ -/***/ (function(module, exports) { - -// Manually extracted from mysql-5.5.23/include/mysql_com.h -exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */ -exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */ -exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */ -exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */ -exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */ -exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */ -exports.CLIENT_ODBC = 64; /* Odbc client */ -exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ -exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */ -exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */ -exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */ -exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */ -exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */ -exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */ -exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */ -exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */ - -exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */ -exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */ -exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */ - -exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */ - -exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824; -exports.CLIENT_REMEMBER_OPTIONS = 2147483648; - - -/***/ }), -/* 10 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = { nextTick: nextTick }; -} else { - module.exports = process -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -var urlParse = __webpack_require__(33).parse; -var ClientConstants = __webpack_require__(9); +var urlParse = __webpack_require__(35).parse; +var ClientConstants = __webpack_require__(10); var Charsets = __webpack_require__(16); var SSLProfiles = null; @@ -1310,7 +1183,7 @@ ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) { ConnectionConfig.getSSLProfile = function getSSLProfile(name) { if (!SSLProfiles) { - SSLProfiles = __webpack_require__(34); + SSLProfiles = __webpack_require__(36); } var ssl = SSLProfiles[name]; @@ -1387,53 +1260,90 @@ ConnectionConfig.parseUrl = function(url) { }; +/***/ }), +/* 10 */ +/***/ (function(module, exports) { + +// Manually extracted from mysql-5.5.23/include/mysql_com.h +exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */ +exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */ +exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */ +exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */ +exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */ +exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */ +exports.CLIENT_ODBC = 64; /* Odbc client */ +exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ +exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */ +exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */ +exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */ +exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */ +exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */ +exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */ +exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */ +exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */ + +exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */ +exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */ +exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */ + +exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */ + +exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824; +exports.CLIENT_REMEMBER_OPTIONS = 2147483648; + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = nextTick; +} else { + module.exports = process.nextTick; +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + + /***/ }), /* 12 */ -/***/ (function(module, exports) { - -// Manually extracted from mysql-5.7.9/include/mysql.h.pp -// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html -exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) -exports.TINY = 0x01; // aka TINYINT, 1 byte -exports.SHORT = 0x02; // aka SMALLINT, 2 bytes -exports.LONG = 0x03; // aka INT, 4 bytes -exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes -exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes -exports.NULL = 0x06; // NULL (used for prepared statements, I think) -exports.TIMESTAMP = 0x07; // aka TIMESTAMP -exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes -exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes -exports.DATE = 0x0a; // aka DATE -exports.TIME = 0x0b; // aka TIME -exports.DATETIME = 0x0c; // aka DATETIME -exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask) -exports.NEWDATE = 0x0e; // aka ? -exports.VARCHAR = 0x0f; // aka VARCHAR (?) -exports.BIT = 0x10; // aka BIT, 1-8 byte -exports.TIMESTAMP2 = 0x11; // aka TIMESTAMP with fractional seconds -exports.DATETIME2 = 0x12; // aka DATETIME with fractional seconds -exports.TIME2 = 0x13; // aka TIME with fractional seconds -exports.JSON = 0xf5; // aka JSON -exports.NEWDECIMAL = 0xf6; // aka DECIMAL -exports.ENUM = 0xf7; // aka ENUM -exports.SET = 0xf8; // aka SET -exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT -exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT -exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT -exports.BLOB = 0xfc; // aka BLOB, TEXT -exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY -exports.STRING = 0xfe; // aka CHAR, BINARY -exports.GEOMETRY = 0xff; // aka GEOMETRY - - -/***/ }), -/* 13 */ -/***/ (function(module, exports) { - -module.exports = require("stream"); - -/***/ }), -/* 14 */ /***/ (function(module, exports, __webpack_require__) { var Classes = Object.create(null); @@ -1571,22 +1481,22 @@ function loadClass(className) { Class = __webpack_require__(8); break; case 'ConnectionConfig': - Class = __webpack_require__(11); + Class = __webpack_require__(9); break; case 'Pool': - Class = __webpack_require__(27); + Class = __webpack_require__(28); break; case 'PoolCluster': Class = __webpack_require__(84); break; case 'PoolConfig': - Class = __webpack_require__(28); + Class = __webpack_require__(29); break; case 'SqlString': - Class = __webpack_require__(26); + Class = __webpack_require__(27); break; case 'Types': - Class = __webpack_require__(12); + Class = __webpack_require__(13); break; default: throw new Error('Cannot find class \'' + className + '\''); @@ -1599,6 +1509,51 @@ function loadClass(className) { } +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + +// Manually extracted from mysql-5.7.9/include/mysql.h.pp +// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html +exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) +exports.TINY = 0x01; // aka TINYINT, 1 byte +exports.SHORT = 0x02; // aka SMALLINT, 2 bytes +exports.LONG = 0x03; // aka INT, 4 bytes +exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes +exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes +exports.NULL = 0x06; // NULL (used for prepared statements, I think) +exports.TIMESTAMP = 0x07; // aka TIMESTAMP +exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes +exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes +exports.DATE = 0x0a; // aka DATE +exports.TIME = 0x0b; // aka TIME +exports.DATETIME = 0x0c; // aka DATETIME +exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask) +exports.NEWDATE = 0x0e; // aka ? +exports.VARCHAR = 0x0f; // aka VARCHAR (?) +exports.BIT = 0x10; // aka BIT, 1-8 byte +exports.TIMESTAMP2 = 0x11; // aka TIMESTAMP with fractional seconds +exports.DATETIME2 = 0x12; // aka DATETIME with fractional seconds +exports.TIME2 = 0x13; // aka TIME with fractional seconds +exports.JSON = 0xf5; // aka JSON +exports.NEWDECIMAL = 0xf6; // aka DECIMAL +exports.ENUM = 0xf7; // aka ENUM +exports.SET = 0xf8; // aka SET +exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT +exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT +exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT +exports.BLOB = 0xfc; // aka BLOB, TEXT +exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY +exports.STRING = 0xfe; // aka CHAR, BINARY +exports.GEOMETRY = 0xff; // aka GEOMETRY + + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + +module.exports = require("stream"); + /***/ }), /* 15 */ /***/ (function(module, exports) { @@ -1877,7 +1832,7 @@ exports.UTF32 = exports.UTF32_GENERAL_CI; /* 17 */ /***/ (function(module, exports, __webpack_require__) { -var Types = __webpack_require__(12); +var Types = __webpack_require__(13); module.exports = Field; function Field(options) { @@ -1954,10 +1909,10 @@ Auth.token = function(password, scramble) { // This is a port of sql/password.c:hash_password which needs to be used for // pre-4.1 passwords. Auth.hashPassword = function(password) { - var nr = [0x5030, 0x5735]; - var add = 7; - var nr2 = [0x1234, 0x5671]; - var result = Buffer.alloc(8); + var nr = [0x5030, 0x5735], + add = 7, + nr2 = [0x1234, 0x5671], + result = Buffer.alloc(8); if (typeof password === 'string'){ password = Buffer.from(password); @@ -2005,12 +1960,12 @@ Auth.myRnd = function(r){ }; Auth.scramble323 = function(message, password) { - var to = Buffer.allocUnsafe(8); - var hashPass = this.hashPassword(password); - var hashMessage = this.hashPassword(message.slice(0, 8)); - var seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0); - var seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4); - var r = this.randomInit(seed1, seed2); + var to = Buffer.allocUnsafe(8), + hashPass = this.hashPassword(password), + hashMessage = this.hashPassword(message.slice(0, 8)), + seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0), + seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4), + r = this.randomInit(seed1, seed2); for (var i = 0; i < 8; i++){ to[i] = Math.floor(this.myRnd(r) * 31) + 64; @@ -2029,8 +1984,8 @@ Auth.xor32 = function(a, b){ }; Auth.add32 = function(a, b){ - var w1 = a[1] + b[1]; - var w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16); + var w1 = a[1] + b[1], + w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16); return [w2 & 0xFFFF, w1 & 0xFFFF]; }; @@ -2038,8 +1993,8 @@ Auth.add32 = function(a, b){ Auth.mul32 = function(a, b){ // based on this example of multiplying 32b ints using 16b // http://www.dsprelated.com/showmessage/89790/1.php - var w1 = a[1] * b[1]; - var w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF); + var w1 = a[1] * b[1], + w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF); return [w2 & 0xFFFF, w1 & 0xFFFF]; }; @@ -2050,8 +2005,8 @@ Auth.and32 = function(a, b){ Auth.shl32 = function(a, b){ // assume b is 16 or less - var w1 = a[1] << b; - var w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16); + var w1 = a[1] << b, + w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16); return [w2 & 0xFFFF, w1 & 0xFFFF]; }; @@ -2080,8 +2035,8 @@ var Util = __webpack_require__(0); var Packets = __webpack_require__(2); var ResultSet = __webpack_require__(69); var ServerStatus = __webpack_require__(70); -var fs = __webpack_require__(71); -var Readable = __webpack_require__(72); +var fs = __webpack_require__(20); +var Readable = __webpack_require__(71); module.exports = Query; Util.inherits(Query, Sequence); @@ -2257,12 +2212,12 @@ Query.prototype._sendLocalDataFile = function(path) { }; Query.prototype.stream = function(options) { - var self = this; + var self = this, + stream; options = options || {}; options.objectMode = true; - - var stream = new Readable(options); + stream = new Readable(options); stream._read = function() { self._connection && self._connection.resume(); @@ -2297,6 +2252,12 @@ Query.prototype.stream = function(options) { /***/ }), /* 20 */ +/***/ (function(module, exports) { + +module.exports = require("fs"); + +/***/ }), +/* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2325,13 +2286,13 @@ Query.prototype.stream = function(options) { /**/ -var pna = __webpack_require__(10); +var processNextTick = __webpack_require__(11); /**/ module.exports = Readable; /**/ -var isArray = __webpack_require__(73); +var isArray = __webpack_require__(72); /**/ /**/ @@ -2349,11 +2310,12 @@ var EElistenerCount = function (emitter, type) { /**/ /**/ -var Stream = __webpack_require__(21); +var Stream = __webpack_require__(22); /**/ +// TODO(bmeurer): Change this back to const once hole checks are +// properly optimized away early in Ignition+TurboFan. /**/ - var Buffer = __webpack_require__(1).Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { @@ -2362,7 +2324,6 @@ function _uint8ArrayToBuffer(chunk) { function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } - /**/ /**/ @@ -2380,8 +2341,8 @@ if (debugUtil && debugUtil.debuglog) { } /**/ -var BufferList = __webpack_require__(75); -var destroyImpl = __webpack_require__(22); +var BufferList = __webpack_require__(74); +var destroyImpl = __webpack_require__(23); var StringDecoder; util.inherits(Readable, Stream); @@ -2391,13 +2352,15 @@ var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); - - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } } function ReadableState(options, stream) { @@ -2405,26 +2368,17 @@ function ReadableState(options, stream) { options = options || {}; - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; - // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; - var readableHwm = options.readableHighWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; - - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); @@ -2471,7 +2425,7 @@ function ReadableState(options, stream) { this.decoder = null; this.encoding = null; if (options.encoding) { - if (!StringDecoder) StringDecoder = __webpack_require__(24).StringDecoder; + if (!StringDecoder) StringDecoder = __webpack_require__(25).StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } @@ -2627,7 +2581,7 @@ Readable.prototype.isPaused = function () { // backwards compatibility. Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = __webpack_require__(24).StringDecoder; + if (!StringDecoder) StringDecoder = __webpack_require__(25).StringDecoder; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; @@ -2797,7 +2751,7 @@ function emitReadable(stream) { if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; - if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); } } @@ -2816,7 +2770,7 @@ function emitReadable_(stream) { function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; - pna.nextTick(maybeReadMore_, stream, state); + processNextTick(maybeReadMore_, stream, state); } } @@ -2861,7 +2815,7 @@ Readable.prototype.pipe = function (dest, pipeOpts) { var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable, unpipeInfo) { @@ -3051,7 +3005,7 @@ Readable.prototype.on = function (ev, fn) { state.readableListening = state.needReadable = true; state.emittedReadable = false; if (!state.reading) { - pna.nextTick(nReadingNextTick, this); + processNextTick(nReadingNextTick, this); } else if (state.length) { emitReadable(this); } @@ -3082,7 +3036,7 @@ Readable.prototype.resume = function () { function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; - pna.nextTick(resume_, stream, state); + processNextTick(resume_, stream, state); } } @@ -3119,19 +3073,18 @@ function flow(stream) { // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. Readable.prototype.wrap = function (stream) { - var _this = this; - var state = this._readableState; var paused = false; + var self = this; stream.on('end', function () { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); - if (chunk && chunk.length) _this.push(chunk); + if (chunk && chunk.length) self.push(chunk); } - _this.push(null); + self.push(null); }); stream.on('data', function (chunk) { @@ -3141,7 +3094,7 @@ Readable.prototype.wrap = function (stream) { // don't skip over falsy values in objectMode if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - var ret = _this.push(chunk); + var ret = self.push(chunk); if (!ret) { paused = true; stream.pause(); @@ -3162,12 +3115,12 @@ Readable.prototype.wrap = function (stream) { // proxy certain important events. for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); } // when we try to consume some more bytes, simply unpause the // underlying stream. - this._read = function (n) { + self._read = function (n) { debug('wrapped _read', n); if (paused) { paused = false; @@ -3175,19 +3128,9 @@ Readable.prototype.wrap = function (stream) { } }; - return this; + return self; }; -Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._readableState.highWaterMark; - } -}); - // exposed for testing purposes only. Readable._fromList = fromList; @@ -3300,7 +3243,7 @@ function endReadable(stream) { if (!state.endEmitted) { state.ended = true; - pna.nextTick(endReadableNT, state, stream); + processNextTick(endReadableNT, state, stream); } } @@ -3313,6 +3256,12 @@ function endReadableNT(state, stream) { } } +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; @@ -3321,14 +3270,14 @@ function indexOf(xs, x) { } /***/ }), -/* 21 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(13); +module.exports = __webpack_require__(14); /***/ }), -/* 22 */ +/* 23 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3336,7 +3285,7 @@ module.exports = __webpack_require__(13); /**/ -var pna = __webpack_require__(10); +var processNextTick = __webpack_require__(11); /**/ // undocumented cb() API, needed for core, not for public API @@ -3350,9 +3299,9 @@ function destroy(err, cb) { if (cb) { cb(err); } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { - pna.nextTick(emitErrorNT, this, err); + processNextTick(emitErrorNT, this, err); } - return this; + return; } // we set destroyed to true before firing error callbacks in order @@ -3369,7 +3318,7 @@ function destroy(err, cb) { this._destroy(err || null, function (err) { if (!cb && err) { - pna.nextTick(emitErrorNT, _this, err); + processNextTick(emitErrorNT, _this, err); if (_this._writableState) { _this._writableState.errorEmitted = true; } @@ -3377,8 +3326,6 @@ function destroy(err, cb) { cb(err); } }); - - return this; } function undestroy() { @@ -3408,7 +3355,7 @@ module.exports = { }; /***/ }), -/* 23 */ +/* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3441,7 +3388,7 @@ module.exports = { /**/ -var pna = __webpack_require__(10); +var processNextTick = __webpack_require__(11); /**/ module.exports = Writable; @@ -3468,7 +3415,7 @@ function CorkedRequest(state) { /* */ /**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ /**/ @@ -3484,16 +3431,15 @@ util.inherits = __webpack_require__(7); /**/ var internalUtil = { - deprecate: __webpack_require__(76) + deprecate: __webpack_require__(75) }; /**/ /**/ -var Stream = __webpack_require__(21); +var Stream = __webpack_require__(22); /**/ /**/ - var Buffer = __webpack_require__(1).Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { @@ -3502,10 +3448,9 @@ function _uint8ArrayToBuffer(chunk) { function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } - /**/ -var destroyImpl = __webpack_require__(22); +var destroyImpl = __webpack_require__(23); util.inherits(Writable, Stream); @@ -3516,27 +3461,18 @@ function WritableState(options, stream) { options = options || {}; - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; - // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; - var writableHwm = options.writableHighWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; - - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); @@ -3650,7 +3586,6 @@ if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.protot Object.defineProperty(Writable, Symbol.hasInstance, { value: function (object) { if (realHasInstance.call(this, object)) return true; - if (this !== Writable) return false; return object && object._writableState instanceof WritableState; } @@ -3702,7 +3637,7 @@ function writeAfterEnd(stream, cb) { var er = new Error('write after end'); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); - pna.nextTick(cb, er); + processNextTick(cb, er); } // Checks that a user-supplied chunk is valid, especially for the particular @@ -3719,7 +3654,7 @@ function validChunk(stream, state, chunk, cb) { } if (er) { stream.emit('error', er); - pna.nextTick(cb, er); + processNextTick(cb, er); valid = false; } return valid; @@ -3728,7 +3663,7 @@ function validChunk(stream, state, chunk, cb) { Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; - var isBuf = !state.objectMode && _isUint8Array(chunk); + var isBuf = _isUint8Array(chunk) && !state.objectMode; if (isBuf && !Buffer.isBuffer(chunk)) { chunk = _uint8ArrayToBuffer(chunk); @@ -3782,16 +3717,6 @@ function decodeChunk(state, chunk, encoding) { return chunk; } -Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._writableState.highWaterMark; - } -}); - // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. @@ -3849,10 +3774,10 @@ function onwriteError(stream, state, sync, er, cb) { if (sync) { // defer the callback if we are being called synchronously // to avoid piling up things on the stack - pna.nextTick(cb, er); + processNextTick(cb, er); // this can emit finish, and it will always happen // after error - pna.nextTick(finishMaybe, stream, state); + processNextTick(finishMaybe, stream, state); stream._writableState.errorEmitted = true; stream.emit('error', er); } else { @@ -3950,7 +3875,6 @@ function clearBuffer(stream, state) { } else { state.corkedRequestsFree = new CorkedRequest(state); } - state.bufferedRequestCount = 0; } else { // Slow case, write chunks one-by-one while (entry) { @@ -3961,7 +3885,6 @@ function clearBuffer(stream, state) { doWrite(stream, state, false, len, chunk, encoding, cb); entry = entry.next; - state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently @@ -3974,6 +3897,7 @@ function clearBuffer(stream, state) { if (entry === null) state.lastBufferedRequest = null; } + state.bufferedRequestCount = 0; state.bufferedRequest = entry; state.bufferProcessing = false; } @@ -4027,7 +3951,7 @@ function prefinish(stream, state) { if (typeof stream._final === 'function') { state.pendingcb++; state.finalCalled = true; - pna.nextTick(callFinal, stream, state); + processNextTick(callFinal, stream, state); } else { state.prefinished = true; stream.emit('prefinish'); @@ -4051,7 +3975,7 @@ function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { - if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); + if (state.finished) processNextTick(cb);else stream.once('finish', cb); } state.ended = true; stream.writable = false; @@ -4101,37 +4025,13 @@ Writable.prototype._destroy = function (err, cb) { }; /***/ }), -/* 24 */ +/* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -/**/ - var Buffer = __webpack_require__(1).Buffer; -/**/ var isEncoding = Buffer.isEncoding || function (encoding) { encoding = '' + encoding; @@ -4243,10 +4143,10 @@ StringDecoder.prototype.fillLast = function (buf) { }; // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a -// continuation byte. If an invalid byte is detected, -2 is returned. +// continuation byte. function utf8CheckByte(byte) { if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; - return byte >> 6 === 0x02 ? -1 : -2; + return -1; } // Checks at most 3 bytes at the end of a Buffer in order to detect an @@ -4260,13 +4160,13 @@ function utf8CheckIncomplete(self, buf, i) { if (nb > 0) self.lastNeed = nb - 1; return nb; } - if (--j < i || nb === -2) return 0; + if (--j < i) return 0; nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) self.lastNeed = nb - 2; return nb; } - if (--j < i || nb === -2) return 0; + if (--j < i) return 0; nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) { @@ -4280,7 +4180,7 @@ function utf8CheckIncomplete(self, buf, i) { // Validates as many continuation bytes for a multi-byte UTF-8 character as // needed or are available. If we see a non-continuation byte where we expect // one, we "replace" the validated continuation bytes we've seen so far with -// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding +// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding // behavior. The continuation byte check is included three times in the case // where all of the continuation bytes for a character exist in the same buffer. // It is also done this way as a slight performance increase instead of using a @@ -4288,17 +4188,17 @@ function utf8CheckIncomplete(self, buf, i) { function utf8CheckExtraBytes(self, buf, p) { if ((buf[0] & 0xC0) !== 0x80) { self.lastNeed = 0; - return '\ufffd'; + return '\ufffd'.repeat(p); } if (self.lastNeed > 1 && buf.length > 1) { if ((buf[1] & 0xC0) !== 0x80) { self.lastNeed = 1; - return '\ufffd'; + return '\ufffd'.repeat(p + 1); } if (self.lastNeed > 2 && buf.length > 2) { if ((buf[2] & 0xC0) !== 0x80) { self.lastNeed = 2; - return '\ufffd'; + return '\ufffd'.repeat(p + 2); } } } @@ -4329,11 +4229,11 @@ function utf8Text(buf, i) { return buf.toString('utf8', i, end); } -// For UTF-8, a replacement character is added when ending on a partial -// character. +// For UTF-8, a replacement character for each buffered byte of a (partial) +// character needs to be added to the output. function utf8End(buf) { var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + '\ufffd'; + if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); return r; } @@ -4403,7 +4303,7 @@ function simpleEnd(buf) { } /***/ }), -/* 25 */ +/* 26 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4483,28 +4383,39 @@ util.inherits = __webpack_require__(7); util.inherits(Transform, Duplex); -function afterTransform(er, data) { - var ts = this._transformState; +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; ts.transforming = false; var cb = ts.writecb; if (!cb) { - return this.emit('error', new Error('write callback called multiple times')); + return stream.emit('error', new Error('write callback called multiple times')); } ts.writechunk = null; ts.writecb = null; - if (data != null) // single equals check for both `null` and `undefined` - this.push(data); + if (data !== null && data !== undefined) stream.push(data); cb(er); - var rs = this._readableState; + var rs = stream._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { - this._read(rs.highWaterMark); + stream._read(rs.highWaterMark); } } @@ -4513,14 +4424,9 @@ function Transform(options) { Duplex.call(this, options); - this._transformState = { - afterTransform: afterTransform.bind(this), - needTransform: false, - transforming: false, - writecb: null, - writechunk: null, - writeencoding: null - }; + this._transformState = new TransformState(this); + + var stream = this; // start out asking for a readable event once data is transformed. this._readableState.needReadable = true; @@ -4537,19 +4443,11 @@ function Transform(options) { } // When the writable side finishes, then flush out anything remaining. - this.on('prefinish', prefinish); -} - -function prefinish() { - var _this = this; - - if (typeof this._flush === 'function') { - this._flush(function (er, data) { - done(_this, er, data); - }); - } else { - done(this, null, null); - } + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); + });else done(stream); + }); } Transform.prototype.push = function (chunk, encoding) { @@ -4599,41 +4497,43 @@ Transform.prototype._read = function (n) { }; Transform.prototype._destroy = function (err, cb) { - var _this2 = this; + var _this = this; Duplex.prototype._destroy.call(this, err, function (err2) { cb(err2); - _this2.emit('close'); + _this.emit('close'); }); }; function done(stream, er, data) { if (er) return stream.emit('error', er); - if (data != null) // single equals check for both `null` and `undefined` - stream.push(data); + if (data !== null && data !== undefined) stream.push(data); // if there's nothing in the write buffer, then that means // that nothing more will ever be provided - if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0'); + var ws = stream._writableState; + var ts = stream._transformState; - if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming'); + if (ws.length) throw new Error('Calling transform done when ws.length != 0'); + + if (ts.transforming) throw new Error('Calling transform done when still transforming'); return stream.push(null); } /***/ }), -/* 26 */ +/* 27 */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(81); /***/ }), -/* 27 */ +/* 28 */ /***/ (function(module, exports, __webpack_require__) { -var mysql = __webpack_require__(14); +var mysql = __webpack_require__(12); var Connection = __webpack_require__(8); var EventEmitter = __webpack_require__(4).EventEmitter; var Util = __webpack_require__(0); @@ -4930,11 +4830,11 @@ function spliceConnection(array, connection) { /***/ }), -/* 28 */ +/* 29 */ /***/ (function(module, exports, __webpack_require__) { -var ConnectionConfig = __webpack_require__(11); +var ConnectionConfig = __webpack_require__(9); module.exports = PoolConfig; function PoolConfig(options) { @@ -4968,7 +4868,7 @@ PoolConfig.prototype.newConnectionConfig = function newConnectionConfig() { /***/ }), -/* 29 */ +/* 30 */ /***/ (function(module, exports) { @@ -5005,172 +4905,240 @@ PoolSelector.ORDER = function PoolSelectorOrder() { /***/ }), -/* 30 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { -const mysql = __webpack_require__(14); +const MySQL = __webpack_require__(32); +const Logger = __webpack_require__(86); +const Profiler = __webpack_require__(87); +const parseSettings = __webpack_require__(88); +const { + prepareQuery, typeCast, safeInvoke, sanitizeTransactionInput, +} = __webpack_require__(89); +let logger = null; +let profiler = null; +let mysql = null; let config = {}; -let debug = 0; -let pool; - -function prepareQuery(query, parameters) { - let sql = query; - if (parameters !== null && typeof parameters === 'object') { - sql = query.replace(/@(\w+)/g, (txt, key) => { - if (parameters.hasOwnProperty(key)) { - return mysql.escape(parameters[key]); - } else if (parameters.hasOwnProperty(`@${key}`)) { - return mysql.escape(parameters[`@${key}`]); - } - return txt; - }); - } - return sql; -} - -function writeDebug(time, sql, error) { - if (error) console.log(`[ERROR] [MySQL] An error happens on MySQL for query "${sql}": ${error.message}`) - if (debug) console.log(`[MySQL] [${(time[0]*1e3+time[1]*1e-6).toFixed()}ms] ${sql}`); -} - -async function safeInvoke(callback, args) { - if (typeof callback === 'function') setImmediate(() => { - callback(args); - }); -} - -// transform tinyint(1) to boolean -function useBoolean(fields, results) { - if (fields) { - fields.forEach(field => { - // found a column with tinyint(1) - if (field.type === 1 && field.length === 1) { - results.forEach((_, index) => { - results[index][field.name] = (results[index][field.name] !== 0); - }); - } - }); - } - return results; -} global.exports('mysql_execute', (query, parameters, callback) => { - let sql = prepareQuery(query, parameters); - let start = process.hrtime(); - pool.query(sql, (error, results) => { - writeDebug(process.hrtime(start), sql, error); - safeInvoke(callback, (results) ? results.affectedRows : 0); - }); + const invokingResource = global.GetInvokingResource(); + const sql = prepareQuery(query, parameters); + mysql.execute({ sql, typeCast }, invokingResource).then((result) => { + safeInvoke(callback, (result) ? result.affectedRows : 0); + return true; + }).catch(() => false); }); global.exports('mysql_fetch_all', (query, parameters, callback) => { - let sql = prepareQuery(query, parameters); - let start = process.hrtime(); - pool.query(sql, (error, results, fields) => { - writeDebug(process.hrtime(start), sql, error); - results = useBoolean(fields, results); - safeInvoke(callback, results); - }); + const invokingResource = global.GetInvokingResource(); + const sql = prepareQuery(query, parameters); + mysql.execute({ sql, typeCast }, invokingResource).then((result) => { + safeInvoke(callback, result); + return true; + }).catch(() => false); }); global.exports('mysql_fetch_scalar', (query, parameters, callback) => { - let sql = prepareQuery(query, parameters); - let start = process.hrtime(); - pool.query(sql, (error, results, fields) => { - writeDebug(process.hrtime(start), sql, error); - results = useBoolean(fields, results); - safeInvoke(callback, (results) ? Object.values(results[0])[0] : null); - }); + const invokingResource = global.GetInvokingResource(); + const sql = prepareQuery(query, parameters); + mysql.execute({ sql, typeCast }, invokingResource).then((result) => { + safeInvoke(callback, (result && result[0]) ? Object.values(result[0])[0] : null); + return true; + }).catch(() => false); }); global.exports('mysql_insert', (query, parameters, callback) => { - let sql = prepareQuery(query, parameters); - let start = process.hrtime(); - pool.query(sql, (error, results) => { - writeDebug(process.hrtime(start), sql, error); - safeInvoke(callback, (results) ? results.insertId : 0); - }); + const invokingResource = global.GetInvokingResource(); + const sql = prepareQuery(query, parameters); + mysql.execute({ sql, typeCast }, invokingResource).then((result) => { + safeInvoke(callback, (result) ? result.insertId : 0); + return true; + }).catch(() => false); }); -function parseOptions(config, options) { - const cfg = config; - const opts = options.split('&'); - opts.forEach((o) => { - const keyValue = o.split('='); - cfg[keyValue[0]] = keyValue[1]; +global.exports('mysql_transaction', (querys, values, callback) => { + const invokingResource = global.GetInvokingResource(); + let sqls = []; + let cb = callback; + [sqls, cb] = sanitizeTransactionInput(querys, values, cb); + mysql.beginTransaction((connection) => { + if (!connection) safeInvoke(cb, false); + const promises = []; + sqls.forEach((sql) => { + promises.push(mysql.execute({ sql }, invokingResource, connection)); }); - return cfg; -} - -function parseConnectingString(connectionString) { - if(/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.test(connectionString)) { - - let matches = (/(?:host|server|data\s?source|addr(?:ess)?)=(?:(.*?);|(.*))/gi.exec(connectionString)); - const host = (matches) ? matches[1] || matches[2] : 'localhost'; - matches = (/(?:Port)=(?:(.*?);|(.*))/gi.exec(connectionString)); - const port = (matches) ? matches[1] || matches[2] : 3306; - matches = (/(?:user\s?(?:id|name)?|uid)=(?:(.*?);|(.*))/gi.exec(connectionString)); - const user = (matches) ? matches[1] || matches[2] : 'root'; - matches = (/(?:password|pwd)=(?:(.*?);|(.*))/gi.exec(connectionString)); - const password = (matches) ? matches[1] || matches[2] : ''; - matches = (/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.exec(connectionString)); - const database = (matches) ? matches[1] || matches[2] : ''; - return { host, port, user, password, database, dateStrings: true }; - - } else if(/mysql:\/\//gi.test(connectionString)) { - - let matches = /mysql:\/\/(.*?)(?::|@)(?:(.*)@)?(.*?)(?::(\d{1,5}))?\/(.*?)\?(.*)/gi.exec(connectionString); - const host = (matches[3]) ? matches[3] : 'localhost'; - const port = (matches[4]) ? matches[4] : 3306; - const user = (matches[1]) ? matches[1] : 'root'; - const password = (matches[2]) ? matches[2] : ''; - const database = (matches[5]) ? matches[5] : ''; - const config = { host, port, user, password, database }; - const options = matches[6]; - return parseOptions(config, options); - - } else throw new Error('No valid connection string found'); -} + mysql.commitTransaction(promises, connection, (result) => { + safeInvoke(cb, result); + }); + }); +}); let isReady = false; +global.exports('is_ready', () => isReady); + global.on('onServerResourceStart', (resourcename) => { - if (resourcename == 'mysql-async') { - const connectionString = global.GetConvar('mysql_connection_string', 'mysql://localhost/'); - config = parseConnectingString(connectionString); - debug = global.GetConvarInt('mysql_debug', 0); - pool = mysql.createPool(config); - global.emit('onMySQLReady'); // avoid ESX bugs - isReady = true; - } - if (isReady) { - global.emit('MySQLReady'); // avoid ESX bugs + if (resourcename === 'mysql-async') { + const trace = global.GetConvarInt('mysql_debug', 0); + const slowQueryWarningTime = global.GetConvarInt('mysql_slow_query_warning', 200); + + logger = new Logger(global.GetConvar('mysql_debug_output', 'console')); + profiler = new Profiler(logger, { trace, slowQueryWarningTime }); + + // needs to move to a new file + const connectionString = global.GetConvar('mysql_connection_string', 'Empty'); + if (connectionString === 'Empty') { + logger.error('Empty mysql_connection_string detected.'); + } else { + config = parseSettings(connectionString); + + mysql = new MySQL(config, logger, profiler); + global.emit('onMySQLReady'); // avoid old ESX bugs + isReady = true; } + } }); +global.onNet('mysql-async:request-data', () => { + if (isReady) { + const src = global.source; + global.emitNet('mysql-async:update-resource-data', src, profiler.profiles.resources); + global.emitNet('mysql-async:update-time-data', src, profiler.profiles.executionTimes); + global.emitNet('mysql-async:update-slow-queries', src, profiler.profiles.slowQueries); + } +}); -/***/ }), -/* 31 */ -/***/ (function(module, exports) { - -module.exports = require("net"); /***/ }), /* 32 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { + +const mysql = __webpack_require__(12); + +function formatVersion(versionString) { + let versionPrefix = 'MariaDB'; + const version = versionString; + if (version[0] === '5' || version[0] === '8') { + versionPrefix = 'MySQL'; + } + return { versionPrefix, version }; +} + +class MySQL { + constructor(mysqlConfig, logger, profiler) { + this.pool = null; + this.profiler = profiler; + this.logger = logger; + if (typeof mysqlConfig === 'object') { + this.pool = mysql.createPool(mysqlConfig); + } else { + this.logger.error(`[ERROR] [MySQL] Unexpected configuration of type ${typeof mysqlconfig} received.`); + } + + this.pool.query('SELECT VERSION()', (error, result) => { + if (!error) { + const { versionPrefix, version } = formatVersion(result[0]['VERSION()']); + profiler.setVersion(`${versionPrefix}:${version}`); + logger.log('\x1b[32m[mysql-async]\x1b[0m Database server connection established.'); + } else { + logger.error(`[ERROR] ${error.message}`); + } + }); + + // for people with faulty network configurations, to keep the handle for timing out + // might be some tcp / udp issue + if (mysqlConfig.keepAlive) { + this.ping(Number(mysqlConfig.keepAlive)); + } + } + + // for people with faulty network configurations, to keep the handle for timing out + // might be some tcp / udp issue + // actual function that keeps the connection alive + ping(keepAliveTimeout) { + if (keepAliveTimeout && keepAliveTimeout > 0) { + this.execute({ sql: 'SELECT 1' }, 'mysql-async:keepAlive').then(() => { + setTimeout(() => this.ping(keepAliveTimeout), keepAliveTimeout * 1000); + }); + } + } + + execute(sql, invokingResource, connection) { + const queryPromise = new Promise((resolve, reject) => { + const start = process.hrtime(); + const db = connection || this.pool; + + db.query(sql, (error, result) => { + this.profiler.profile(process.hrtime(start), sql.sql, invokingResource); + if (error) reject(error); + resolve(result); + }); + }).catch((error) => { + this.logger.error(`[ERROR] [MySQL] [${invokingResource}] An error happens on MySQL for query "${sql.sql}": ${error.message}`); + }); + + return queryPromise; + } + + onTransactionError(error, connection, callback) { + connection.rollback(() => { + this.logger.error(error.message); + callback(false); + }); + } + + beginTransaction(callback) { + this.pool.getConnection((connectionError, connection) => { + if (connectionError) { + this.logger.error(connectionError.message); + callback(false); + return; + } + connection.beginTransaction((transactionError) => { + if (transactionError) this.onTransactionError(transactionError, connection, callback); + else callback(connection); + }); + }); + } + + commitTransaction(promises, connection, callback) { + Promise.all(promises).then(() => { + connection.commit((commitError) => { + if (commitError) this.onTransactionError(commitError, connection, callback); + else callback(true); + }); + // Otherwise catch the error from the execution + }).catch((executeError) => { + this.onTransactionError(executeError, connection, callback); + }); + } +} + +module.exports = MySQL; -module.exports = require("tls"); /***/ }), /* 33 */ /***/ (function(module, exports) { -module.exports = require("url"); +module.exports = require("net"); /***/ }), /* 34 */ /***/ (function(module, exports) { +module.exports = require("tls"); + +/***/ }), +/* 35 */ +/***/ (function(module, exports) { + +module.exports = require("url"); + +/***/ }), +/* 36 */ +/***/ (function(module, exports) { + // Certificates for Amazon RDS exports['Amazon RDS'] = { ca: [ @@ -5651,43 +5619,6 @@ exports['Amazon RDS'] = { + 'igXx7B5GgP+IHb6DTjPJAi0=\n' + '-----END CERTIFICATE-----\n', - /** - * Amazon RDS us-east-2 certificate CA 2016 to 2020 - * - * CN = Amazon RDS us-east-2 CA - * OU = Amazon RDS - * O = Amazon Web Services, Inc. - * L = Seattle - * ST = Washington - * C = US - * P = 2016-08-11T19:58:45Z/2020-03-05T19:58:45Z - * F = 9B:78:E3:64:7F:74:BC:B2:52:18:CF:13:C3:62:B8:35:9D:3D:5F:B6 - */ - '-----BEGIN CERTIFICATE-----\n' - + 'MIID/DCCAuSgAwIBAgIBTjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n' - + 'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n' - + 'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n' - + 'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNjA4MTExOTU4NDVaFw0y\n' - + 'MDAzMDUxOTU4NDVaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n' - + 'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n' - + 'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n' - + 'UyB1cy1lYXN0LTIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp\n' - + 'WnnUX7wM0zzstccX+4iXKJa9GR0a2PpvB1paEX4QRCgfhEdQWDaSqyrWNgdVCKkt\n' - + '1aQkWu5j6VAC2XIG7kKoonm1ZdBVyBLqW5lXNywlaiU9yhJkwo8BR+/OqgE+PLt/\n' - + 'EO1mlN0PQudja/XkExCXTO29TG2j7F/O7hox6vTyHNHc0H88zS21uPuBE+jivViS\n' - + 'yzj/BkyoQ85hnkues3f9R6gCGdc+J51JbZnmgzUkvXjAEuKhAm9JksVOxcOKUYe5\n' - + 'ERhn0U9zjzpfbAITIkul97VVa5IxskFFTHIPJbvRKHJkiF6wTJww/tc9wm+fSCJ1\n' - + '+DbQTGZgkQ3bJrqRN29/AgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n' - + 'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBSAHQzUYYZbepwKEMvGdHp8wzHnfDAfBgNV\n' - + 'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQsFAAOCAQEA\n' - + 'MbaEzSYZ+aZeTBxf8yi0ta8K4RdwEJsEmP6IhFFQHYUtva2Cynl4Q9tZg3RMsybT\n' - + '9mlnSQQlbN/wqIIXbkrcgFcHoXG9Odm/bDtUwwwDaiEhXVfeQom3G77QHOWMTCGK\n' - + 'qadwuh5msrb17JdXZoXr4PYHDKP7j0ONfAyFNER2+uecblHfRSpVq5UeF3L6ZJb8\n' - + 'fSw/GtAV6an+/0r+Qm+PiI2H5XuZ4GmRJYnGMhqWhBYrY7p3jtVnKcsh39wgfUnW\n' - + 'AvZEZG/yhFyAZW0Essa39LiL5VSq14Y1DOj0wgnhSY/9WHxaAo1HB1T9OeZknYbD\n' - + 'fl/EGSZ0TEvZkENrXcPlVA==\n' - + '-----END CERTIFICATE-----\n', - /** * Amazon RDS ca-central-1 certificate CA 2016 to 2020 * @@ -5760,167 +5691,20 @@ exports['Amazon RDS'] = { + 'JesWxBMXXGoDC1rIYTFO7szwDyOHlCcVXJDNsTJhc32oDWYdeIbW7o/5I+aQsrXZ\n' + 'C96HykZcgWzz6sElrQxUaT3IoMw/5nmw4uWKKnZnxgI9bY4fpQwMeBZ96iHfFxvH\n' + 'mqfEEuC7uUoPofXdBp2ObQ==\n' - + '-----END CERTIFICATE-----\n', - - /** - * Amazon RDS us-gov-west-1 CA 2017 to 2022 - * - * CN = Amazon RDS us-gov-west-1 CA - * OU = Amazon RDS - * O = Amazon Web Services, Inc. - * L = Seattle - * ST = Washington - * C = US - * P = 2017-05-19T22:31:19Z/2022-05-18T12:00:00Z - * F = 77:55:8C:C4:5E:71:1F:1B:57:E3:DA:6E:5B:74:27:12:4E:E8:69:E8 - */ - '-----BEGIN CERTIFICATE-----\n' - + 'MIIECjCCAvKgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAlVT\n' - + 'MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK\n' - + 'DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT\n' - + 'MSQwIgYDVQQDDBtBbWF6b24gUkRTIEdvdkNsb3VkIFJvb3QgQ0EwHhcNMTcwNTE5\n' - + 'MjIzMTE5WhcNMjIwNTE4MTIwMDAwWjCBkzELMAkGA1UEBhMCVVMxEzARBgNVBAgM\n' - + 'Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBX\n' - + 'ZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJDAiBgNVBAMM\n' - + 'G0FtYXpvbiBSRFMgdXMtZ292LXdlc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\n' - + 'ggEPADCCAQoCggEBAM8YZLKAzzOdNnoi7Klih26Zkj+OCpDfwx4ZYB6f8L8UoQi5\n' - + '8z9ZtIwMjiJ/kO08P1yl4gfc7YZcNFvhGruQZNat3YNpxwUpQcr4mszjuffbL4uz\n' - + '+/8FBxALdqCVOJ5Q0EVSfz3d9Bd1pUPL7ARtSpy7bn/tUPyQeI+lODYO906C0TQ3\n' - + 'b9bjOsgAdBKkHfjLdsknsOZYYIzYWOJyFJJa0B11XjDUNBy/3IuC0KvDl6At0V5b\n' - + '8M6cWcKhte2hgjwTYepV+/GTadeube1z5z6mWsN5arOAQUtYDLH6Aztq9mCJzLHm\n' - + 'RccBugnGl3fRLJ2VjioN8PoGoN9l9hFBy5fnFgsCAwEAAaNmMGQwDgYDVR0PAQH/\n' - + 'BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEG7+br8KkvwPd5g\n' - + '71Rvh2stclJbMB8GA1UdIwQYMBaAFEkQz6S4NS5lOYKcDjBSuCcVpdzjMA0GCSqG\n' - + 'SIb3DQEBCwUAA4IBAQBMA327u5ABmhX+aPxljoIbxnydmAFWxW6wNp5+rZrvPig8\n' - + 'zDRqGQWWr7wWOIjfcWugSElYtf/m9KZHG/Z6+NG7nAoUrdcd1h/IQhb+lFQ2b5g9\n' - + 'sVzQv/H2JNkfZA8fL/Ko/Tm/f9tcqe0zrGCtT+5u0Nvz35Wl8CEUKLloS5xEb3k5\n' - + '7D9IhG3fsE3vHWlWrGCk1cKry3j12wdPG5cUsug0vt34u6rdhP+FsM0tHI15Kjch\n' - + 'RuUCvyQecy2ZFNAa3jmd5ycNdL63RWe8oayRBpQBxPPCbHfILxGZEdJbCH9aJ2D/\n' - + 'l8oHIDnvOLdv7/cBjyYuvmprgPtu3QEkbre5Hln/\n' - + '-----END CERTIFICATE-----\n', - - /** - * Amazon RDS eu-west-3 certificate CA 2017 to 2020 - * - * CN = Amazon RDS eu-west-3 CA - * OU = Amazon RDS - * O = Amazon Web Services, Inc. - * L = Seattle - * ST = Washington - * C = US - * P = 2017-08-25T21:39:26Z/2020-03-05T21:39:26Z - * F = FD:35:A7:84:60:68:98:00:12:54:ED:34:26:8C:66:0F:72:DD:B2:F4 - */ - '-----BEGIN CERTIFICATE-----\n' - + 'MIID/DCCAuSgAwIBAgIBUTANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n' - + 'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n' - + 'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n' - + 'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNzA4MjUyMTM5MjZaFw0y\n' - + 'MDAzMDUyMTM5MjZaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n' - + 'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n' - + 'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n' - + 'UyBldS13ZXN0LTMgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+\n' - + 'xmlEC/3a4cJH+UPwXCE02lC7Zq5NHd0dn6peMeLN8agb6jW4VfSY0NydjRj2DJZ8\n' - + 'K7wV6sub5NUGT1NuFmvSmdbNR2T59KX0p2dVvxmXHHtIpQ9Y8Aq3ZfhmC5q5Bqgw\n' - + 'tMA1xayDi7HmoPX3R8kk9ktAZQf6lDeksCvok8idjTu9tiSpDiMwds5BjMsWfyjZ\n' - + 'd13PTGGNHYVdP692BSyXzSP1Vj84nJKnciW8tAqwIiadreJt5oXyrCXi8ekUMs80\n' - + 'cUTuGm3aA3Q7PB5ljJMPqz0eVddaiIvmTJ9O3Ez3Du/HpImyMzXjkFaf+oNXf/Hx\n' - + '/EW5jCRR6vEiXJcDRDS7AgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n' - + 'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRZ9mRtS5fHk3ZKhG20Oack4cAqMTAfBgNV\n' - + 'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQsFAAOCAQEA\n' - + 'F/u/9L6ExQwD73F/bhCw7PWcwwqsK1mypIdrjdIsu0JSgwWwGCXmrIspA3n3Dqxq\n' - + 'sMhAJD88s9Em7337t+naar2VyLO63MGwjj+vA4mtvQRKq8ScIpiEc7xN6g8HUMsd\n' - + 'gPG9lBGfNjuAZsrGJflrko4HyuSM7zHExMjXLH+CXcv/m3lWOZwnIvlVMa4x0Tz0\n' - + 'A4fklaawryngzeEjuW6zOiYCzjZtPlP8Fw0SpzppJ8VpQfrZ751RDo4yudmPqoPK\n' - + '5EUe36L8U+oYBXnC5TlYs9bpVv9o5wJQI5qA9oQE2eFWxF1E0AyZ4V5sgGUBStaX\n' - + 'BjDDWul0wSo7rt1Tq7XpnA==\n' - + '-----END CERTIFICATE-----\n', - - /** - * Amazon RDS ap-northeast-3 certificate CA 2017 to 2020 - * - * CN = Amazon RDS ap-northeast-3 CA - * OU = Amazon RDS - * O = Amazon Web Services, Inc. - * L = Seattle - * ST = Washington - * C = US - * P = 2017-12-01T00:55:42Z/2020-03-05T00:55:42Z - * F = C0:C7:D4:B3:91:40:A0:77:43:28:BF:AF:77:57:DF:FD:98:FB:10:3F - */ - '-----BEGIN CERTIFICATE-----\n' - + 'MIIEATCCAumgAwIBAgIBTjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n' - + 'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n' - + 'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n' - + 'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNzEyMDEwMDU1NDJaFw0y\n' - + 'MDAzMDUwMDU1NDJaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n' - + 'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n' - + 'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE\n' - + 'UyBhcC1ub3J0aGVhc3QtMyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n' - + 'ggEBAMZtQNnm/XT19mTa10ftHLzg5UhajoI65JHv4TQNdGXdsv+CQdGYU49BJ9Eu\n' - + '3bYgiEtTzR2lQe9zGMvtuJobLhOWuavzp7IixoIQcHkFHN6wJ1CvqrxgvJfBq6Hy\n' - + 'EuCDCiU+PPDLUNA6XM6Qx3IpHd1wrJkjRB80dhmMSpxmRmx849uFafhN+P1QybsM\n' - + 'TI0o48VON2+vj+mNuQTyLMMP8D4odSQHjaoG+zyJfJGZeAyqQyoOUOFEyQaHC3TT\n' - + '3IDSNCQlpxb9LerbCoKu79WFBBq3CS5cYpg8/fsnV2CniRBFFUumBt5z4dhw9RJU\n' - + 'qlUXXO1ZyzpGd+c5v6FtrfXtnIUCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG\n' - + 'A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFETv7ELNplYy/xTeIOInl6nzeiHg\n' - + 'MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA\n' - + 'A4IBAQCpKxOQcd0tEKb3OtsOY8q/MPwTyustGk2Rt7t9G68idADp8IytB7M0SDRo\n' - + 'wWZqynEq7orQVKdVOanhEWksNDzGp0+FPAf/KpVvdYCd7ru3+iI+V4ZEp2JFdjuZ\n' - + 'Zz0PIjS6AgsZqE5Ri1J+NmfmjGZCPhsHnGZiBaenX6K5VRwwwmLN6xtoqrrfR5zL\n' - + 'QfBeeZNJG6KiM3R/DxJ5rAa6Fz+acrhJ60L7HprhB7SFtj1RCijau3+ZwiGmUOMr\n' - + 'yKlMv+VgmzSw7o4Hbxy1WVrA6zQsTHHSGf+vkQn2PHvnFMUEu/ZLbTDYFNmTLK91\n' - + 'K6o4nMsEvhBKgo4z7H1EqqxXhvN2\n' - + '-----END CERTIFICATE-----\n', - - /** - * Amazon RDS GovCloud Root CA 2017 to 2022 - * - * CN = Amazon RDS GovCloud Root CA - * OU = Amazon RDS - * O = Amazon Web Services, Inc. - * L = Seattle - * ST = Washington - * C = US - * P = 2017-05-19T22:29:11Z/2022-05-18T22:29:11Z - * F = A3:61:F9:C9:A2:5B:91:FE:73:A6:52:E3:59:14:8E:CE:35:12:0F:FD - */ - '-----BEGIN CERTIFICATE-----\n' - + 'MIIEDjCCAvagAwIBAgIJAMM61RQn3/kdMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\n' - + 'VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi\n' - + 'MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h\n' - + 'em9uIFJEUzEkMCIGA1UEAwwbQW1hem9uIFJEUyBHb3ZDbG91ZCBSb290IENBMB4X\n' - + 'DTE3MDUxOTIyMjkxMVoXDTIyMDUxODIyMjkxMVowgZMxCzAJBgNVBAYTAlVTMRAw\n' - + 'DgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQKDBlB\n' - + 'bWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSQw\n' - + 'IgYDVQQDDBtBbWF6b24gUkRTIEdvdkNsb3VkIFJvb3QgQ0EwggEiMA0GCSqGSIb3\n' - + 'DQEBAQUAA4IBDwAwggEKAoIBAQDGS9bh1FGiJPT+GRb3C5aKypJVDC1H2gbh6n3u\n' - + 'j8cUiyMXfmm+ak402zdLpSYMaxiQ7oL/B3wEmumIpRDAsQrSp3B/qEeY7ipQGOfh\n' - + 'q2TXjXGIUjiJ/FaoGqkymHRLG+XkNNBtb7MRItsjlMVNELXECwSiMa3nJL2/YyHW\n' - + 'nTr1+11/weeZEKgVbCUrOugFkMXnfZIBSn40j6EnRlO2u/NFU5ksK5ak2+j8raZ7\n' - + 'xW7VXp9S1Tgf1IsWHjGZZZguwCkkh1tHOlHC9gVA3p63WecjrIzcrR/V27atul4m\n' - + 'tn56s5NwFvYPUIx1dbC8IajLUrepVm6XOwdQCfd02DmOyjWJAgMBAAGjYzBhMA4G\n' - + 'A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRJEM+kuDUu\n' - + 'ZTmCnA4wUrgnFaXc4zAfBgNVHSMEGDAWgBRJEM+kuDUuZTmCnA4wUrgnFaXc4zAN\n' - + 'BgkqhkiG9w0BAQsFAAOCAQEAcfA7uirXsNZyI2j4AJFVtOTKOZlQwqbyNducnmlg\n' - + '/5nug9fAkwM4AgvF5bBOD1Hw6khdsccMwIj+1S7wpL+EYb/nSc8G0qe1p/9lZ/mZ\n' - + 'ff5g4JOa26lLuCrZDqAk4TzYnt6sQKfa5ZXVUUn0BK3okhiXS0i+NloMyaBCL7vk\n' - + 'kDwkHwEqflRKfZ9/oFTcCfoiHPA7AdBtaPVr0/Kj9L7k+ouz122huqG5KqX0Zpo8\n' - + 'S0IGvcd2FZjNSNPttNAK7YuBVsZ0m2nIH1SLp//00v7yAHIgytQwwB17PBcp4NXD\n' - + 'pCfTa27ng9mMMC2YLqWQpW4TkqjDin2ZC+5X/mbrjzTvVg==\n' + '-----END CERTIFICATE-----\n' ] }; /***/ }), -/* 35 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { -var Parser = __webpack_require__(36); -var Sequences = __webpack_require__(41); +var Parser = __webpack_require__(38); +var Sequences = __webpack_require__(43); var Packets = __webpack_require__(2); -var Stream = __webpack_require__(13).Stream; +var Timers = __webpack_require__(79); +var Stream = __webpack_require__(14).Stream; var Util = __webpack_require__(0); var PacketWriter = __webpack_require__(80); @@ -6072,7 +5856,7 @@ Protocol.prototype._enqueue = function(sequence) { self._delegateError(err, sequence); }) .on('packet', function(packet) { - sequence._timer.active(); + Timers.active(sequence); self._emitPacket(packet); }) .on('end', function() { @@ -6088,7 +5872,7 @@ Protocol.prototype._enqueue = function(sequence) { self._delegateError(err, sequence); }) .on('start-tls', function() { - sequence._timer.active(); + Timers.active(sequence); self._connection._startTLS(function(err) { if (err) { // SSL negotiation error are fatal @@ -6098,7 +5882,7 @@ Protocol.prototype._enqueue = function(sequence) { return; } - sequence._timer.active(); + Timers.active(sequence); sequence._tlsUpgradeCompleteHandler(); }); }); @@ -6183,7 +5967,7 @@ Protocol.prototype._parsePacket = function() { this._handshakeInitializationPacket = packet; } - sequence._timer.active(); + Timers.active(sequence); if (!sequence[packetName]) { var err = new Error('Received packet in the wrong sequence.'); @@ -6240,7 +6024,7 @@ Protocol.prototype._determinePacket = function(sequence) { }; Protocol.prototype._dequeue = function(sequence) { - sequence._timer.stop(); + Timers.unenroll(sequence); // No point in advancing the queue, we are dead if (this._fatalError) { @@ -6262,7 +6046,8 @@ Protocol.prototype._dequeue = function(sequence) { Protocol.prototype._startSequence = function(sequence) { if (sequence._timeout > 0 && isFinite(sequence._timeout)) { - sequence._timer.start(sequence._timeout); + Timers.enroll(sequence, sequence._timeout); + Timers.active(sequence); } if (sequence.constructor === Sequences.ChangeUser) { @@ -6354,16 +6139,11 @@ Protocol.prototype.destroy = function() { }; Protocol.prototype._debugPacket = function(incoming, packet) { - var connection = this._connection; - var headline = incoming + var headline = (incoming) ? '<-- ' : '--> '; - if (connection && connection.threadId !== null) { - headline += '(' + connection.threadId + ') '; - } - - headline += packet.constructor.name; + headline = headline + packet.constructor.name; // check for debug packet restriction if (Array.isArray(this._config.debug) && this._config.debug.indexOf(packet.constructor.name) === -1) { @@ -6377,15 +6157,15 @@ Protocol.prototype._debugPacket = function(incoming, packet) { /***/ }), -/* 36 */ +/* 38 */ /***/ (function(module, exports, __webpack_require__) { var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; var MUL_32BIT = Math.pow(2, 32); -var PacketHeader = __webpack_require__(37); -var BigNumber = __webpack_require__(38); +var PacketHeader = __webpack_require__(39); +var BigNumber = __webpack_require__(40); var Buffer = __webpack_require__(1).Buffer; -var BufferList = __webpack_require__(40); +var BufferList = __webpack_require__(42); module.exports = Parser; function Parser(options) { @@ -6549,8 +6329,8 @@ Parser.prototype.resume = function() { process.nextTick(this.write.bind(this)); }; -Parser.prototype.peak = function peak(offset) { - return this._buffer[this._offset + (offset >>> 0)]; +Parser.prototype.peak = function() { + return this._buffer[this._offset]; }; Parser.prototype.parseUnsignedNumber = function parseUnsignedNumber(bytes) { @@ -6859,7 +6639,7 @@ Parser.prototype._advanceToNextPacket = function() { /***/ }), -/* 37 */ +/* 39 */ /***/ (function(module, exports) { module.exports = PacketHeader; @@ -6870,16 +6650,16 @@ function PacketHeader(length, number) { /***/ }), -/* 38 */ +/* 40 */ /***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_RESULT__;/*! bignumber.js v4.1.0 https://github.com/MikeMcl/bignumber.js/LICENCE */ +var __WEBPACK_AMD_DEFINE_RESULT__;/*! bignumber.js v4.0.4 https://github.com/MikeMcl/bignumber.js/LICENCE */ ;(function (globalObj) { 'use strict'; /* - bignumber.js v4.1.0 + bignumber.js v4.0.4 A JavaScript library for arbitrary-precision arithmetic. https://github.com/MikeMcl/bignumber.js Copyright (c) 2017 Michael Mclaughlin @@ -9604,13 +9384,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/*! bignumber.js v4.1.0 https://github.com/Mik /***/ }), -/* 39 */ +/* 41 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 40 */ +/* 42 */ /***/ (function(module, exports) { @@ -9641,20 +9421,20 @@ BufferList.prototype.push = function push(buf) { /***/ }), -/* 41 */ +/* 43 */ /***/ (function(module, exports, __webpack_require__) { -exports.ChangeUser = __webpack_require__(42); +exports.ChangeUser = __webpack_require__(44); exports.Handshake = __webpack_require__(67); exports.Ping = __webpack_require__(68); exports.Query = __webpack_require__(19); -exports.Quit = __webpack_require__(78); +exports.Quit = __webpack_require__(77); exports.Sequence = __webpack_require__(3); -exports.Statistics = __webpack_require__(79); +exports.Statistics = __webpack_require__(78); /***/ }), -/* 42 */ +/* 44 */ /***/ (function(module, exports, __webpack_require__) { var Sequence = __webpack_require__(3); @@ -9701,7 +9481,7 @@ ChangeUser.prototype['ErrorPacket'] = function(packet) { /***/ }), -/* 43 */ +/* 45 */ /***/ (function(module, exports) { module.exports = AuthSwitchRequestPacket; @@ -9727,7 +9507,7 @@ AuthSwitchRequestPacket.prototype.write = function write(writer) { /***/ }), -/* 44 */ +/* 46 */ /***/ (function(module, exports) { module.exports = AuthSwitchResponsePacket; @@ -9747,7 +9527,7 @@ AuthSwitchResponsePacket.prototype.write = function write(writer) { /***/ }), -/* 45 */ +/* 47 */ /***/ (function(module, exports, __webpack_require__) { var Buffer = __webpack_require__(1).Buffer; @@ -9807,7 +9587,7 @@ ClientAuthenticationPacket.prototype.write = function(writer) { /***/ }), -/* 46 */ +/* 48 */ /***/ (function(module, exports) { module.exports = ComChangeUserPacket; @@ -9839,7 +9619,7 @@ ComChangeUserPacket.prototype.write = function(writer) { /***/ }), -/* 47 */ +/* 49 */ /***/ (function(module, exports) { module.exports = ComPingPacket; @@ -9857,7 +9637,7 @@ ComPingPacket.prototype.parse = function(parser) { /***/ }), -/* 48 */ +/* 50 */ /***/ (function(module, exports) { module.exports = ComQueryPacket; @@ -9878,7 +9658,7 @@ ComQueryPacket.prototype.parse = function(parser) { /***/ }), -/* 49 */ +/* 51 */ /***/ (function(module, exports) { module.exports = ComQuitPacket; @@ -9896,7 +9676,7 @@ ComQuitPacket.prototype.write = function write(writer) { /***/ }), -/* 50 */ +/* 52 */ /***/ (function(module, exports) { module.exports = ComStatisticsPacket; @@ -9914,7 +9694,7 @@ ComStatisticsPacket.prototype.parse = function(parser) { /***/ }), -/* 51 */ +/* 53 */ /***/ (function(module, exports) { module.exports = EmptyPacket; @@ -9926,7 +9706,7 @@ EmptyPacket.prototype.write = function write() { /***/ }), -/* 52 */ +/* 54 */ /***/ (function(module, exports) { module.exports = EofPacket; @@ -9957,7 +9737,7 @@ EofPacket.prototype.write = function(writer) { /***/ }), -/* 53 */ +/* 55 */ /***/ (function(module, exports) { module.exports = ErrorPacket; @@ -9998,7 +9778,7 @@ ErrorPacket.prototype.write = function(writer) { /***/ }), -/* 54 */ +/* 56 */ /***/ (function(module, exports) { module.exports = FieldPacket; @@ -10097,11 +9877,11 @@ FieldPacket.prototype.write = function(writer) { /***/ }), -/* 55 */ +/* 57 */ /***/ (function(module, exports, __webpack_require__) { var Buffer = __webpack_require__(1).Buffer; -var Client = __webpack_require__(9); +var Client = __webpack_require__(10); module.exports = HandshakeInitializationPacket; function HandshakeInitializationPacket(options) { @@ -10206,7 +9986,7 @@ HandshakeInitializationPacket.prototype.scrambleBuff = function() { /***/ }), -/* 56 */ +/* 58 */ /***/ (function(module, exports) { module.exports = LocalDataFilePacket; @@ -10227,7 +10007,7 @@ LocalDataFilePacket.prototype.write = function(writer) { /***/ }), -/* 57 */ +/* 59 */ /***/ (function(module, exports) { @@ -10277,7 +10057,7 @@ OkPacket.prototype.write = function(writer) { /***/ }), -/* 58 */ +/* 60 */ /***/ (function(module, exports) { module.exports = OldPasswordPacket; @@ -10298,7 +10078,7 @@ OldPasswordPacket.prototype.write = function(writer) { /***/ }), -/* 59 */ +/* 61 */ /***/ (function(module, exports) { module.exports = ResultSetHeaderPacket; @@ -10329,10 +10109,10 @@ ResultSetHeaderPacket.prototype.write = function(writer) { /***/ }), -/* 60 */ +/* 62 */ /***/ (function(module, exports, __webpack_require__) { -var Types = __webpack_require__(12); +var Types = __webpack_require__(13); var Charsets = __webpack_require__(16); var Field = __webpack_require__(17); var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53); @@ -10468,13 +10248,13 @@ function typeMatch(type, list) { /***/ }), -/* 61 */ +/* 63 */ /***/ (function(module, exports, __webpack_require__) { // http://dev.mysql.com/doc/internals/en/ssl.html // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest -var ClientConstants = __webpack_require__(9); +var ClientConstants = __webpack_require__(10); module.exports = SSLRequestPacket; @@ -10501,7 +10281,7 @@ SSLRequestPacket.prototype.write = function(writer) { /***/ }), -/* 62 */ +/* 64 */ /***/ (function(module, exports) { module.exports = StatisticsPacket; @@ -10527,7 +10307,7 @@ StatisticsPacket.prototype.write = function(writer) { /***/ }), -/* 63 */ +/* 65 */ /***/ (function(module, exports) { module.exports = UseOldPasswordPacket; @@ -10547,13 +10327,13 @@ UseOldPasswordPacket.prototype.write = function(writer) { /***/ }), -/* 64 */ +/* 66 */ /***/ (function(module, exports) { /** * MySQL error constants * - * Extracted from version 5.7.21 + * Extracted from version 5.7.19 * * !! Generated by generate-error-constants.js, do not modify by hand !! */ @@ -11756,11 +11536,6 @@ exports.ER_WARN_USING_GEOMFROMWKB_TO_SET_SRID_ZERO exports.ER_WARN_USING_GEOMFROMWKB_TO_SET_SRID = 3196; exports.ER_XA_RETRY = 3197; exports.ER_KEYRING_AWS_UDF_AWS_KMS_ERROR = 3198; -exports.ER_BINLOG_UNSAFE_XA = 3199; -exports.ER_UDF_ERROR = 3200; -exports.ER_KEYRING_MIGRATION_FAILURE = 3201; -exports.ER_KEYRING_ACCESS_DENIED_ERROR = 3202; -exports.ER_KEYRING_MIGRATION_STATUS = 3203; // Lookup-by-number table exports[1] = 'EE_CANTCREATEFILE'; @@ -12961,58 +12736,8 @@ exports[3195] = 'ER_WARN_USING_GEOMFROMWKB_TO_SET_SRID_ZERO'; exports[3196] = 'ER_WARN_USING_GEOMFROMWKB_TO_SET_SRID'; exports[3197] = 'ER_XA_RETRY'; exports[3198] = 'ER_KEYRING_AWS_UDF_AWS_KMS_ERROR'; -exports[3199] = 'ER_BINLOG_UNSAFE_XA'; -exports[3200] = 'ER_UDF_ERROR'; -exports[3201] = 'ER_KEYRING_MIGRATION_FAILURE'; -exports[3202] = 'ER_KEYRING_ACCESS_DENIED_ERROR'; -exports[3203] = 'ER_KEYRING_MIGRATION_STATUS'; -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -var Timers = __webpack_require__(66); - -module.exports = Timer; -function Timer(object) { - this._object = object; - this._timeout = null; -} - -Timer.prototype.active = function active() { - if (this._timeout) { - if (this._timeout.refresh) { - this._timeout.refresh(); - } else { - Timers.active(this._timeout); - } - } -}; - -Timer.prototype.start = function start(msecs) { - this.stop(); - this._timeout = Timers.setTimeout(this._onTimeout.bind(this), msecs); -}; - -Timer.prototype.stop = function stop() { - if (this._timeout) { - Timers.clearTimeout(this._timeout); - this._timeout = null; - } -}; - -Timer.prototype._onTimeout = function _onTimeout() { - return this._object._onTimeout(); -}; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports) { - -module.exports = require("timers"); - /***/ }), /* 67 */ /***/ (function(module, exports, __webpack_require__) { @@ -13021,7 +12746,7 @@ var Sequence = __webpack_require__(3); var Util = __webpack_require__(0); var Packets = __webpack_require__(2); var Auth = __webpack_require__(18); -var ClientConstants = __webpack_require__(9); +var ClientConstants = __webpack_require__(10); module.exports = Handshake; Util.inherits(Handshake, Sequence); @@ -13053,6 +12778,12 @@ Handshake.prototype.determinePacket = function determinePacket(firstByte, parser }; Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) { + switch (packet.authMethodName) { + case 'mysql_native_password': + case 'mysql_old_password': + default: + } + if (packet.authMethodName === 'mysql_native_password') { var challenge = packet.authMethodData.slice(0, 20); @@ -13231,15 +12962,9 @@ exports.SERVER_PS_OUT_PARAMS = 4096; /***/ }), /* 71 */ -/***/ (function(module, exports) { - -module.exports = require("fs"); - -/***/ }), -/* 72 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(13); +var Stream = __webpack_require__(14); if (process.env.READABLE_STREAM === 'disable' && Stream) { module.exports = Stream; exports = module.exports = Stream.Readable; @@ -13250,18 +12975,18 @@ if (process.env.READABLE_STREAM === 'disable' && Stream) { exports.PassThrough = Stream.PassThrough; exports.Stream = Stream; } else { - exports = module.exports = __webpack_require__(20); + exports = module.exports = __webpack_require__(21); exports.Stream = Stream || exports; exports.Readable = exports; - exports.Writable = __webpack_require__(23); + exports.Writable = __webpack_require__(24); exports.Duplex = __webpack_require__(5); - exports.Transform = __webpack_require__(25); - exports.PassThrough = __webpack_require__(77); + exports.Transform = __webpack_require__(26); + exports.PassThrough = __webpack_require__(76); } /***/ }), -/* 73 */ +/* 72 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -13272,7 +12997,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 74 */ +/* 73 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -13301,16 +13026,18 @@ if (typeof Object.create === 'function') { /***/ }), -/* 75 */ +/* 74 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/**/ + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Buffer = __webpack_require__(1).Buffer; -var util = __webpack_require__(0); +/**/ function copyBuffer(src, target, offset) { src.copy(target, offset); @@ -13378,15 +13105,8 @@ module.exports = function () { return BufferList; }(); -if (util && util.inspect && util.inspect.custom) { - module.exports.prototype[util.inspect.custom] = function () { - var obj = util.inspect({ length: this.length }); - return this.constructor.name + ' ' + obj; - }; -} - /***/ }), -/* 76 */ +/* 75 */ /***/ (function(module, exports, __webpack_require__) { @@ -13398,7 +13118,7 @@ module.exports = __webpack_require__(0).deprecate; /***/ }), -/* 77 */ +/* 76 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -13431,7 +13151,7 @@ module.exports = __webpack_require__(0).deprecate; module.exports = PassThrough; -var Transform = __webpack_require__(25); +var Transform = __webpack_require__(26); /**/ var util = __webpack_require__(6); @@ -13451,7 +13171,7 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) { }; /***/ }), -/* 78 */ +/* 77 */ /***/ (function(module, exports, __webpack_require__) { var Sequence = __webpack_require__(3); @@ -13497,7 +13217,7 @@ Quit.prototype.start = function() { /***/ }), -/* 79 */ +/* 78 */ /***/ (function(module, exports, __webpack_require__) { var Sequence = __webpack_require__(3); @@ -13532,6 +13252,12 @@ Statistics.prototype.determinePacket = function determinePacket(firstByte) { }; +/***/ }), +/* 79 */ +/***/ (function(module, exports) { + +module.exports = require("timers"); + /***/ }), /* 80 */ /***/ (function(module, exports, __webpack_require__) { @@ -13845,19 +13571,13 @@ SqlString.format = function format(sql, values, stringifyObjects, timeZone) { } var chunkIndex = 0; - var placeholdersRegex = /\?+/g; + var placeholdersRegex = /\?\??/g; var result = ''; var valuesIndex = 0; var match; while (valuesIndex < values.length && (match = placeholdersRegex.exec(sql))) { - var len = match[0].length; - - if (len > 2) { - continue; - } - - var value = len === 2 + var value = match[0] === '??' ? SqlString.escapeId(values[valuesIndex]) : SqlString.escape(values[valuesIndex], stringifyObjects, timeZone); @@ -14074,10 +13794,10 @@ PoolConnection.prototype._removeFromPool = function _removeFromPool() { /* 84 */ /***/ (function(module, exports, __webpack_require__) { -var Pool = __webpack_require__(27); -var PoolConfig = __webpack_require__(28); +var Pool = __webpack_require__(28); +var PoolConfig = __webpack_require__(29); var PoolNamespace = __webpack_require__(85); -var PoolSelector = __webpack_require__(29); +var PoolSelector = __webpack_require__(30); var Util = __webpack_require__(0); var EventEmitter = __webpack_require__(4).EventEmitter; @@ -14369,7 +14089,7 @@ function _noop() {} /***/ (function(module, exports, __webpack_require__) { var Connection = __webpack_require__(8); -var PoolSelector = __webpack_require__(29); +var PoolSelector = __webpack_require__(30); module.exports = PoolNamespace; @@ -14506,5 +14226,284 @@ PoolNamespace.prototype._getClusterNode = function _getClusterNode() { }; +/***/ }), +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +const fs = __webpack_require__(20); + +class Logger { + constructor(output) { + this.output = output; + this.fileStream = null; + if (this.output === 'file' || this.output === 'both') { + this.fileStream = fs.createWriteStream('./mysql-async.log'); + } + this.writeConsole = msg => console.log(msg); + } + + writeFile(msg) { + this.fileStream.write(`${msg}\n`); + } + + log(msg) { + switch (this.output) { + default: + case 'console': + this.writeConsole(msg); + break; + case 'file': + this.writeFile(msg); + break; + case 'both': + this.writeConsole(msg); + this.writeFile(msg); + break; + } + } + + error(msg) { + let errorMsg = msg; + if (this.output !== 'file') { + errorMsg = `\x1b[31m${msg}\x1b[0m`; + } + this.log(errorMsg); + } +} + +module.exports = Logger; + + +/***/ }), +/* 87 */ +/***/ (function(module, exports) { + +const profilerDefaultConfig = { + trace: false, + slowQueryWarningTime: 100, + slowestQueries: 21, + timeInterval: 300000, +}; + +function updateExecutionTimes(object, queryTime) { + let returnObj = null; + + if (object) { + const { totalExecutionTime, queryCount } = object; + + returnObj = { + totalExecutionTime: totalExecutionTime + queryTime, + queryCount: queryCount + 1, + }; + } else { + returnObj = { + totalExecutionTime: queryTime, + queryCount: 1, + }; + } + + return returnObj; +} + +class Profiler { + constructor(logger, config) { + this.version = 'MySQL'; + this.startTime = Date.now(); + this.logger = logger; + this.config = Object.assign({}, profilerDefaultConfig, config); + this.profiles = { + executionTimes: [], + resources: {}, + slowQueries: [], + }; + this.slowQueryLimit = 0; + } + + get getFastestSlowQuery() { + return this.profiles.slowQueries.reduce((acc, cur) => ((cur < acc) ? cur : acc)); + } + + addSlowQuery(sql, resource, queryTime) { + this.profiles.slowQueries.push({ sql, resource, queryTime }); + if (this.profiles.slowQueries.length > this.config.slowestQueries) { + const min = this.getFastestSlowQuery; + this.profiles.slowQueries = this.profiles.slowQueries.filter(el => el !== min); + this.slowQueryLimit = this.getFastestSlowQuery; + } + } + + setVersion(version) { + this.version = version; + } + + fillExecutionTimes(interval) { + for (let i = 0; i < interval; i += 1) { + if (!this.profiles.executionTimes[i]) { + this.profiles.executionTimes[i] = { + totalExecutionTime: 0, + queryCount: 0, + }; + } + } + } + + profile(time, sql, resource) { + const interval = Math.floor((Date.now() - this.startTime) / this.config.timeInterval); + const queryTime = time[0] * 1e3 + time[1] * 1e-6; + + this.profiles.resources[resource] = updateExecutionTimes( + this.profiles.resources[resource], queryTime, + ); + this.profiles.executionTimes[interval] = updateExecutionTimes( + this.profiles.executionTimes[interval], queryTime, + ); + // fix execution times manually + this.fillExecutionTimes(interval); + // todo: cull old intervals + + if (this.slowQueryLimit < queryTime) { + this.addSlowQuery(sql, resource, queryTime); + } + + if (this.slowQueryWarningTime < queryTime) { + this.logger.error(`[${this.version}] [Slow Query Warning] [${resource}] [${queryTime.toFixed()}ms] ${sql}`); + } + + if (this.config.trace) { + this.logger.log(`[${this.version}] [${resource}] [${queryTime.toFixed()}ms] ${sql}`); + } + } +} + +module.exports = Profiler; + + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +const { parseUrl } = __webpack_require__(9); + +const defaultCfg = { + host: '127.0.0.1', + user: 'root', + database: 'fivem', + supportBigNumbers: true, + multipleStatements: true, +}; + + +function parseConnectingString(connectionString) { + let cfg = {}; + if (/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.test(connectionString)) { + // replace the old version with the new one + const connectionStr = connectionString + .replace(/(?:host|server|data\s?source|addr(?:ess)?)=/gi, 'host=') + .replace(/(?:port)=/gi, 'port=') + .replace(/(?:user\s?(?:id|name)?|uid)=/gi, 'user=') + .replace(/(?:password|pwd)=/gi, 'password=') + .replace(/(?:database|initial\scatalog)=/gi, 'database='); + connectionStr.split(';').forEach((el) => { + const equal = el.indexOf('='); + const key = (equal > -1) ? el.substr(0, equal) : el; + const value = (equal > -1) ? el.substr(equal + 1) : ''; + cfg[key] = value; + }); + } else if (/mysql:\/\//gi.test(connectionString)) { + cfg = parseUrl(connectionString); + } else throw new Error('No valid connection string found'); + + return Object.assign({}, defaultCfg, cfg); +} + +module.exports = parseConnectingString; + + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + +const mysql = __webpack_require__(12); + +function safeInvoke(callback, args) { + if (typeof callback === 'function') { + setImmediate(() => { + callback(args); + }); + } +} + +function mysqlEscape(parameters, text, key) { + let result = text; + if (Object.prototype.hasOwnProperty.call(parameters, key)) { + result = mysql.escape(parameters[key]); + } else if (Object.prototype.hasOwnProperty.call(parameters, text)) { + result = mysql.escape(parameters[text]); + } + return result; +} + +function prepareQuery(query, parameters) { + let sql = query; + if (parameters !== null && typeof parameters === 'object') { + sql = query.replace(/@(\w+)/g, (txt, key) => mysqlEscape(parameters, txt, key)); + } + return sql; +} + +function typeCast(field, next) { + let dateString = ''; + switch (field.type) { + case 'DATETIME': + case 'DATETIME2': + case 'TIMESTAMP': + case 'TIMESTAMP2': + case 'NEWDATE': + case 'DATE': + dateString = field.string(); + if (field.type === 'DATE') dateString += ' 00:00:00'; + return (new Date(dateString)).getTime(); + case 'TINY': + if (field.length === 1) { + return (field.string() !== '0'); + } + return next(); + case 'BIT': + return Number(field.buffer()[0]); + default: + return next(); + } +} + +function prepareTransactionLegacyQuery(querys) { + const sqls = querys; + sqls.forEach((element, index) => { + const query = prepareQuery(element.query, element.parameters); + sqls[index] = query; + }); + return sqls; +} + +function sanitizeTransactionInput(querys, params, callback) { + let sqls = []; + let cb = callback; + // if every query is a string we are dealing with syntax type a + if (!querys.every(element => typeof element === 'string')) sqls = querys; + else { + const values = (typeof params === 'function') ? [] : params; + querys.forEach((element) => { + sqls.push({ query: element, parameters: values }); + }); + } + if (typeof params === 'function') cb = params; + sqls = prepareTransactionLegacyQuery(sqls); + return [sqls, cb]; +} + +module.exports = { + safeInvoke, prepareQuery, typeCast, sanitizeTransactionInput, +}; + + /***/ }) /******/ ]); \ No newline at end of file