Gathering detailed insights and metrics for @krvinay/mysql
Gathering detailed insights and metrics for @krvinay/mysql
Gathering detailed insights and metrics for @krvinay/mysql
Gathering detailed insights and metrics for @krvinay/mysql
sequelize mysql package to migrate from persistent connection to sequelize pool connection
npm install @krvinay/mysql
Typescript
Module System
Node Version
NPM Version
JavaScript (100%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
4 Commits
1 Watchers
1 Branches
1 Contributors
Updated on Oct 18, 2021
Latest Version
1.0.3
Package Id
@krvinay/mysql@1.0.3
Unpacked Size
27.18 kB
Size
8.28 kB
File Count
6
NPM Version
9.6.7
Node Version
18.17.1
Published on
Aug 23, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Sequelize mysql package to migrate from Mysql persistent connection to sequelize pool connection. this package will fix the issue of PROTOCOL_CONNECTION_LOST (Connection lost: The server closed the connection.) featuring:
1$ npm i @krvinay/mysql 2 3# And Sequelize and mysql2 package: 4$ npm i sequelize 5$ npm i mysql2
1mysql = require("@krvinay/mysql"); 2connection = new mysql({ 3 username: "mysql user", 4 password: "mysql password", 5 database: "database name", 6 host: "host", // default localhost 7 dateStrings: true // Force date types (TIMESTAMP, DATETIME, DATE) 8});
1connection = new mysql({ 2 ... 3 logging: (sql, exec_time) => { console.log(sql, exec_time) }, // function to log sql 4 logQueryParameters: true, //bind parameters to sql 5 benchmark: true // gives execution time to logging function on second argument 6});
1connection = new mysql({ 2 ... 3 pool: { 4 max: 5, // Maximum number of connection in pool 5 min: 0, // Minimum number of connection in pool 6 idle: 10000, // The maximum time, in milliseconds, that a connection can be idle before being released. 7 acquire: 60000, // The maximum time, in milliseconds, that pool will try to get connection before throwing error 8 evict: 1000, // The time interval, in milliseconds, after which sequelize-pool will remove idle connections. 9 } 10});
The most basic way to perform a query is to call the .query()
method on an connection object.
The simplest form of .query()
is .query(sqlString, callback)
, where a SQL string
is the first argument and the second is a callback:
1connection.query('SELECT * FROM `books` WHERE `author` = "Vinay"', function (error, results) { 2 // error will be an Error if one occurred during the query 3 // results will contain the results of the query 4});
OR
1results = await connection.querySync('SELECT * FROM `books` WHERE `author` = "Vinay"');
The second form .query(sqlString, values, callback)
comes when using
placeholder values (see escaping query values):
1connection.query('SELECT * FROM `books` WHERE `author` = ?', ['Vinay'], function (error, results) { 2 // error will be an Error if one occurred during the query 3 // results will contain the results of the query 4});
OR
1results = await connection.querySync('SELECT * FROM `books` WHERE `author` = ?', ['Vinay']);
Caution These methods of escaping values only works when the NO_BACKSLASH_ESCAPES SQL mode is disabled (which is the default state for MySQL servers).
In order to avoid SQL Injection attacks, you should always escape any user
provided data before using it inside a SQL query. You can do so using the
connection.escape()
method:
1var userId = 'some user provided value'; 2var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId); 3console.log(sql); // SELECT * FROM users WHERE id = 'some user provided value'
Alternatively, you can use ?
characters as placeholders for values you would
like to have escaped like this:
1var userId = 1; 2var sql = connection.format('SELECT * FROM users WHERE id = ?', [userId]); 3console.log(sql); // SELECT * FROM users WHERE id = 1
Multiple placeholders are mapped to values in the same order as passed. For example,
in the following query foo
equals a
, bar
equals b
, baz
equals c
, and
id
will be userId
:
1var userId = 1; 2var sql = connection.format('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', 3 ['a', 'b', 'c', userId]); 4console.log(sql); // UPDATE users SET foo = 'a', bar = 'b', baz = 'c' WHERE id = 1
This looks similar to prepared statements in MySQL, however it really just uses
the same connection.escape()
method internally.
Caution This also differs from prepared statements in that all ?
are
replaced, even those contained in comments and strings.
Different value types are escaped differently, here is how:
true
/ false
'YYYY-mm-dd HH:ii:ss'
stringsX'0fa5'
['a', 'b']
turns into 'a', 'b'
[['a', 'b'], ['c', 'd']]
turns into ('a', 'b'), ('c', 'd')
toSqlString
method will have .toSqlString()
called
and the returned value is used as the raw SQL.key = 'val'
pairs for each enumerable property on
the object. If the property's value is a function, it is skipped; if the
property's value is an object, toString() is called on it and the returned
value is used.undefined
/ null
are converted to NULL
NaN
/ Infinity
are left as-is. MySQL does not support these, and trying
to insert them as values will trigger MySQL errors until they implement
support.You may have noticed that this escaping allows you to do neat things like this:
1var post = {id: 1, title: 'Hello MySQL'}; 2var sql = connection.format('INSERT INTO posts SET ?', post); 3console.log(sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
Caution The string provided to connection.raw()
will skip all escaping
functions when used, so be careful when passing in unvalidated input.
1var CURRENT_TIMESTAMP = connection.raw('CURRENT_TIMESTAMP()'); 2var sql = connection.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]); 3console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42
If you can't trust an SQL identifier (database / table / column name) because it is
provided by a user, you should escape it with connection.escapeId(identifier)
like this:
1var sorter = 'date'; 2var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId(sorter); 3console.log(sql); // SELECT * FROM posts ORDER BY `date`
It also supports adding qualified identifiers. It will escape both parts.
1var sorter = 'date'; 2var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId('posts.' + sorter); 3console.log(sql); // SELECT * FROM posts ORDER BY `posts`.`date`
If you do not want to treat .
as qualified identifiers, you can set the second
argument to true
in order to keep the string as a literal identifier:
1var sorter = 'date.2'; 2var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId(sorter, true); 3console.log(sql); // SELECT * FROM posts ORDER BY `date.2`
Alternatively, you can use ??
characters as placeholders for identifiers you would
like to have escaped like this:
1var userId = 1; 2var columns = ['username', 'email']; 3var sql = connection.format('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId]); 4console.log(sql); // SELECT `username`, `email` FROM `users` WHERE id = 1
When you pass an Object to .escape()
or .format()
, .escapeId()
is used to avoid SQL injection in object keys.
You can use connection.format
to prepare a query with multiple insertion points,
utilizing the proper escaping for ids and values. A simple example of this follows:
1var userId = 1; 2var inserts = ['users', 'id', userId]; 3var sql = connection.format('SELECT * FROM ?? WHERE ?? = ?', inserts); 4console.log(sql); // SELECT * FROM `users` WHERE `id` = 1
Following this you then have a valid, escaped query that you can then send to the database safely.
This is useful if you are looking to prepare the query before actually sending it to the database.
You also have the option (but are not required) to pass in stringifyObject
and timeZone
,
allowing you provide a custom means of turning objects into strings, as well as a
location-specific/timezone-aware Date
.
This can be further combined with the connection.raw()
helper to generate SQL
that includes MySQL functions as dynamic vales:
1var userId = 1; 2var data = { email: 'foobar@example.com', modified: connection.raw('NOW()') }; 3var sql = connection.format('UPDATE ?? SET ? WHERE `id` = ?', ['users', data, userId]); 4console.log(sql); // UPDATE `users` SET `email` = 'foobar@example.com', `modified` = NOW() WHERE `id` = 1
Simple transaction support is available at the connection level:
1connection.beginTransaction(function(err, transConn) { 2 if (err) { throw err; } 3 transConn.query('INSERT INTO posts SET title=?', title, function (error, results) { 4 if (error) { 5 return transConn.rollback(function() { 6 throw error; 7 }); 8 } 9 10 var log = 'Post ' + results.insertId + ' added'; 11 12 transConn.query('INSERT INTO log SET data=?', log, function (error, results) { 13 if (error) { 14 return transConn.rollback(function() { 15 throw error; 16 }); 17 } 18 transConn.commit(function(err) { 19 if (err) { 20 return transConn.rollback(function() { 21 throw err; 22 }); 23 } 24 console.log('success!'); 25 }); 26 }); 27 }); 28});
Please note that beginTransaction(), commit() and rollback() are simply convenience functions that execute the START TRANSACTION, COMMIT, and ROLLBACK commands respectively. It is important to understand that many commands in MySQL can cause an implicit commit, as described in the MySQL documentation
1var transConn = null; 2try{ 3 transConn = await connection.beginTransactionSync(); 4 var results = await transConn.querySync('INSERT INTO posts SET title=?', title); 5 var log = 'Post ' + results.insertId + ' added'; 6 ..... more queries ..... 7 await transConn.commitSync(); 8 console.log('success!'); 9} catch (error){ 10 if(transConn){ 11 await transConn.rollbackSync(); 12 } 13}
Isolations levels can be set per-transaction by passing isolationLevel to transaction. Default to "READ COMMITTED"
but you can override the default isolation level by passing isolationLevel in beginTransactionSync.
The possible isolations levels:
"READ UNCOMMITTED", "READ COMMITTED", "REPEATABLE READ", "SERIALIZABLE"
Pass in the desired level as the first argument:
1await connection.beginTransactionSync("READ COMMITTED");
No vulnerabilities found.
No security vulnerabilities found.