how to block nodejs for result of query - node.js

I am pretty new to nodejs.
What I want my code to do it to query a database a number of times, collect data from all the queries in one variable and then use it somewhere.
But I guess nodejs instead of waiting for the result of the queries, execute without blocking.
This is what I think is happening. Sorry if I am wrong.
for (var i = step_min; i < (step_max); i += step) {
query = 'select count(' + colName + ') as num_count from ' +
rows[0].tablename + ' where ' + 'dictionaryid=' +
rows[0].dictionaryid + ' and ' + colName + ' between ' + i +
' and ' + (i + step);
connection.query(query, function(err, rows1, fields) {
if (err) {
console.log(err);
throw err;
}
try {
console.log("$$$$$$$$$$$$$$$ pushed : "+ rows1[0].num_count);
contents.push(rows1[0].num_count);
console.log('contents : '+ contents+'\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
}
});
console.log("##################### " + query + "\n");
console.log('contents : '+ contents+'\n');
}
Any advice either on how to block nodejs till the result from query is obtained or otherwise a way to restructure my code ?
Thanks in advance.

You are correct that it is not waiting for your queries before executing. You can look at the node-mysql-queues module which you can use to queue queries, and execute the given callback after all have executed (it will also allow you do perform transactions)
Another (hack) approach is to set a counter of the number of queries you are executing. In the callback of each transaction save the result into your return object and decrement the counter. If it is <= 0 then all your queries have completed, and you can execute your main callback with the return object.
Also, watch out for SQL injection.

try this:
https://github.com/luciotato/waitfor
your code with wait.for:
for (var i = step_min; i < (step_max); i += step) {
query = 'select count(' + colName + ') as num_count from ' +
rows[0].tablename + ' where ' + 'dictionaryid=' +
rows[0].dictionaryid + ' and ' + colName + ' between ' + i +
' and ' + (i + step);
var rows1 = wait.forMethod(connection,"query",query); //waits until callback
console.log("$$$$$$$$$$$$$$$ pushed : "+ rows1[0].num_count);
contents.push(rows1[0].num_count);
}
console.log("##################### " + query + "\n");
console.log('contents : '+ contents+'\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
....
}

Doing something like below could be a work around.
//Its just a test code whatever came to mind first so I'll tune it later...
var contents = [];
var lock = 0;
for (var i = step_min; i < (step_max + step); i += step) {
lock++;
}
for (var i = step_min; i < (step_max + step); i += step) {
query = 'select count(' + colName + ') as num_count from ' + rows[0].tablename + ' where ' + 'dictionaryid=' + rows[0].dictionaryid + ' and ' + colName + ' between ' + i + ' and ' + (i + step);
connection.query(query, function(err, rows1, fields) {
if (err) {
console.log(err);
throw err;
}
try {
console.log("$$$$$$$$$$$$$$$ pushed : " + rows1[0].num_count);
contents.push(rows1[0].num_count);
console.log('contents : ' + contents + '\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
}
lock--;
if (lock == 0) {
queryDone();
}
});
}
function queryDone() {
console.log("##################### " + query + "\n");
console.log('contents : ' + contents + '\n');
var id = obj.exptID + '.' + obj.exptITR + '.' + obj.nodeID + '.' + obj.resourceName + '.' + colName;
serie = {
name: colName,
data: contents,
id: id
};
console.log("--------------------\n " + step_max + "\n" + step_min + "\n------------------------\n");
}
The approach is to fire a function when all queries are done as Nick said...

Related

Node.JS - calling function that may need to recall itself during SQL- Unsure

So im working on a node.js function that when called with a partnumber it then calls an SQL query to find details in a SQL database where this partnumber exists.
I am then aiming to check the results and if there is a field for supercessions then I rerun the same function with the new 'partnumber' being the supercession. I completed this in PHP but I'm working on reworking for node.js and I'm struggling on getting the row data to finally return. I can get the console logs to show whats needed but I think I'm not returning it correctly.
PHP example:
function sscheck($partnumber)
{
$partnumber = str_replace('-', '', $partnumber);
if(!isset($con))
{
$con = setConOld();
}
if($stmt = $con->prepare("SELECT partnumber, partsupercession, altpartnumber, rrp, vatcode, salescode FROM pfk_kop.pfk_chkprice WHERE partnumber = ? LIMIT 1"))
{
$stmt->bind_param('s', $partnumber);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($pn, $ss, $altpn, $rrp, $vatcode, $salescode);
$stmt->fetch();
if($salescode == "1")
{
if($ss != "")
{
$con->close();
return sscheck($ss);
}
$con->close();
return array($pn, $ss, $altpn, $rrp, $vatcode, $salescode);
}
$con->close();
return array($pn, $ss, $altpn, $rrp, $vatcode, $salescode);
}
$con->close();
return array("N/A", "N/A", "N/A", "N/A", "N/A", "N/A");
}
and the existing function I have for node.js which is messy is:
function getSupercession($partnumber){
if ($partnumber != "") {
console.log("partnumber Received correctly - " + $partnumber)
}
var results
var connection = getKawasakiSupConnection();
var query_str = "SELECT altpartnumber, rrp, vatcode, salescode, partsupercession, partnumber FROM pfk_kop.pfk_chkprice WHERE partnumber = '" + $partnumber + "' LIMIT 1";
var query_var = [$partnumber];
console.log("Query Generated - " + query_str)
connection.query(query_str, query_var, results = function (err, rows) {
//if (err) throw err;
if (err) {
//throw err;
console.log(err);
logger.info(err);
next(err);
}
else {
// handle your data
console.log("I think we fetched supercessions successfully");
var sc = rows[0].salescode
var ss = rows[0].partsupercession
var pn = rows[0].partnumber
console.log("1- I think the details are " + sc + ss + pn);
if (sc == "1"){
if (ss != ""){
return getSupercession(ss);
} else {
console.log("2- I think the details are " + sc + ss + pn);
return rows;
}
} else {
console.log("3- I think the details are " + sc + ss + pn);
return rows;
}
}
});
}
Any help on this or questions would be greatly appreciated. I think I've been staring too much at a screen :D

Node JS Discord Log guildMemberUpdate

I have tried various things and there are no errors but my bot has no response I tried to change my nickname, avatar, etc. there is no response here I am using node js please help me following my sample code. but when I attempt to carry it over to role adding and deletion, usernames, nicknames, and avatar changes, the bot fails to log this and crashes. How do I fix this issue within my code?
//declare changes
var Changes = {
unknown: 0,
addedRole: 1,
removedRole: 2,
username: 3,
nickname: 4,
avatar: 5
};
var change = Changes.unknown;
//check if roles were removed
var removedRole = '';
oldMember.roles.every(function(value) {
if(newMember.roles.find('id', value.id) == null) {
change = Changes.removedRole;
removedRole = value.name;
}
});
//check if roles were added
var addedRole = '';
newMember.roles.every(function(value) {
if(oldMember.roles.find('id', value.id) == null) {
change = Changes.addedRole;
addedRole = value.name;
}
});
//check if username changed
if(newMember.user.username != oldMember.user.username)
change = Changes.username;
//check if nickname changed
if(newMember.nickname != oldMember.nickname)
change = Changes.nickname;
//check if avatar changed
if(newMember.user.displayAvatarURL != oldMember.user.displayAvatarURL)
change = Changes.avatar;
//post in the guild's log channel
var log = newMember.guild.channels.cache.get("channelID")
if (log != null) {
switch(change) {
case Changes.unknown:
log.send('**[User Update]** ' + newMember);
break;
case Changes.addedRole:
log.send('**[User Role Added]** ' + newMember + ': ' + addedRole);
break;
case Changes.removedRole:
log.send('**[User Role Removed]** ' + newMember + ': ' + removedRole);
break;
case Changes.username:
log.send('**[User Username Changed]** ' + newMember + ': Username changed from ' +
oldMember.user.username + '#' + oldMember.user.discriminator + ' to ' +
newMember.user.username + '#' + newMember.user.discriminator);
break;
case Changes.nickname:
log.send('**[User Nickname Changed]** ' + newMember + ': ' +
(oldMember.nickname != null ? 'Changed nickname from ' + oldMember.nickname +
+ newMember.nickname : 'Set nickname') + ' to ' +
(newMember.nickname != null ? newMember.nickname + '.' : 'original username.'));
break;
case Changes.avatar:
log.send('**[User Avatar Changed]** ' + newMember);
break;
}
}
})

* Suitescript 2.0 * How can update the status of a custom record from Map Reduce script?

So all i want to do is if the m/r script fails, update the corresponding dropdown value on custom record from m/r script.
How to do this in SuiteScript 2.0
You can use the summary step to get the errors that occurred in your Map Reduce script. The following code should help you achieve this:
function summarize(summary) {
handleErrors(summary);
handleSummaryOutput(summary.output);
//*********** HELPER FUNCTIONS ***********
function handleErrors(summary) {
var errorsArray = getErrorsArray(summary);
if(!errorsArray || !errorsArray.length){
log.debug('No errors encountered');
return;
}
for (var i in errorsArray) {
log.error('Error ' + i, errorsArray[i]);
}
if(errorsArray && errorsArray.length){
//
//INSERT YOUR CODE HERE
//
}
return errorsArray;
//*********** HELPER FUNCTIONS ***********
function getErrorsArray(summary){
var errorsArray = [];
if (summary.inputSummary.error){
log.audit('Input Error', summary.inputSummary.error);
errorsArray.push('Input Error | MSG: ' + summary.inputSummary.error);
}
summary.mapSummary.errors.iterator().each(function (key, e){
var errorString = getErrorString(e);
log.audit('Map Error', 'KEY: ' + key + ' | ERROR: ' + errorString);
errorsArray.push('Map Error | KEY: ' + key + ' | ERROR: ' + errorString);
return true; //Must return true to keep looping
});
summary.reduceSummary.errors.iterator().each(function (key, e){
var errorString = getErrorString(e);
log.audit('Reduce Error', 'KEY: ' + key + ' | MSG: ' + errorString);
errorsArray.push('Reduce Error | KEY: ' + key + ' | MSG: ' + errorString);
return true; //Must return true to keep looping
});
return errorsArray;
//*********** HELPER FUNCTIONS ***********
function getErrorString(e){
var errorString = '';
var errorObj = JSON.parse(e);
if (errorObj.type == 'error.SuiteScriptError' || errorObj.type == 'error.UserEventError'){
errorString = errorObj.name + ': ' + errorObj.message;
} else {
errorString = e;
}
return errorString;
}
}
}
function handleSummaryOutput(output){
var contents = '';
output.iterator().each(function (key, value){
contents += (key + ' ' + value + '\n');
return true;
});
if(contents){
log.debug('output', contents);
}
}
}

Asterisk 11 active calls event over AMI

Data I would like to have:
Num From , Num To , Duration, Codec, Context, Hold status
ofc in realtime update
I using node.js + nami
what the best way to get this information?
tried use an action Status(), but this gives me not full information about call and if I run it every second browser dies.
here is what I have:
updateCallList();
function updateCallList() {
socket.emit('GET_ACTIVE_CALLS', function(calls) {
$("#callsList").find("tr:gt(0)").remove();
if (calls.response != 'Success') return;
var calls = calls.events;
for (call in calls) {
if (calls[call].privilege == 'Call') {
var callFrom = calls[call].calleridnum + '<' + calls[call].calleridname + '>';
var callTo = calls[call].extension;
var callDuration = calls[call].seconds;
var callRoute = calls[call].context;
var tmpRow = '<tr>';
tmpRow = tmpRow + '<td>' + callFrom + '</td>';
tmpRow = tmpRow + '<td>' + callTo + '</td>';
tmpRow = tmpRow + '<td>' + callDuration + '</td>';
tmpRow = tmpRow + '<td>' + callRoute + '</td>';
tmpRow = tmpRow + '</tr>';
$('#callsList tr:last').after(tmpRow);
}
}
setInterval(function(){
updateCallList();
},1000);
});
}
server side
socket.on('GET_ACTIVE_CALLS', function (callback) {
action = new namiLib.Actions.Status();
nami.send(action, function (response) {
callback(response);
});
});
You need start daemon which will collect NewExten, Link, Unlink, Hangup events and create list of channels.
http://www.voip-info.org/wiki/view/asterisk+manager+events
Also you can do action command with "core show channels" "core show channel XXXXX", but asterisk will die if you do alot of that.
http://www.voip-info.org/wiki/view/Asterisk+Manager+API+Action+Command

NodeJs looping through object variables behaving strange

I am running mysql selects from within a loop, for some reason my variables are being overwritten..
My code below:
setInterval(function () {
for (var s in _bots) {
if (_bots.hasOwnProperty(s)) {
var obj = _bots[s];
for (var prop in obj) {
console.log(' ----- ' + _bots[s][prop].channel + ' ----- ');
channel = _bots[s][prop].channel;
cc = s;
dd = prop;
var sql = 'SELECT * FROM `usrs` WHERE cID = ' + connection.escape(_bots[s][prop].channel) + ' LIMIT 1';
connection.query(sql, function(err, results) {
if(results.length != 0) {
console.log('NAME ---> ' + cc);
console.log('MSG_TO ---> ' + dd);
console.log('ID ---> ' + channel);
} else {
//....
}
});
}
}
}
}, 15000)
Problem is that NAME --> MSG_TO --> variables (cc, dd and channel) always hold the last values from the object. For some reason they are overwriten.. Strangely i am not allowed to use for example s and prop inside the mysql select function.
I need a way to be able to use the s and prop inside the mysql select from the loop
Any ideas?
This is expected behavior. Each pass of your for..in loop defines a closure, and all the closures reference the same function scope in their scope chains. While cc, dd, and channel are all variables in this scope, of course you get same output.
If you want different output, you have to bind these variables to the function before their values were changed. Try:
connection.query(sql, function(cc, dd, channel, err, results) {
if(results.length != 0) {
console.log('NAME ---> ' + cc);
console.log('MSG_TO ---> ' + dd);
console.log('ID ---> ' + channel);
} else {
//....
}
}.bind(null, cc, dd, channel)); // bind the values here

Resources