I'm working on some scripts to be hosted on the AWS Lambda service. I chose Node.js because I'm okay with JS but I've not learned Python or Java. However it's proving to be a nightmare because I need to query a MySQL database and I just cannot figure out how to get the result out of the function correctly.
So basically I have something like this (I've cut some stuff out but you should get the idea), and this is all I want to do. I want to be able to query the MySQL database and when it has an answer simply return it or throw if there was an error.
var mysql = require("mysql"); //npm installed module "mysql"
var err = require("./errors.js"); //internally requires npm installed module "errors"
var main = function(event, context, callback){
try{
//Confidential
var data = null;
//Confidential
try{
data = databaseCommand("SELECT * FROM `<table>` WHERE <field> = <value>");
}
catch(e){
if(e instanceof err.Database)
//Return state that indicates "Internal server error".
else
throw e;
return
}
//Do maths on data
//Return "OK" and result
}
catch(e){
//Return "Unkown error"
}
};
var databaseCommand = function(cmdString){
if(typeof cmdString !== "string") throw new err.InputInvalidType({explanation: "'cmdString' is of type '" + typeof cmdString + "', expected type 'string'"});
var connection = mysql.createConnection({
host: process.env.db_host,
port: process.env.db_port || 3306,
user: process.env.db_username,
password: process.env.db_password,
database: process.env.db_database
});
var ret = {
error: null,
result: null
};
//I cut out the connection.connect() because it can be implied and I'm confused enough
connection.query(cmdString, function(error, rows){
if(error)
ret.error = error;
else
ret.result = rows;
});
connection.end();
if(ret.error)
throw new err.Database();
return ret.result;
};
But for those who are versed in Node.js obviously this doesn't work because the call to connection.query is asynchronous, so my databaseCommand function always returns null (and doesn't throw) and causes errors in my main function.
Please help me understand how I can perform a basic synchronous request like this.
EDIT
I've seen "solutions" on using async methods that show something like (I probably have this wrong) the following changes, but I don't see how this is any different.
var mysql = require("mysql"); //npm installed module "mysql"
var err = require("./errors.js"); //internally requires npm installed module "errors"
var main = function(event, context, callback){
try{
//Confidential
var data = null;
//Confidential
try{
databaseCommand("SELECT * FROM `<table>` WHERE <field> = <value>", function(err, result){
if(err)
throw err;
data = result;
});
//This function will still return before data is set
//Maths will still be performed before data is set
}
catch(e){
if(e instanceof err.Database)
//Return state that indicates "Internal server error".
else
throw e;
return
}
//Do maths on data
//Return result
}
catch(e){
//Return "Unkown error"
}
}
var databaseCommand = function(cmdString, callback){
if(typeof cmdString !== "string") throw new err.InputInvalidType({explanation: "'cmdString' is of type '" + typeof cmdString + "', expected type 'string'"});
var connection = mysql.createConnection({
host: process.env.db_host,
port: process.env.db_port || 3306,
user: process.env.db_username,
password: process.env.db_password,
database: process.env.db_database
});
var ret = {
error: null,
result: null
};
//I cut out the connection.connect() because it can be implied and I'm confused enough
connection.query(cmdString, function(error, rows){
if(error)
callback(err, null);
else
callback(null, rows);
});
connection.end();
}