Existe-t-il un moyen d'utiliser pool.getConnection()
tirée de la bibliothèque mysqljs/mysql avec la async/ await
syntaxe?
L'idée est d'avoir une méthode qui retourne une connexion qui peut être transmise entre les requêtes d'écriture avec diverses contraintes de clé étrangère (requêtes séquentielles) avant de la libérer et en même temps potentiellement obtenir d'autres connexions du pool pour diverses requêtes de lecture (parallèle).
Partagez mon exemple de travail:
J'utilise ceci middleware MySQL promis pour Node.js
lire cet article Créer un middleware de base de données MySQL avec Node.js 8 et Async/Await
voici ma base de données.js
var mysql = require('mysql');
// node -v must > 8.x
var util = require('util');
// !!!!! for node version < 8.x only !!!!!
// npm install util.promisify
//require('util.promisify').shim();
// -v < 8.x has problem with async await so upgrade -v to v9.6.1 for this to work.
// connection pool https://github.com/mysqljs/mysql [1]
var pool = mysql.createPool({
connectionLimit : process.env.mysql_connection_pool_Limit, // default:10
Host : process.env.mysql_Host,
user : process.env.mysql_user,
password : process.env.mysql_password,
database : process.env.mysql_database
})
// Ping database to check for common exception errors.
pool.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.')
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.')
}
}
if (connection) connection.release()
return
})
// Promisify for Node.js async/await.
pool.query = util.promisify(pool.query)
module.exports = pool
Vous devez mettre à niveau le nœud -v> 8.x
vous devez utiliser la fonction asynchrone pour pouvoir utiliser l'attente.
exemple:
var pool = require('./database')
// node -v must > 8.x, --> async / await
router.get('/:template', async function(req, res, next)
{
...
try {
var _sql_rest_url = 'SELECT * FROM arcgis_viewer.rest_url WHERE id='+ _url_id;
var rows = await pool.query(_sql_rest_url)
_url = rows[0].rest_url // first record, property name is 'rest_url'
if (_center_lat == null) {_center_lat = rows[0].center_lat }
if (_center_long == null) {_center_long= rows[0].center_long }
if (_center_zoom == null) {_center_zoom= rows[0].center_zoom }
_place = rows[0].place
} catch(err) {
throw new Error(err)
}
Compagnons. Je ne sais pas pourquoi mais j'ai essayé toute la journée mais je n'ai pas réussi à le faire fonctionner. À l'aide de vos commentaires, j'ai réessayé et cela fonctionne bien sûr.
db.js:
const pool = mysql.createPool(config);
exports.getConnection = () => {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) {
return reject(err);
}
resolve(connection);
});
});
};
someWhereElse.js:
const db = require('./db');
const wrappingFunction = async () => {
const connection = await db.getConnection();
console.log(connection);
};
wrappingFunction();
Les réponses précédentes (avec til.promisify) ne fonctionnaient pas pour moi, et l'implémentation manuelle de Promise ne fonctionne que:
Fonction:
async function removeItem (id) {
return new Promise( (resolve) => {
pool.query('DELETE FROM table_name WHERE id=' + id, (error) => {
resolve ({result: !error});
});
});
}
Usage:
const app = express();
const mysql = require('mysql');
const pool = mysql.createPool({
connectionLimit: 10,
Host: 'localhost',
user: 'login',
password: 'pass',
database: 'dbname'
});
app.post("/:id", async (req, res) => {
const answer = await itemRemove(id);
res.send(answer);
});
Il semble que la mise en œuvre manuelle des promesses soit une meilleure option. Je partage juste ce que j'ai utilisé dans mon code -
const mysql = require('mysql');
const config = require('config');
const pool = mysql.createPool(config.get('db.mysql'));
module.exports = {
checkConnection: () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, conn) => {
if (err) {
return reject(err);
}
resolve(conn.release());
});
});
},
pool,
closeConnection: () => pool.end(),
};
Bien sûr, vous devez d'abord le promettre, ce que vous pouvez faire depuis node 8.0.0
maintenant:
const util = require('util');
async function doSomething() {
const getConnectionAsync = util.promisify(pool.getConnection);
try {
const result = await getConnectionAsync('MASTER');
}catch(err) {
console.log('Oh no');
}
}
Si, pour une raison quelconque, vous ne pouvez pas utiliser le nœud 8 ou supérieur, il existe d'autres façons de le promettre, comme http://bluebirdjs.com/docs/api/promise.promisify.html
Je partage juste ce que j'ai toujours utilisé dans mon code:
//Filename: MySQL.js
module.exports = {
connect: function ()
{
return new Promise((resolve, reject) => {
let pool = Mysql.createPool({ //require configfile.js or just put connection detail here
connectionLimit: config.mysql.connectionLimit,
Host: config.mysql.Host,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database
});
pool.getConnection((err, connection) =>
{
try
{
if (connection)
{
resolve({"status":"success", "data":"MySQL connected.", "con":pool});
connection.release();
}
}
catch (err)
{
reject({"status":"failed", "error":`MySQL error. ${err}`});
}
resolve({"status":"failed", "error":"Error connecting to MySQL."});
});
});
}
}
Ensuite, chaque fois que vous devez appeler la connexion à MySQL
//Filename: somefile.js
const useMySQL = require('./path/to/MySQL');
module.exports = {
getSomething: function () {
return new Promise(async (resolve) => {
try
{
let connection = await useMySQL.connect();
con = connection.con;
//Do some query here, then
resolve(`Send some result/handle error`);
}
catch (err)
{
//Handle error if any, log, etc, and eventually
resolve(err);
}
});
}
J'espère que cela t'aides.