So I have done C++ Java and PHP and wanted to give a crack at Node.js. Below I have a very simple and unsecured SQL query.
module.exports = {
LoginCheck: function(data,cb){
console.log(data.password);
console.log(data.username);
if(data.username && data.password){
console.log('we have arrived');
var config = require(__dirname+'/../Config/config.json');
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.LoginDBhost,
port: config.LoginDBport,
user: config.LoginDBusername,
password: config.LoginDBpassword,
database: config.LoginDB
});
con.connect(function(err) {
if (err) throw err;
console.log('we have connected');
con.query("SELECT * FROM `Users` WHERE `Username` = '"+data.username+"'", function (err, result) {
if (err) console.log(err);
if(result.Password){
if(result[0].Password){
if(result[0].Password == data.password){
console.log('true');
cb(true);
}
}
}
});
});
}
//either password is null or didnt match on file... if we are this far its a fail
console.log('false');
cb(false);
},
bar: function () {
// whateverss
}
};
The code does not wait for the sql connection and skips to being false. I been banging my head on a desk for days trying to figure out how promises and callbacks works after years of having my code follow steps layed.
Could someone convert this and explain how to force my code to be synchronous when I need it to be?
Try this code :
module.exports = {
LoginCheck: function(data,cb){
console.log(data.password);
console.log(data.username);
if(data.username && data.password){
console.log('we have arrived');
var config = require(__dirname+'/../Config/config.json');
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.LoginDBhost,
port: config.LoginDBport,
user: config.LoginDBusername,
password: config.LoginDBpassword,
database: config.LoginDB
});
con.connect(function(err) {
// I think cb(false) here but you use throw err.
if (err) throw err;
console.log('we have connected');
con.query("SELECT * FROM `Users` WHERE `Username` = '"+data.username+"'", function (err, result) {
if (err) console.log(err);
if(result.Password){
if(result[0].Password){
if(result[0].Password == data.password){
console.log('true');
cb(true);
}
}
}
//either password is null or didn't match on file... if we are this far its a fail
console.log('false');
cb(false);
});
});
}
},
bar: function () {
// whateverss
}
};
Related
I am having problem with sql query execution using callback, I never worked on the node.js, so looking for some guidance and get going.
Tried with having database connection in same file, but unable to execute when having the database connection in another file.
DatabaseManager.js
var Tedious = require('tedious');
var Connection = Tedious.Connection;
var Request = Tedious.Request;
function connect(cb) {
var config = {
userName: 'dddff',
password: 'fsfdsf',
server: '12345.database.windows.net',
options:
{
database: '12345',
encrypt: true
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
if (err) {
console.log(err);
return;
}
console.log('CONNECTED TO DATABASE');
cb(connection);
});
}
module.exports = connect;
app.js
var connect = require('./DatabaseManager');
bot.dialog('profileDialog', (session) => {
session.send('Hello Message', session.message.text);
console.log('Creating a connection');
connect(function(connection) {
console.log('Reading rows from the Table.');
// Execute queries here and how to frame the syntax here?
connection.query("select FNAME from StudentProfile where ID=1"),
function(err, result, fields) {
if (err) throw err;
console.log(result);
}
});
})
I expect the output of select statement result on the console.
I'm trying to build a chatbot using Botpress. I'm a beginner, looking for your help. One of the requirements is to query database to answer questions. This is what I have tried so far:
dbconnect.js
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
var db = function dbCall(sql, values) {
return new Promise(function(resolve, reject){
oracledb.getConnection(
{
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
},
function(err, connection) {
if (err) {
reject(err);
return;
}
connection.execute(
sql,
values,
{
maxRows: 1
},
function(err, result) {
if (err) {
console.error(err.message);
return;
}
resolve(result);
doRelease(connection);
}
);
});
});
}
// Note: connections should always be released when not needed
function doRelease(connection) {
connection.close(
function (err) {
if (err) {
console.error(err.message);
}
});
}
module.exports = db;
select.js
var dbConnect = require('../oracledb/dbconnect');
dbConnect('select code from table1' +
' where id=:id', {id:'value1'}).then(function (response) {
console.info(response.rows);
}).catch(function(error) {
console.info(error);
});
everything above works great, if I run select.js. How could I bring the response into the botpress chat window? I tried placing the select.js code in index.js event.reply, it doesn't work.
Thanks,
Babu.
I have resolved this by using the promise directly in the action.
return dbConnect('<SQL here>=:id', { id: Id })
.then(function(response) {
var res = response.rows
console.info(res);
const newState = { ...state, status: res}
return newState
})
.catch(function(error) {
console.info(error)
})
Note that response has the resultset.
i have make a socket.io chatroom and i am using some database queries to insert and select data but unfortunately i am getting some error of query
The code of the file on which i am getting error is as follow
var rooms = [];
module.exports.getUserFeeds = function (chatpage, socket, io, pool,async)
{
socket.on('senddata', function (data)
{
socket.user_id = data.user_id;
socket.room_id=data.room_id;
socket.room = 'room' + data.room_id;
rooms['room' + data.room_id] = 'room' + data.room_id;
socket.join('room' + data.room_id);
pool.getConnection(function (err, connection)
{
async.parallel([
function(callback)
{
connection.query('SELECT user_id,username FROM chat_users where user_id=' + data.user_id + '', function (error1, userdata)
{
if (error1) return callback(error1);
callback(null, userdata);
});
},
function (callback)
{
if(data.user_id)
connection.query('SELECT user_id,username FROM chat_users', function (error3, memdata)
{
if (error3) return callback(error3);
callback(null, memdata);
});
else
callback(null,null);
},
function(callback)
{
if(data.user_id)
connection.query('SELECT comment_id,comment,chat_users.user_id,username,comments.added FROM comments INNER JOIN chat_users ON comments.user_id=chat_users.user_id',function(error4,converdata){
if (error4) return callback(error4);
callback(null, converdata);
});
else
callback(null,null);
}
], function (err, results)
{
if(err) throw err;
socket.emit('chatdata',
{
memdata:results[1],
converdata:results[2],
});
socket.broadcast.to('room'+ data.room_id +'').emit('newuser', {userdata:results[0]});
connection.release();
});
});
});
socket.on('sendcomment', function (data)
{
pool.getConnection(function (err, connection)
{
connection.query('INSERT INTO comments (user_id,comment,added) VALUES (' + data.user_id + ',"' + data.msg + '","' + data.datetime + '")', function (err, result)
{
if (err) throw err;
async.parallel([
function (callback)
{
connection.query('SELECT comments.*,username,comments.added from comments JOIN chat_users ON comments.user_id=chat_users.user_id WHERE comments.comment_id=' + result.insertId + '', function (err2, comments)
{
if (err2) return callback(err2);
callback(null, comments);
});
},
function (callback)
{
connection.query('SELECT count(comment_id) as tot_comment from comments', function (err3, comment_count)
{
if (err3) return callback(err3);
callback(null, comment_count);
});
},
], function (err, results)
{
if (err) throw err;
if (results[0])
{
chatpage. in('room'+ data.room_id +'').emit('showcomment',
{
room_comment: results[0],
comment_count: results[1]
});
}
connection.release();
});
});
});
});
socket.on('disconnect', function ()
{
console.log("user disconnected");
pool.getConnection(function (err, connection)
{
connection.query('DELETE from chat_users where user_id='+socket.user_id+'', function (err, removeuser)
{
if (err) throw err;
});
connection.query('DELETE from comments where user_id='+socket.user_id+'', function (err, removecomments)
{
if (err) throw err;
});
connection.release();
});
socket.broadcast.to('room'+ socket.room_id +'').emit('removeuser', {user_id:socket.user_id});
socket.leave(socket.room);
});
};
and the error i am getting because of this code is
The image of the error i am getting
please can anyone help me regarding this issue
Thanks a lot
Regards
It seems there is error in your mysql connection.try make proper connection first
Step 1: Create the pool (only do this once)
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'hostname',
user : 'username',
password : 'password',
database : 'db_name',
connectionLimit : 10, // this is the max number of connections before your pool starts waiting for a release
multipleStatements : true // I like this because it helps prevent nested sql statements, it can be buggy though, so be careful
});
Step 2: Get a connection
pool.getConnection(function (err, conn) {
if (err)
return res.send(400);
// if you got a connection...
conn.query('SELECT * FROM table WHERE id=? AND name=?', [id, name], function(err, rows) {
if(err) {
conn.release();
return res.send(400, 'Couldnt get a connection');
}
// for simplicity, just send the rows
res.send(rows);
// CLOSE THE CONNECTION
conn.release();
}
});
check this for more detail https://youtu.be/2CeAnrCsBQo
http://fearby.com/article/how-to-setup-pooled-mysql-connections-in-node-js-that-dont-disconnect/
Adding the following 2 parameters solved my problem
queueLimit
connectionLimit
exports.pool = mysqlCon.createPool({
host: host,
user: user,
port: 3306,
password: pass,
database: db,
queueLimit : 0, // unlimited queueing
connectionLimit : 0 // unlimited connections
});
Note : Be careful, this might break your database.
mysql> ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY '< MySQL password >';
mysql> FLUSH PRIVILEGES;
Solved mine by using mysql2 instead of mysql
I also faced this error. It was due to the fact that the server where I hosted MySQL was down and the connection wasn't establishing while I was querying the database. As soon as I started the server again then it all got set.
You need to handle errors, otherwise you can encounter issues like this. Specifically in this case, you aren't checking if err is set in your pool.getConnection() callback. It is most likely set and is why you don't have a valid connection object.
I am using oracledb npm package to establish connection with the DB when creating a node.js backend API. I am able to obtain the result when I do console.log(result.rows)
Below is the function code
getDbConnection: function(query) {
var connectInfo= [EnvConfig.getConnectionHostName(), EnvConfig.getConnectionPort()]; // Array of hostname and port
var connectHost = connectInfo.join(':'); // join hostname and port with ':'
var connectionAttr = [connectHost, EnvConfig.getConnectionSID()]; // hostname:port and SID
var connectString = connectionAttr.join('/'); // creating the connection string like 'hostname:port'
console.log(connectString);
// creating a oracle connection
oracledb.getConnection(
{
user: EnvConfig.getConnectionUserName(),
password: EnvConfig.getConnectionPassword(),
connectString: connectString
},
function (err, connection) {
if(err) {
console.log(err.message);
return;
}
connection.execute(
query, function(err, result) {
if(err) {
console.log(err.message);
return;
}
console.log(result.rows); // I get result here
return result.rows; // return result on success
}
);
}
);
}
I call the getDbConnection function from other file and when I console.log() like console.log(getDbConnection(query)) . I get the result as undefined. How do I solve this.
you can't get your data like this. Return like this will not gonna work here
Since it works in async nature, you can do one thing to use a callback function to get that result like this
DbConnection: function(query,callback) {//pass callback as parameter
var connectInfo = [EnvConfig.getConnectionHostName(), EnvConfig.getConnectionPort()]; // Array of hostname and port
var connectHost = connectInfo.join(':'); // join hostname and port with ':'
var connectionAttr = [connectHost, EnvConfig.getConnectionSID()]; // hostname:port and SID
var connectString = connectionAttr.join('/'); // creating the connection string like 'hostname:port'
console.log(connectString);
// creating a oracle connection
oracledb.getConnection({
user: EnvConfig.getConnectionUserName(),
password: EnvConfig.getConnectionPassword(),
connectString: connectString
},
function(err, connection) {
if (err) {
console.log(err.message);
return callback(err);
}
connection.execute(
query,
function(err, result) {
if (err) {
console.log(err.message);
return callback(err);
}
console.log(result.rows); // I get result here
return callback(null,result.rows); // return result on success
}
);
}
);
}
And call like this
//Use your function with callback
getDbConnection(query,function(err,result){
if(!err){
console.log(result)
}
})
I am having trouble understanding node.js.
Example, MongoDB access, here's what I've got (mydb.js):
var mongodb = require('mongodb'),
server = new mongodb.Server('staff.mongohq.com', 10030, {
auto_reconnect: true
}),
db = new mongodb.Db('mydb', server);
function authenticateAndGo(db, handle) {
db.authenticate('username', 'password', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Database user authenticated');
var collection = new mongodb.Collection(db, 'test');
handle(collection);
});
}
function query(handle) {
db.open(function(err, db) {
if( err ) {
console.log(err);
return;
}
console.log('Database connected');
authenticateAndGo(db, handle);
});
};
exports.query = query;
So, if I want to use it later, I would
var mydb = require('./mydb');
mydb.query(function(collection) {
collection.find({}, {
limit: 10
}).toArray(function(err, docs) {
console.log(docs);
});
});
But, If I do multiple calls, like so:
var mydb = require('./mydb');
mydb.query(function(collection) {
collection.find({}, {
limit: 10
}).toArray(function(err, docs) {
console.log(docs);
});
});
mydb.query(function(collection) {
collection.find({}, {
limit: 10
}).toArray(function(err, docs) {
console.log(docs);
});
});
I get an exception:
Error: db object already connecting, open cannot be called multiple times
I think that there is really something fundamental that I do not understand about all this and it is probable that this question is stupid ...
Anyway, all help is welcome.
Thanks in advance.
mydb.js:
var mongodb= require('mongodb'),
server = new mongodb.Server('staff.mongohq.com', 10030, {
auto_reconnect: true
}),
db1 = new mongodb.Db('mydb', server);
// callback: (err, db)
function openDatabase(callback) {
db1.open(function(err, db) {
if (err)
return callback(err);
console.log('Database connected');
return callback(null, db);
});
}
// callback: (err, collection)
function authenticate(db, username, password, callback) {
db.authenticate(username, password, function(err, result) {
if (err) {
return callback (err);
}
if (result) {
var collection = new mongodb.Collection(db, 'test');
// always, ALWAYS return the error object as the first argument of a callback
return callback(null, collection);
} else {
return callback (new Error('authentication failed'));
}
});
}
exports.openDatabase = openDatabase;
exports.authenticate = authenticate;
use.js:
var mydb = require('./mydb');
// open the database once
mydb.openDatabase(function(err, db) {
if (err) {
console.log('ERROR CONNECTING TO DATABASE');
console.log(err);
process.exit(1);
}
// authenticate once after you opened the database. What's the point of
// authenticating on-demand (for each query)?
mydb.authenticate(db, 'usernsame', 'password', function(err, collection) {
if (err) {
console.log('ERROR AUTHENTICATING');
console.log(err);
process.exit(1);
}
// use the returned collection as many times as you like INSIDE THE CALLBACK
collection.find({}, {limit: 10})
.toArray(function(err, docs) {
console.log('\n------ 1 ------');
console.log(docs);
});
collection.find({}, {limit: 10})
.toArray(function(err, docs) {
console.log('\n------ 2 ------');
console.log(docs);
});
});
});
Result:
on success:
Database connected
Database user authenticated
------ 1 ------
[ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]
------ 2 ------
[ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]
on failure:
Database connected
{ [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 }
[Original Answer]:
You're opening the db multiple times (once in each query). You should open the database just once, and use the db object in the callback for later use.
You're using the same variable name multiple times, and that might've caused some confusion.
var mongodb = require('mongodb'),
server = new mongodb.Server('staff.mongohq.com', 10030, {
auto_reconnect: true
}),
db1 = new mongodb.Db('mydb', server);
function authenticateAndGo(db, handle) {
db.authenticate('username', 'password', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Database user authenticated');
var collection = new mongodb.Collection(db, 'test');
handle(collection);
});
}
function query(handle) {
db1.open(function(err, db2) {
if( err ) {
console.log(err);
return;
}
console.log('Database connected');
authenticateAndGo(db2, handle);
});
};
exports.query = query;
I've changed the above code a little (db1 for the original db, db2 for the opened db). As you can see, you're opening db1 multiple times, which is not good. extract the code for opening into another method and use it ONCE and use the db2 instance for all your queries/updates/removes/...
You can only call "open" once. When the open callback fires, you can then do your queries on the DB object it returns. So one way to handle this is to queue up the requests until the open completes.
e.g MyMongo.js
var mongodb = require('mongodb');
function MyMongo(host, port, dbname) {
this.host = host;
this.port = port;
this.dbname = dbname;
this.server = new mongodb.Server(
'localhost',
9000,
{auto_reconnect: true});
this.db_connector = new mongodb.Db(this.dbname, this.server);
var self = this;
this.db = undefined;
this.queue = [];
this.db_connector.open(function(err, db) {
if( err ) {
console.log(err);
return;
}
self.db = db;
for (var i = 0; i < self.queue.length; i++) {
var collection = new mongodb.Collection(
self.db, self.queue[i].cn);
self.queue[i].cb(collection);
}
self.queue = [];
});
}
exports.MyMongo = MyMongo;
MyMongo.prototype.query = function(collectionName, callback) {
if (this.db != undefined) {
var collection = new mongodb.Collection(this.db, collectionName);
callback(collection);
return;
}
this.queue.push({ "cn" : collectionName, "cb" : callback});
}
and then a sample use:
var MyMongo = require('./MyMongo.js').MyMongo;
var db = new MyMongo('localhost', 9000, 'db1');
var COL = 'col';
db.query(COL, function(collection) {
collection.find({}, {
limit: 10
}).toArray(function(err, docs) {
console.log("First:\n", docs);
});
});
db.query(COL, function(collection) {
collection.find({}, {
limit: 10
}).toArray(function(err, docs) {
console.log("\nSecond:\n", docs);
});
});
I simply call the open function once directly after the db init:
var mongodb = require('mongodb');
var server = new mongodb.Server('foo', 3000, {auto_reconnect: true});
var db = new mongodb.Db('mydb', server);
db.open(function(){});
After that I do not have to care about that anymore because of auto_reconnect is true.
db.collection('bar', function(err, collection) { [...] };