Access Multiple table concurrently Mysql Nodejs - mysql

I am trying to assing a structured array from two tables, First table select query from which the value in result fetch the ID and assing to the next query, Here is my code
var query = db.query('select * from orderdish'),
users = [];
query
.on('error', function(err)
{
console.log(err);
updateSockets(err);
})
.on('result', function(order,callback)
{
order.abc ='11';
order.OrderKOT=[];
var queryOrderKOT = db.query('select * from tblorderkot where order_Id='+ order.order_Id,function()
{
kotOrders = [];
queryOrderKOT
.on('error',function(err)
{
console.log(err);
updateSocket(err);
})
.on('result',function(orderKOT)
{
kotOrders.push(orderKOT);
})
.on('end', function()
{
console.log(kotOrders);
order.OrderKOT.push(kotOrders);
});
});
console.log(order);
users.push(order);
/* aa(function(){
});*/
})
.on('end', function()
{
// loop on itself only if there are sockets still connected
if (connectionsArray.length)
{
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
console.log("This is End Values");
updateSockets({ users: users });
}
});
It's setting order.OrderKOT to empty. I know the it got to be done with call back in query.on(result) but if I set it's not fetching me any result. Second Query queryOrderKOT is working but it's fetching value pretty late and it's not pusing value to order.OrderKOT. Suggesst me for fetching the value concurrently.

It is likely that the "end" event for the first query is occurring before the second queryOrderKot query has had a chance to complete.
You should experience the expected behavior if you move the main response logic from the "end" of query to the "end" or "result" of queryOrderKot.

After so much of head breaking finally found the solution for concurrent mysql nodejs check #kevin Reilly thanks for trying a lot. I found out what ever we tried was streaming query. Which will be do the process async. Now coming back to the callback I wrote following and it's working perfectly
var query = db.query('select * from orderdish', function (err, results, fields, callback) {
if (err) {
console.log("ERROR: " + err.message);
updateSockets(err);
}
else {
// length of results
var count = 0;
// pass the db object also if you wanna use the same instance
q2(count, results, callback);
}
});
function q2(count, results, callbacks) {
var queryOrderKOT = db.query('select * from tblorderkot where order_Id=' + results[count].order_Id, function (err, resultKOT, KOTFields, callback) {
console.log(resultKOT);
results[count].OrderKOT = resultKOT;
count++;
if (count < results.length) {
q2(count, results, callback);
}
else {
// do something that you need to do after this
console.log(results);
//callbacks(results);
}
});
}

Here is my whole Code,
var mysql = require('mysql')
var io = require('socket.io').listen(3000)
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'vsk',
database: 'hahaha'
})
var POLLING_INTERVAL = 3000, connectionsArray = [], pollingTimer;
db.connect(function (err) {
if (err) console.log(err)
})
var socketCount = 0, restID = 0;
var pollingLoop = function () {
var query = db.query('select * from orderdish'), users = [];
.on('error', function (err) {
console.log(err);
updateSockets(err);
}).on('result', function (order) {
console.log("THis is USerID" + order.order_Id);
order.abc = '11';
order.OrderKOT = [];
var queryOrderKOT = db.query('select * from tblorderkot where order_Id=' + order.order_Id);
kotOrders = [];
queryOrderKOT.on('error', function (err) {
console.log(err);
updateSocket(err);
}).on('result', function (orderKOT) {
kotOrders.push(orderKOT);
query.on('end', function () {
console.log("This is at end values");
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
console.log("This is End Values");
updateSockets({
users: users
});
}
});
}).on('end', function () {
console.log(kotOrders);
console.log("This is my KOT End");
order.OrderKOT.push(kotOrders);
users.push(order);
console.log(users);
//callback(kotOrders);
});
console.log(order);
});
};
io.sockets.on('connection', function (socket) {
console.log("New Connection Opened");
socket.on('restID', function (restIDs) {
console.log(restIDs);
restID = restIDs;
console.log('Number of connections:' + connectionsArray.length);
if (connectionsArray.length > 0) {
console.log("Here is the Pooling Loop");
pollingLoop();
}
});
socket.on('disconnect', function () {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socket = ' + socketIndex + ' disconnected');
if (socketIndex >= 0) {
connectionsArray.splice(socketIndex, 1);
}
});
connectionsArray.push(socket);
});
var updateSockets = function (data) { // adding the time of the last update data.time = new Date();
// sending new data to all the sockets connected connectionsArray.forEach(function(tmpSocket) {
// tmpSocket.volatile.emit('notification', data); console.log(data); tmpSocket.volatile.emit('notification', data); }); };

Related

Using multiple queries and render to HTML

I'm trying to complete 2 select with 2 different SQL Server queries in the same HTML.
I'm using this code to complete 1
router.js
app.get('/bajatel', function(req, res, next) {
var data = []
request.query('select NLineas from tb_lineas', function(err, fields){
if(err) {
console.log('error en la busqueda');
return;
}
console.log(fields)
// Pass the DB result to the templates
for (var i = 0; i < fields.recordset.length ; i++){
data.push({NLineas: fields.recordset[i]})
}
res.render('bajatel.html', {Valuelist: data});
console.log(data)
});
});
db.js
var sql = require('mssql');
var config = {
user : 'sa',
password : 'xxxxxxxx',
server : 'xxxxxxxx',
database : 'db_test'
};
var connection = sql.connect(config, function(err) {
if (err){
throw err ;
} else{
console.log('connected');
}
});
module.exports.connection = connection;
I want to add a second query in the app.get to have a second array:
var motivo = []
request.query('Select DescMotivo from tb_Motivos', function(err, rows){
if(err){
console.log('error en la busqueda');
return;
}
for (var i = 0; i < rows.recordset.length; i++){
motivo.push({DescMotivo: rows.recordset[i]})
}
The final render should be:
res.render('bajatel.html',{Valuelist: data, Motivolist: motivo})
but I don't know how to export the data to complete the array outside of the query.
the idea is to have 2 boxes with the queries options and they must select the default values
Could somebody help me?

How to insert json into mysql using node js?

var express = require('express');
var app=express();
var length;
var affiliate = require('flipkart-affiliate');
var url = require('url');
var moment=require('moment');
var mysql = require('mysql');
var body;
var getUrl;
var product;
var offer;
var offer1;
var offer2;
var offer3;
var test1;
var test2;
var test3;
var title=[];
var description=[];
var startTime=[];
var endTime=[];
var json={};
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'coupontest'
});
var client = affiliate.createClient({
FkAffId: 'anandhkum',
FkAffToken: 'eb030998c556443087d3b1a27ac569d0',
responseType: 'json'
});
client.getCategoryFeed({
trackingId: 'anandhkum'
}, function(err, result,getUrl){
if(!err){
body=JSON.parse(result);
getUrl=body.apiGroups.affiliate.apiListings.food_nutrition.availableVariants["v1.1.0"].get;
client.getProductsFeed({
url: getUrl
}, function(err, result){
if(!err){
}else {
console.log(err);
}
});
}
});
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
app.get('/',function (req,res) {
client.getAllOffers(null,function(err, resp) {
if (!err) {
offer = JSON.parse(resp);
test1 = offer.allOffersList.length;
res.send(offer);
for(var i=0;i<test1;i++){
description[i]=offer.allOffersList[i].description;
startTime[i]=offer.allOffersList[i].startTime;
endTime[i]=offer.allOffersList[i].endTime;
}
var stmt = "INSERT INTO offers(description,start_time,end_time) VALUES (?, ?, ?)";
connection.query(stmt, [description,startTime,endTime], function (err, result) {
if (err) throw err.message;
console.log("Number of records inserted: " + result.affectedRows);
});
}
else {
console.log(err);
}
});
});
app.listen(3000);
console.log("Listening to port 3000");
the code is about getting the offer details as json data from flipkart.com and store it into the mysql table.
But I'm getting the error
throw err; // Rethrow non-MySQL errors
ER_WRONG_VALUE_COUNT_ON_ROW: Column count doesn't match value count at row 1
I tried using many sql syntax but it's showing the above error
Can anyone help me on solving the above error?
Try doing it this way, as I can see you want to insert multiple result at once so need to pass an array values which I have made in following query also the error "ER_WRONG_VALUE_COUNT_ON_ROW" is due to incorrect no of ? that you were passing in the query as you need to insert multiple no of rows so you need to make sure you get correct ? count.
var queryString = "";
var insertString = "(?,?,?),";
var values = [];
for(var i=0;i<test1;i++){
description[i]=offer.allOffersList[i].description;
startTime[i]=offer.allOffersList[i].startTime;
endTime[i]=offer.allOffersList[i].endTime;
values.push(description[i],startTime[i],endTime[i]);
queryString = queryString + insertString;
}
queryString = queryString.substring(0, queryString.length - 1); // is used to remove last ',' which will get inserted while we are creating queryString
var stmt = "INSERT INTO offers(description,start_time,end_time) VALUES " + queryString ;
connection.query(stmt,values, function (err, result) {
if (err) throw err.message;
console.log("Number of records inserted: " + result.affectedRows);
});

variable value becomes undefined in NodeJS ExpressJS

I am working with NodeJS using ExpressJS framework in a mysql backend. I am running a query inside a for loop and my loop and work afterwards depends on the return value of the query. I am not very good with mysql query so I am running it through a for loop.
The problem is, due asynchronous [I guess!], the for loop ends long before the query result comes out.
Here is my code:
function search_people_step2(user_id, search_criteria, user_friend)
{
var first_name_friends = [];
var last_name_friends = [];
for(var i = 0; i < user_friend.length; i++)
{
con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
{
if(err)
{
//error;
}
else
{
if(rows.length == 0)
{
//nothing gets returned
}
else {
console.log(rows);
first_name_friends[i] = rows[0].first_name;
last_name_friends[i] = rows[0].second_name;
}
}
});
}
Now,I can get the value (using console.log) inside the query statement, however, on the outside, the value becomes empty (undefined) since the rest of the code has already been computed.
How can I solve this?
Thanks in advance.
The first thing that I find weird in your code is that you are not using an IN statement in your SQL query (not directly related to your problem though) which means you are making as many requests as there are entries in user_friend. The problem is that the SQL library is implemented asynchronously and you cannot avoid it. BUT you can handle it elegantly with Promises which are ES6 features:
(I didn't test the code but I think it should work)
function search_people_step2(user_id, search_criteria, user_friend)
{
return new Promise((resolve,reject)=>{
var first_name_friends = [];
var last_name_friends = [];
var placeHolders=user_friend.map(()=>"?").join(",");
con.query("SELECT first_name, second_name FROM user WHERE userid IN ("+placeHolders+")",user_friend,(err,rows)=>{
if(err)
reject(err);
else{
rows.forEach(row=>{
first_name_friends.push(row.first_name);
last_name_friends.push(row.second_name);
});
resolve({first_name_friends,last_name_friends});
}
});
});
}
And call your function like this :
search_people_step2(id,crit,friends).then(result=>{
//handle result asynchronously as there is no choice
console.log(result.first_name_friends);
console.log(result.last_name_friends);
}).catch(err=>{
//handle error
});
You are right, your problem is the asynchronous nature of the mysql call. You have to provide a callback to your search_people_step2 function.
You may change it like this:
search_people_step2(user_id, search_criteria, user_friend, callback)
In your function body you may use a library called async to handle all the callbacks properly. Here is an example for the usage:
async.eachSeries(user_friend, function(item, eachCb){
con.query("SELECT first_name, second_name FROM user WHERE userid = ?",
user_friend[i],function(err, rows) {
if(err) {
eachCb('error');
}
else {
if(rows.length == 0){
//nothing gets returned
eachCb(null);
}
else {
console.log(rows);
first_name_friends.push(rows[0].first_name);
last_name_friends.push(rows[0].second_name);
eachCb(null);
}
}
}, callback);
});
This calls each query in order on every item of the array and calls the inner callback if finished. When all items are processed or an error occured the outer callback is called. See the async library for further documentation.
simplest solution is
function search_people_step2(user_id, search_criteria, user_friend)
{
var first_name_friends = [];
var last_name_friends = [];
for(var i = 0; i < user_friend.length; i++)
{
con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
{
if(err)
{
//error;
}
else
{
if(rows.length == 0)
{
//nothing gets returned
}
else {
console.log(rows);
first_name_friends[i] = rows[0].first_name;
last_name_friends[i] = rows[0].second_name;
}
if(i==user_friend.length-1){
//do your work here which you want to perform in end
}
}
});
}
or use async library
var async = require('async');
var first_name_friends = [];
var last_name_friends = [];
async.series([function(cb){
function search_people_step2(user_id, search_criteria, user_friend)
{
for(var i = 0; i < user_friend.length; i++)
{
con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
{
if(err)
{
//error;
}
else
{
if(rows.length == 0)
{
//nothing gets returned
}
else {
console.log(rows);
first_name_friends[i] = rows[0].first_name;
last_name_friends[i] = rows[0].second_name;
}
if(i==user_friend.length-1){
cb()
}
}
});
}
},function(cb){
//do your work here
}],function(err){})

How to handle nodejs async with mysql?

Community,
I am new at nodejs and now i have a problem i cant solve: The async in javascript/nodejs. How can i handle the following so i can push the usernames to the array?
I already tried to help myself with many different functions but nothing works for me... :/
Sincerely Adhskid.
function getCurrentBetInformations () {
connection.query('SELECT * FROM `BETS` WHERE BET_ACTIVE = "1" LIMIT 1', function(err, rowss, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
betid = rowss[0].BET_ID;
betends = rowss[0].BET_END;
connection.query('SELECT * FROM `BETS_BID` WHERE BID_BET_ID=\'' + betid + '\'', function(err, betbids, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
var betQuants = new Array();
var betIds = new Array();
var betUsernames = new Array();
var betDates = new Array();
var rowsAffected = betbids.length;
for(i=0; i < rowsAffected; i++) {
betQuants.push(betbids[i].BID_KEYS_COUNT);
betIds.push(betbids[i].BID_ID);
var betSender = betbids[i].BID_SENDER;
connection.query('SELECT `USER_NAME` FROM `USER` WHERE `USER_STEAMID` = \'' + betSender + '\' LIMIT 1', function(err, rows, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
console.log(rows[0].USER_NAME);
addUsername(rows[0].USER_NAME);
});
function addUsername (currentUsername) {
betUsernames.push(currentUsername);
}
betDates.push(betbids[i].BID_TIME);
if(betUsernames.length === i) {
execSiteRef();
}
}
function execSiteRef() {
console.log(betUsernames);
sendUserSiteRefresh([betQuants, betIds, betUsernames, betDates], betends);
}
});
});
}
I think your problem comes from this part:
if(betUsernames.length === i) {
execSiteRef();
}
You should iinstead check if the betUsernames array is of the final size:
if(betUsernames.length === rowsAffected) {
execSiteRef();
}
maybe there is more errors though, I did not check closely.

NodeJS and MySQL: getting array data inside query callback

I'm trying to run this piece of code:
setInterval(function () {
var params = {
QueueUrl: 'https://sqs.us-east-1.amazonaws.com/821808622769/Teste', // required
MaxNumberOfMessages: 10
};
sqs.receiveMessage(params, function (err, data) {
if (err)
console.log('Erro de SQS:' + err);
else {
var retorno = data.Messages;
for (var i in data.Messages) {
var queryString = 'SELECT now()'; //dummy query, just for tests
db_connection.query(queryString, null, function (err, rows, fields) {
if (err) {
console.log('Erro no BD:' + err);
return;
}
var date = new Date();
console.log(retorno[i].Body + ' ' + date.getTime().toString());
});
}
console.log();
}
});
}, 30000);
and I have 5 messages in AWS SQS, such as this:
but when I run my code, instead of having the retorno[i].Body of each message, sometimes I get a message repeated, as show in this image
My for loop is running from 1 to 5 queries, but how do I carry the retorno[i] inside the callback to the database query? I mean, how do I identify which message I was dealing with?
Using .bind() you can setting the internal version of i to be the same as the version of i in your loop.
.bind({i:i}) at the end of your callback and change the internal code to reference this.i
for (var i in data.Messages) {
var queryString = 'SELECT now()'; //dummy query, just for tests
db_connection.query(queryString, null, function(err, rows, fields) {
if (err) {
console.log('Erro no BD:' + err);
return;
}
var date = new Date();
console.log(retorno[this.i].Body + ' ' + date.getTime().toString());
}.bind({
i: i
});
}
}