Node.js synchronously with mysql query - mysql

I am trying to implement a synchronous query in mysql with node.js, I tried several ways and did not succeed
I am new to node.js
I use express.js
connection.js
var mysql = require('mysql');
var connMySql = function() {
return mysql.createConnection({
host : 'localhost',
user : 'root',
password : '******',
database : 'ress'
});
}
module.exports = function() {
return connMySql;
}
DAO.js
function UserDAO(connection){
this._connection = connection();
}
UserDAO.prototype.createUser = function (user, callback){
var sql = "insert into... ";
this._connection.query(sql, function(err, result){
//console.log(result)
//console.log()
if (err){
callback(err,false )
}
if (result){
var newI = result.insertId
var sqlOther = "insert into ..... ";
this._connection.query(sql, function(err, result){
if (err){
callback(err,false )
}else if (result.length > 0){
callback(false, result.insertId)
}
});
}
});
}
I try implements await, async and Promisse(.then) but no success.
What I need to make calls synchronously and return insert id?
thanks

From mysql repo I see that you're missing connection.connect()

connection.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '******',
database : 'ress'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
DAO _connection must be closed when it's done with it's job
UserDAO.prototype.createUser = function (user, callback){
var sql = "insert into... ";
this._connection.query(sql, function(err, result){
//console.log(result)
//console.log()
if (err){
callback(err,false )
this._connection.end();
}
if (result){
var newI = result.insertId
var sqlOther = "insert into ..... ";
this._connection.query(sql, function(err, result){
if (err){
callback(err,false )
} else if (result.length > 0){
callback(false, result.insertId)
}
this._connection.end();
});
}
});
}

Related

How to make return wait for MySQL connection to end? Node.js

I'm new to Node.js I'm testing some code on Wix to check my database if a account name already exists prior to allowing a new one to be created (I'm purposely not using the WHERE tag at the moment for learning purposes).
Currently the method check account name returns before the connection finishes, not allowing the check to take place properly.
Any help appreciated.
export function tryToCreateAccount(login, password)
{
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'host',
user: 'user',
password: 'pass',
database: 'db'
});
if(checkAccountName(login, connection))
{
console.log("Name didn't exist.");
}
else
{
console.log("Name Existed.");
}
}
function checkAccountName(account_name, connection)
{
var accountNameAvailable = true;
connection.connect(function (err)
{
if(err) throw err;
connection.query("SELECT login FROM accounts", function (err, result)
{
if (err) throw err;
for(var i = 0; i < result.length ; i++)
{
if(result[i].login == account_name)
{
console.log("Should of been false");
connection.end;
accountNameAvailable = false;
}
}
});
connection.end;
});
return accountNameAvailable;
}
I figured out why it wasn't doing anything, the next was getting called too late since the connection ended and next was within the connection code block.
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'host',
user: 'user',
password: 'pass',
database: 'db'
});
export function tryToCreateAccount(login, password)
{
checkAccountName(login, connection, function(err, accountNameAvailable)
{
if(err || !accountNameAvailable){
console.log("Name didn't exist.");
}
else
{
console.log("Name Existed.");
}
})
}
function checkAccountName(login, connection, next)
{
var accountNameAvailable = false;
connection.connect(function (err)
{
if(err) next(err);
connection.query("SELECT login FROM accounts", function (err, result){
if (err) next(err);
for(var i = 0; i < result.length ; i++)
{
if(result[i].login == login)
{
accountNameAvailable = true;
}
}
next(null, accountNameAvailable);
connection.end();
});
});
}
Welcome to Node.js (and the world of Async functions (and Promises (and Callbacks)))
I've written this in the "callback" style, but I highly recommend looking into async/await for something like this, as well as understanding how "promises" fit into the picture.
// to test, call tryToCreateAccount('login','pass',function(err,data){console.log(err,data)});
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'host',
user: 'user',
password: 'pass',
database: 'db'
});
export function tryToCreateAccount(login, password, next)
{
checkAccountName(login, connection, function(err, accountNameAvailable){
if(err || !accountNameAvailable){
console.log("Name didn't exist.");
next(err || 'Name didn't exist.')
}
else
{
console.log("Name Existed.");
next(null, true)
}
})
}
function checkAccountName(account_name, connection, next)
{
var accountNameAvailable = false;
connection.connect(function (err)
{
if(err) next(err);
connection.query("SELECT login FROM accounts", function (err, result){
if (err) next(err);
for(var i = 0; i < result.length ; i++)
{
if(result[i].login == account_name)
{
console.log("Should of been false");
connection.end;
accountNameAvailable = true;
}
}
connection.end();
next(null, accountNameAvailable);
});
});
}

nodejs mysql module errors

I have a nodejs module which get result from a mysql database and insert into another mysql database within a given interval. After few queries it just get stuck and throw "ER_CON_COUNT_ERROR" and says Too many connections. My module is as follows:
function get_data() {
const mysql = require('mysql');
const moment = require('moment');
var items_per_query = 1000;
let to_connection = mysql.createConnection({
host: 'localhost',
user: 'username',
password: 'pass',
database: 'todatabase'
});
let from_connection = mysql.createConnection({
host: 'localhost',
user: 'username',
password: 'pass',
database: 'fromdatabase'
});
from_connection.query("SELECT p.*, d.uniqueid as imei FROM tc_positions p left join tc_devices d on d.id = p.deviceid order by p.id desc limit " + items_per_query, function (err, result, fields) {
if (err) throw err;
var items = [];
var table_columns_list = {};
if (Object.keys(result).length > 0) {
Object.keys(result).forEach(function (key) {
var x = result[key];
table_columns_list = {
'dt_server': moment(x['servertime']).format('YYYY-MM-DD HH:MM:ss'),
'dt_tracker': moment(x['devicetime']).format('YYYY-MM-DD HH:MM:ss'),
'lat': x['latitude'],
'long': x['longitude'],
'altitude': x['altitude'],
'angle': x['course'],
'speed': x['speed'],
'params': x['attributes'],
'fix_time': moment(x['fixtime']).format('YYYY-MM-DD HH:MM:ss'),
'accuracy': x['accuracy'],
'network': x['network']
}
items.push({ 'id': x['id'], 'table_name': 'table_' + x['imei'], 'table_columns': table_columns_list });
});
}
if (items.length >=500) {
var items_to_be_removed = [];
var total_rows_inserted = 0;
for (var x = 0; x < items.length; x++) {
to_connection.query(imei_insert, function (err, results, fields) {
if (err) {
console.log(err.message);
}
else {
let createTable = " create table if not exists .... ";
to_connection.query(createTable, function (err, results, fields) {
if (err) {
console.log(err.message);
}
else {
let insert_data = "INSERT INTO .... ";
to_connection.query(insert_data, function (err, results, fields) {
if (err) {
console.log(err.message);
}
total_rows_inserted++;
items_to_be_removed.push(row_id);
if (total_rows_inserted == items.length) {
//remove data from traccar positions table that were inserted to platform
var ids = items_to_be_removed.join(",");
from_connection.query("DELETE FROM tc_positions where id IN(" + ids + ")", function (err, results, fields) {
if (err) throw err;
console.log('removed ' + total_rows_inserted + ' rows from traccar');
return get_data(); // after finish all task call the same function again
});
}
});
}
});
}
});
}
}
else {
setInterval(get_data, 15000);
}
});
}
and I just call get_data(); function to run. Is there any efficient way to run this module smoothly. I should run it 7 days 24 hours without any interruption.
You're creating a new connection to the servers each time get_data() runs, which is overwhelming them. You need to reuse connections, as for example with connection pooling.

Mysql connection closed after some time in node js and gives PROTOCOL_CONNECTION_LOST'

I am new in node mysql and I am facing an issue. My node js server gets closed and gives connection closed PROTOCOL_CONNECTION_LOST.I don't understand where I am going wrong. Please resolve if any one has knowledge about it.Thanks in advance
var sockjs = require('sockjs');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : process.env.IP,
user : 'root',
port : '80',
password : '123456',
database : 'test',
});
connection.connect(function(err) {
if(err){
console.log('error in connection is : ',err);
}else{
console.log("Connected!");
}
});
var echo = sockjs.createServer();
var connections = [];
echo.on('connection', function (conn) {
connections.push(conn);
conn.on('data', function (message) {
var sql1 = "SELECT count(`id`) as counting FROM `complaints_chat` WHERE `createby`='client' and `read`='0'";
connection.query(sql1, function(err, rows, fields) {
if (err) throw err;
if (rows.length > 0) {
counting=rows[0]['counting'];
}else{ counting=0; }
});
});
});
you can recover connect,when it's unconnect.such as
connection.on('error', err => {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// db error reconnect
disconnect_handler();
} else {
throw err;
}
});

Nested Query in Nodejs Mysql

I want to count a line in table that has FOO table.
The following code has a bug which show only the last db_name.
RESULT IS LOOK LIKE THIS:
db_0099,0
db_0099,5
db_0099,10
db_0099,3
Could you please suggest me how to fix the nodejs code?
var mysql = require('mysql');
var sql1 = "SELECT table_schema as db_name from information_schema.tables WHERE table_name = 'FOO' ";
var sql2 = "SELECT COUNT(*) as solution FROM {0}.FOO";
var connection = mysql.createConnection({
host : '$$$$$$$',
user : '$$$$$$$',
password : '$$$$$$$',
});
connection.connect(function(err){
console.log('connected as id ' + connection.threadId);
});
connection.query(sql1, function(err, result) {
if (err) throw err;
for (var i = 0, len = result.length; i < len; i++) {
var db_name = result[i].db_name;
console.log(db_name);
connection.query(sql2.replace("{0}",db_name), function(err, result) {
if (err) throw err;
console.log(db_name+','+result[0].solution); //Here db_name is showed only the last one.
});
};
connection.end();
});
i advice a two step solution to this problem:
use connection pooling
var pool = mysql.createPool({
host : 'xxxxx',
user : 'xxxxx',
password : 'xxxxx',
connectionLimit : 100
});
pool can do auto connection, so don't connect to your db, just
pool.query(sql,function(err,res){})
this way you use one connection for each query, which will be closed automatically after using it.
use async await for asyncronous sequential queries.
for that create a getResult function which returns a promise
function getResult(sql){
return new Promise(function(resolve,reject){
pool.query(sql, function(err, result){
if(err){
reject(err)
}else{
resolve(result)
}
})
})
}
then you can await each query in the loop
pool.query(sql1, async function(err, result) {
if (err) throw err;
for (var i = 0; i < result.length; i++) {
var db_name = result[i].db_name;
console.log(db_name);
var sql = sql2.replace("{0}",db_name)
var res = await getResult(sql)
console.log(db_name+','+res[0].solution); //Here db_name is showed only the last one.
};
pool.end()
});
P.S.: async await is a feature of the upcomming node 8.0.0 release in april. for node 7.x you will have to start your script with a commandline switch
node --harmony-async-await yourscript.js
Have you verify the content of result ?
console.log(result);
If it's okay try this :
solutions = results.map(result => {
let dbName = result.db_name;
let queryResult;
connection.query(sql2.replace("{0}", dbName), function(err, result) {
if (err) {
throw err;
} else {
queryResult = `${db_name}, ${result[0].solution}`
console.log(queryResult);
}
});
return queryResult;
})
console.log(solutions);
However, try to use a ORM or a sql parser for your query !
Try this one :)
https://hiddentao.com/squel/

returning values from mysql in nodejs crossbar implementation

I just started with crossbar and nodejs. I have a PHP background. I know that mysql on nodejs is async so I added a callback but i can't get the callback to return a value to the register method from crossbar. What would be the correct way to handle this?
var autobahn = require('autobahn');
var mysql = require('mysql');
var q = require('q');
var connection = new autobahn.Connection({
url: 'ws://127.0.0.1:8080/ws',
realm: 'realm1'}
);
connection.onopen = function (session) {
function dologin (cb) {
var connection = mysql.createConnection({
host : 'localhost',
user : 'xxxxx',
password : 'xxxxx',
database : 'xxxxx'
});
connection.connect();
connection.query('SELECT * from users LIMIT 0,2', function(err, rows, fields) {
if (!err){
cb("Done");
}else{
cb('Error while performing Query. ');
}
});
}
function login (args) {
return dologin(function(response){
return "status: "+response;
});
}
session.register('com.cms.login', login).then(
function (reg) {
console.log("Login registered");
},
function (err) {
console.log("failed to register procedure: " + err);
}
);
};
connection.open();