Skip to content

Commit 9d0eba2

Browse files
GHMattiGHMatti
authored andcommitted
Update to 3.0.10
1 parent 6fa6075 commit 9d0eba2

File tree

3 files changed

+139
-127
lines changed

3 files changed

+139
-127
lines changed

__resource.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
22

3-
version '3.0.9'
3+
version '3.0.10'
44

55
server_script 'mysql-async.js'

mysql-async.js

Lines changed: 137 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -5080,176 +5080,188 @@ PoolSelector.ORDER = function PoolSelectorOrder() {
50805080

50815081
const mysql = __webpack_require__(14);
50825082

5083-
const Promise = global.Promise;
5083+
const { Promise } = global.Promise;
50845084
let config = {};
50855085
let debug = 0;
50865086
let slowQueryWarning = 500;
50875087
let pool;
50885088

50895089
function prepareQuery(query, parameters) {
5090-
let sql = query;
5091-
if (parameters !== null && typeof parameters === 'object') {
5092-
sql = query.replace(/@(\w+)/g, (txt, key) => {
5093-
if (parameters.hasOwnProperty(key)) {
5094-
return mysql.escape(parameters[key]);
5095-
} else if (parameters.hasOwnProperty(`@${key}`)) {
5096-
return mysql.escape(parameters[`@${key}`]);
5097-
}
5098-
return txt;
5099-
});
5100-
}
5101-
return sql;
5090+
let sql = query;
5091+
if (parameters !== null && typeof parameters === 'object') {
5092+
sql = query.replace(/@(\w+)/g, (txt, key) => {
5093+
let result = txt;
5094+
if (Object.prototype.hasOwnProperty.call(parameters, key)) {
5095+
result = mysql.escape(parameters[key]);
5096+
} else if (Object.prototype.hasOwnProperty.call(parameters, `@${key}`)) {
5097+
result = mysql.escape(parameters[`@${key}`]);
5098+
}
5099+
return result;
5100+
});
5101+
}
5102+
return sql;
51025103
}
51035104

51045105
function typeCast(field, next) {
5105-
let dateString = '';
5106-
switch(field.type) {
5107-
case 'DATETIME':
5108-
case 'DATETIME2':
5109-
case 'TIMESTAMP':
5110-
case 'TIMESTAMP2':
5111-
case 'NEWDATE':
5112-
case 'DATE':
5113-
dateString = field.string();
5114-
if (field.type === 'DATE') dateString += ' 00:00:00';
5115-
return (new Date(dateString)).getTime();
5116-
case 'TINY':
5117-
if (field.length === 1) {
5118-
return (field.string() !== '0');
5119-
}
5120-
return next();
5121-
case 'BIT':
5122-
return Number(field.buffer()[0]);
5123-
default:
5124-
return next();
5125-
}
5106+
let dateString = '';
5107+
switch (field.type) {
5108+
case 'DATETIME':
5109+
case 'DATETIME2':
5110+
case 'TIMESTAMP':
5111+
case 'TIMESTAMP2':
5112+
case 'NEWDATE':
5113+
case 'DATE':
5114+
dateString = field.string();
5115+
if (field.type === 'DATE') dateString += ' 00:00:00';
5116+
return (new Date(dateString)).getTime();
5117+
case 'TINY':
5118+
if (field.length === 1) {
5119+
return (field.string() !== '0');
5120+
}
5121+
return next();
5122+
case 'BIT':
5123+
return Number(field.buffer()[0]);
5124+
default:
5125+
return next();
5126+
}
51265127
}
51275128

51285129
function writeDebug(time, sql, resource) {
5129-
const executionTime = time[0]*1e3+time[1]*1e-6;
5130-
if (slowQueryWarning && !debug && executionTime > slowQueryWarning) {
5131-
console.log(`[MySQL] [Slow Query Warning] [${resource}] [${executionTime.toFixed()}ms] ${sql}`);
5132-
}
5133-
if (debug) console.log(`[MySQL] [${resource}] [${executionTime.toFixed()}ms] ${sql}`);
5130+
const executionTime = time[0] * 1e3 + time[1] * 1e-6;
5131+
if (slowQueryWarning && !debug && executionTime > slowQueryWarning) {
5132+
console.log(`[MySQL] [Slow Query Warning] [${resource}] [${executionTime.toFixed()}ms] ${sql}`);
5133+
}
5134+
if (debug) console.log(`[MySQL] [${resource}] [${executionTime.toFixed()}ms] ${sql}`);
51345135
}
51355136

51365137
function safeInvoke(callback, args) {
5137-
if (typeof callback === 'function') setImmediate(() => {
5138-
callback(args);
5138+
if (typeof callback === 'function') {
5139+
setImmediate(() => {
5140+
callback(args);
51395141
});
5142+
}
51405143
}
51415144

51425145
function execute(sql, invokingResource, connection) {
5143-
const queryPromise = new Promise((resolve, reject) => {
5144-
let start = process.hrtime();
5145-
const db = connection || pool;
5146-
db.query(sql, (error, result) => {
5147-
writeDebug(process.hrtime(start), sql.sql, invokingResource);
5148-
if (error) reject(error);
5149-
resolve(result);
5150-
});
5151-
});
5152-
queryPromise.catch((error) => {
5153-
console.log(`[ERROR] [MySQL] [${invokingResource}] An error happens on MySQL for query "${sql}": ${error.message}`);
5146+
const queryPromise = new Promise((resolve, reject) => {
5147+
const start = process.hrtime();
5148+
const db = connection || pool;
5149+
db.query(sql, (error, result) => {
5150+
writeDebug(process.hrtime(start), sql.sql, invokingResource);
5151+
if (error) reject(error);
5152+
resolve(result);
51545153
});
5155-
return queryPromise;
5154+
});
5155+
queryPromise.catch((error) => {
5156+
console.log(`[ERROR] [MySQL] [${invokingResource}] An error happens on MySQL for query "${sql}": ${error.message}`);
5157+
});
5158+
return queryPromise;
51565159
}
51575160

51585161
global.exports('mysql_execute', (query, parameters, callback) => {
5159-
const invokingResource = global.GetInvokingResource();
5160-
let sql = prepareQuery(query, parameters);
5161-
execute({ sql, typeCast }, invokingResource).then((result) => {
5162-
safeInvoke(callback, (result) ? result.affectedRows : 0);
5163-
});
5162+
const invokingResource = global.GetInvokingResource();
5163+
const sql = prepareQuery(query, parameters);
5164+
execute({ sql, typeCast }, invokingResource).then((result) => {
5165+
safeInvoke(callback, (result) ? result.affectedRows : 0);
5166+
});
51645167
});
51655168

51665169
global.exports('mysql_fetch_all', (query, parameters, callback) => {
5167-
const invokingResource = global.GetInvokingResource();
5168-
let sql = prepareQuery(query, parameters);
5169-
execute({ sql, typeCast }, invokingResource).then((result) => {
5170-
safeInvoke(callback, result);
5171-
});
5170+
const invokingResource = global.GetInvokingResource();
5171+
const sql = prepareQuery(query, parameters);
5172+
execute({ sql, typeCast }, invokingResource).then((result) => {
5173+
safeInvoke(callback, result);
5174+
});
51725175
});
51735176

51745177
global.exports('mysql_fetch_scalar', (query, parameters, callback) => {
5175-
const invokingResource = global.GetInvokingResource();
5176-
let sql = prepareQuery(query, parameters);
5177-
execute({ sql, typeCast }, invokingResource).then((result) => {
5178-
safeInvoke(callback, (result && result[0]) ? Object.values(result[0])[0] : null);
5179-
});
5178+
const invokingResource = global.GetInvokingResource();
5179+
const sql = prepareQuery(query, parameters);
5180+
execute({ sql, typeCast }, invokingResource).then((result) => {
5181+
safeInvoke(callback, (result && result[0]) ? Object.values(result[0])[0] : null);
5182+
});
51805183
});
51815184

51825185
global.exports('mysql_insert', (query, parameters, callback) => {
5183-
const invokingResource = global.GetInvokingResource();
5184-
let sql = prepareQuery(query, parameters);
5185-
execute({ sql, typeCast }, invokingResource).then((result) => {
5186-
safeInvoke(callback, (result) ? result.insertId : 0);
5187-
});
5186+
const invokingResource = global.GetInvokingResource();
5187+
const sql = prepareQuery(query, parameters);
5188+
execute({ sql, typeCast }, invokingResource).then((result) => {
5189+
safeInvoke(callback, (result) ? result.insertId : 0);
5190+
});
51885191
});
51895192

51905193
// maybe remove this again
51915194
global.exports('mysql_reset_pool', () => {
5192-
const oldPool = pool;
5193-
pool = mysql.createPool(config);
5194-
setTimeout(() => { oldPool.end(); }, 1000);
5195+
const oldPool = pool;
5196+
pool = mysql.createPool(config);
5197+
setTimeout(() => { oldPool.end(); }, 1000);
51955198
});
51965199

5197-
function parseOptions(config, options) {
5198-
const cfg = config;
5199-
const opts = options.split('&');
5200-
opts.forEach((o) => {
5201-
const keyValue = o.split('=');
5202-
cfg[keyValue[0]] = keyValue[1];
5203-
});
5204-
return cfg;
5200+
function parseOptions(settings, options) {
5201+
const cfg = settings;
5202+
const opts = options.split('&');
5203+
opts.forEach((o) => {
5204+
const keyValue = o.split('=');
5205+
[, cfg[keyValue[0]]] = keyValue;
5206+
});
5207+
return cfg;
52055208
}
52065209

52075210
function parseConnectingString(connectionString) {
5208-
if(/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.test(connectionString)) {
5209-
5210-
let matches = (/(?:host|server|data\s?source|addr(?:ess)?)=(?:(.*?);|(.*))/gi.exec(connectionString));
5211-
const host = (matches) ? matches[1] || matches[2] : 'localhost';
5212-
matches = (/(?:Port)=(?:(.*?);|(.*))/gi.exec(connectionString));
5213-
const port = (matches) ? matches[1] || matches[2] : 3306;
5214-
matches = (/(?:user\s?(?:id|name)?|uid)=(?:(.*?);|(.*))/gi.exec(connectionString));
5215-
const user = (matches) ? matches[1] || matches[2] : 'root';
5216-
matches = (/(?:password|pwd)=(?:(.*?);|(.*))/gi.exec(connectionString));
5217-
const password = (matches) ? matches[1] || matches[2] : '';
5218-
matches = (/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.exec(connectionString));
5219-
const database = (matches) ? matches[1] || matches[2] : '';
5220-
return { host, port, user, password, database, supportBigNumbers: true, multipleStatements: true };
5221-
5222-
} else if(/mysql:\/\//gi.test(connectionString)) {
5223-
5224-
let matches = /mysql:\/\/(.*?)(?::|@)(?:(.*)@)?(.*?)(?::(\d{1,5}))?\/(.*?)\?(.*)/gi.exec(connectionString);
5225-
const host = (matches[3]) ? matches[3] : 'localhost';
5226-
const port = (matches[4]) ? matches[4] : 3306;
5227-
const user = (matches[1]) ? matches[1] : 'root';
5228-
const password = (matches[2]) ? matches[2] : '';
5229-
const database = (matches[5]) ? matches[5] : '';
5230-
const config = { host, port, user, password, database };
5231-
const options = matches[6];
5232-
return parseOptions(config, options);
5233-
5234-
} else throw new Error('No valid connection string found');
5211+
let cfg = null;
5212+
if (/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.test(connectionString)) {
5213+
let matches = (/(?:host|server|data\s?source|addr(?:ess)?)=(?:(.*?);|(.*))/gi.exec(connectionString));
5214+
const host = (matches) ? matches[1] || matches[2] : 'localhost';
5215+
matches = (/(?:Port)=(?:(.*?);|(.*))/gi.exec(connectionString));
5216+
const port = (matches) ? matches[1] || matches[2] : 3306;
5217+
matches = (/(?:user\s?(?:id|name)?|uid)=(?:(.*?);|(.*))/gi.exec(connectionString));
5218+
const user = (matches) ? matches[1] || matches[2] : 'root';
5219+
matches = (/(?:password|pwd)=(?:(.*?);|(.*))/gi.exec(connectionString));
5220+
const password = (matches) ? matches[1] || matches[2] : '';
5221+
matches = (/(?:database|initial\scatalog)=(?:(.*?);|(.*))/gi.exec(connectionString));
5222+
const database = (matches) ? matches[1] || matches[2] : '';
5223+
cfg = {
5224+
host,
5225+
port,
5226+
user,
5227+
password,
5228+
database,
5229+
supportBigNumbers: true,
5230+
multipleStatements: true,
5231+
};
5232+
} else if (/mysql:\/\//gi.test(connectionString)) {
5233+
const matches = /mysql:\/\/(.*?)(?::|@)(?:(.*)@)?(.*?)(?::(\d{1,5}))?\/(.*?)\?(.*)/gi.exec(connectionString);
5234+
const host = (matches[3]) ? matches[3] : 'localhost';
5235+
const port = (matches[4]) ? matches[4] : 3306;
5236+
const user = (matches[1]) ? matches[1] : 'root';
5237+
const password = (matches[2]) ? matches[2] : '';
5238+
const database = (matches[5]) ? matches[5] : '';
5239+
const settings = {
5240+
host, port, user, password, database,
5241+
};
5242+
const options = matches[6];
5243+
cfg = parseOptions(settings, options);
5244+
} else throw new Error('No valid connection string found');
5245+
5246+
return cfg;
52355247
}
52365248

52375249
let isReady = false;
52385250
global.on('onServerResourceStart', (resourcename) => {
5239-
if (resourcename == 'mysql-async') {
5240-
// maybe default to addr=localhost;pwd=;database=essentialmode;uid=root
5241-
const connectionString = global.GetConvar('mysql_connection_string', 'Empty');
5242-
if (connectionString === 'Empty') throw new Error('Empty mysql_connection_string detected.');
5243-
config = parseConnectingString(connectionString);
5244-
debug = global.GetConvarInt('mysql_debug', 0);
5245-
slowQueryWarning = global.GetConvarInt('mysql_slow_query_warning', 500);
5246-
pool = mysql.createPool(config);
5247-
global.emit('onMySQLReady'); // avoid ESX bugs
5248-
isReady = true;
5249-
}
5250-
if (isReady) {
5251-
global.emit('MySQLReady'); // avoid ESX bugs
5252-
}
5251+
if (resourcename === 'mysql-async') {
5252+
// maybe default to addr=localhost;pwd=;database=essentialmode;uid=root
5253+
const connectionString = global.GetConvar('mysql_connection_string', 'Empty');
5254+
if (connectionString === 'Empty') throw new Error('Empty mysql_connection_string detected.');
5255+
config = parseConnectingString(connectionString);
5256+
debug = global.GetConvarInt('mysql_debug', 0);
5257+
slowQueryWarning = global.GetConvarInt('mysql_slow_query_warning', 500);
5258+
pool = mysql.createPool(config);
5259+
global.emit('onMySQLReady'); // avoid ESX bugs
5260+
isReady = true;
5261+
}
5262+
if (isReady) {
5263+
global.emit('MySQLReady'); // avoid ESX bugs
5264+
}
52535265
});
52545266

52555267

src/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mysql-async",
3-
"version": "3.0.9",
3+
"version": "3.0.10",
44
"description": "fivem-mysql-async",
55
"private": true,
66
"scripts": {

0 commit comments

Comments
 (0)