0

I have a NodeJS API which was using 'normal connections' to a MYSQL DB and running well execpt I was having disconnect issues. I have implemented pooling now and that is working however it seems some code is now running out of order due to the new nature of the connections.

I've never used async/await as I'm very new to coding but I've tried to do it here to get the response I need. Pretty much I have put in console logs to see the order it is running and instead of gettting "1,2,3", I'm getting "2,3,1" which obviously is going to give me the wrong results as I need to get query data before proceeding.

Can someone show how to get this await system working? The first section gets the MAC and ID from the user and then checks if this exists in my DB already. If it does then it updates the dateTime of recent login. If it Doesnt then it adds the MAC.

The issue is that I'm not getting my response regarding if the mac exists, so it always is "false" therefore the mac keeps getting added over and over as the it isnt waiting for the very first query result!

router.post('/updateComp/',verify,async (req,res) => {    
    //console.log(req.params.MAC)
       
    var sqlString = "SET @chemistID = ?; SET @MAC = ?; Call checkMAC(@chemistID,@MAC)";
    try{
        const MAC = req.body.MAC;;
        const compName = req.body.compName;
        var compCount = 0;
        var MACExists = false;
        
        console.log(MAC + " " + compName);
        await connection.query(sqlString,[req.user._id,MAC], (err,rows,fields)=>{
            console.log("Check 1"); 
            if(!err){
                
                rows.forEach(element => {
                
                    if(element.constructor == Array){
                        compCount =  element[0].compCount;
                        MACExists =  element[0].MACExists; 
                        console.log(compCount);                    
                        console.log(MACExists);
                    }
                    else{
                    //array not returned?
                    return res.status(500);
                    }
                })    
                
            }else{
                //sql con error?
                return res.status(500);
            }
            console.log("comcount = " + compCount);
        })
        console.log("Check 2");   
        
        if(compCount == 0 || (compCount < 7 && MACExists == false)){
            //Insert new comp
            var sqlString = "INSERT INTO tblLicense (chemistID,compName,MAC,lastAccess) VALUES (?,?,?,current_timestamp());";
            console.log("Check 3");

                connection.query(sqlString,[req.user._id,compName,MAC], (err,rows,fields)=>{
                    if(!err){
                        console.log("New terminal added for " + req.user._id);
                        return res.status(200).json({
                            Result: true,
                            compAdded: true
                        })

                    }else{
                        console.log("Failed to add new computer to sub " + req.user._id);
                        return res.status(500).json({
                            Result: false,
                            compAdded: false,
                            Comment: "Failed to add new computer to sub"                            
                        })
                    }
                })

        }else{
            if (compCount == 7){
                if(MACExists){
                    return res.status(200).json({
                        Result: true                        
                    })
                }else{
                    return res.status(200).json({

                        Result: false,
                        compAdded: false,
                        Comment: compCount
                    })
                }
                
            }else{
                //Update time of current comp access
                var sqlString = "UPDATE tblLicense SET lastAccess = current_timestamp() WHERE MAC = ? AND chemistID = ?;";

                connection.query(sqlString,[MAC,req.user._id], (err,rows,fields)=>{
                    if(!err){
                        return res.status(200).json({

                            Result: true,
                            compAdded: false
                        })

                    }
                    else
                    {
                        return res.status(500).json({

                            Result: false,
                            compAdded: false                            
                        })
                    }
                })
            }
        }
    } catch (e) {
        // this catches any exception in this scope or await rejection
        console.log(e);
        res.status(500).json({ Result: e });
    }  
});

Connection Config:

const mysql = require('mysql');

  var pool = mysql.createPool({    
    host:'localhost',
    user: '1234',
    password: '1234',
    database : '1234',
    multipleStatements: true,
    connectionLimit: 10
});
  
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
})  


module.exports ={
     connection : pool 
} 
Glenn Angel
  • 381
  • 1
  • 3
  • 14
  • 1
    Check what the execution of `connection.query` is returning. I see your are doing `connection.query(param1, param2, callback)`, usually when you switch to async/await means you switch from a callback to a Promise. For the await to work in the way you want `connection.query(...params)` needs to return a Promise. If you can share what connection.query looks like I can help you further – Nicolas Castellanos Jan 20 '21 at 03:09
  • Thanks @NicolasCastellanos, updating now – Glenn Angel Jan 20 '21 at 03:13

1 Answers1

1

Checking https://github.com/mysqljs/mysql doesn't seem connection.query ever returns a Promise.

You can still use async/await by wrapping connection.query inside a promise.

Here's a post that explains how to do it https://medium.com/wenchin-rolls-around/example-of-using-transactions-with-async-await-via-mysql-connection-pool-9a37092f226f

And looks like another option is to use Bluebird How to promisify a MySql function using bluebird?

  • 1
    wow... looks complicated for such a small issue in only one place of my code :( THanks Ill have to really understand before implementing – Glenn Angel Jan 20 '21 at 03:44
  • 1
    @GlennAngel I wrote a [blogpost](https://evertpot.com/executing-a-mysql-query-in-nodejs/) after reading a lot of questions such as yours. There are better ways. Don't use bluebird in 2021. – Evert Jan 20 '21 at 05:19