Hello everyone,
just wondering , is this the proper way to :
get connection from connection pool ,
send a request to mysql server,
wait for result
return the connection back to connection pool?
This below code is called everytime an user logs in, it checks his username and token, if it's a match it will open main menu page, if not it will return back to login page.
The truth is, that it's all working in Chrome, but sometimes it does not work in Firefox , it just doesn't call the connection.query() part at all..
So I'm just checking with you guys , if everything is okay with the code below..Or if there is anything I could improve or change..
var db_pool = mysql.createPool({
host: 'localhost',
user: 'dbuser',
password: 'pass',
database: 'db_name'
});
function CheckUser(username, token)
{
db_pool.getConnection(function(err, connection)
{
console.log(" [i] Getting connection from pool. ");
var entry = 0;
var query = connection.query("SELECT token FROM users where token = '"+token+"' and user_id = '"+username+"'");
query.on('result', function(data){
entry++;
});
query.on('error',
function(err){
throw(err);
}
);
query.on('end',
function()
{
if(entry == 1)
{
console.log(" [info] User ["+username+"] authorized.");
/* DO STUFF */
}else
{
console.log(" [Error] User ["+username+"] does not have token: ["+token+"].");
return false;
}
}
);
console.log(" [i] Returning back connection to pool. ");
connection.release();
});
}
Any help is greatly appreciated,
Alex
I believe that the intermittent behavior is because your release() statement is in line with the connection rather than in the 'end' handler. Here is what works for me:
var mysql = require('mysql'),
config = require('./config.json');
var pool = mysql.createPool( config );
var checkUser = function(username, token) {
pool.getConnection(function(err, connection) {
if (err) throw err;
console.log(" [i] Getting connection from pool. ");
var entry = 0,
statement = 'SELECT token FROM users where token = ? and user_id = ?',
query = connection.query( statement, [ token, username ] );
query.on('result', function(data) {
console.log( data );
entry++;
});
query.on('error', function(err) {
console.log( err );
throw err;
});
query.on('end', function() {
if (entry === 1) {
console.log(" [info] User ["+username+"] authorized.");
/* DO STUFF */
} else {
console.log(" [Error] User [", username, "] does not have token [', token, ']');
}
console.log(" [i] Returning back connection to pool. ");
connection.release();
});
});
};
console.log('check the user...');
checkUser( 'test-user', 'mytoken');
I was able to test this (with an alternate statement) with no problems. I also put the config stuff in a separate file and replaced the string statement with parameters.
Hope this helps...
Related
I encountered a weird bug when doing a quick coding assignment.
Here is my code.
Lets call this 'A'
//Grab all the animals from the database
WebApp.get('/all',(req,res) =>
{
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '1234', //Enter your password here
// I found that mySQL 8.0 uses a new default authent plugin whereas 5.7 uses a different one, If you get a ER_NOT_SUPPORTED_AUTH_MODE error from the response, try referring to this post to alter your root password. (https://stackoverflow.com/questions/50373427/node-js-cant-authenticate-to-mysql-8-0)
database: 'animals'
});
const query = "SELECT * FROM animals";
connection.query(query, (err, rows, fields) =>
{
if (err)
{
console.error('error : ' + err.stack);
res.sendStatus(500);
return;
}
console.log("Fetched animals successfully");
//console.log(rows); // Use this for error checking to see if a authent problem occurs.
res.json(rows);
});
});
and this 'B'
//Grab a selected animal from the database given a valid Id.
WebApp.get('/:id',(req,res) =>
{
console.log("Fetching user with id: " + req.params.id);
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '1234', //Enter your password here
// I found that mySQL 8.0 uses a new default authent plugin whereas 5.7 uses a different one, If you get a ER_NOT_SUPPORTED_AUTH_MODE error from the response, try referring to this post to alter your root password. (https://stackoverflow.com/questions/50373427/node-js-cant-authenticate-to-mysql-8-0)
database: 'animals'
});
const animalId = req.params.id;
const query = "SELECT * FROM animals WHERE id = ?";
connection.query(query, [animalId], (err, rows, fields) =>
{
if (err)
{
console.error('error : ' + err.stack);
res.sendStatus(500);
return;
}
console.log("Fetched animals successfully");
//console.log(rows); // Use this for error checking to see if a authent problem occurs.
res.json(rows);
});
});
For some reason, if I put A before B it works, and I get successful results from my queries. However, if I put B before A, B will return successfully, but A will return '[]'. Anyone know why?
Thanks for any help!
Have you tried terminating the connection after each request, or considered using a connection pool? I am not familiar with nodeJS integration with MySQL, but in SQLServer, it is best to use ConnectionPool, when asynchronously making database requests.
I want to know whether there is any existing user with emailid in my db by the name say xyz#abc.com .
function isDuplicateUser(emailId)
{
var sql='SELECT count(*) FROM UserDetails WHERE emailId ="'+emailId+'";';
var con = mysql.createConnection({
host:"localhost",
user: "root",
password: "32577488",
database:"mydb"
});
con.connect(function(err) {
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Inside Duplicate check");
console.log(result[0]);
console.log(result.count);
console.log(result[0].emailId);
console.log(result[0].count);
console.log("1 record inserted");
});
});
}
But in all the console.log statements I am getting undefined ! I thought of using count so that if there is more than 0 than there exists a user with that userid ! Please help me ! I have another doubt also It is ok to get connection in every function ! Like for signup have a
function signup(email,password,name)
{
var sql =''....;
//getting connection once
}
function signin(emailid,password)
{
//getting connection here
return success;
}
It seems like code is getting replicated many times !
please, try with this sql statement and let me know the result:
// replace your var sql with this one
const sql = `SELECT count(*) FROM UserDetails WHERE emailId = '${emailId}'`;
In the other hand, regarding how to manage connection in each function, my recommendation is create a pool of connections in your app and get a connection from the pool on each function you need (you need to take care about releasing the connection when you finish to make them available for new incoming requests):
// connection first time when node starts
const options = {
connectionLimit: 10,
host: HOST,
user: USER,
password: PASSWORD,
database: DATABASE,
port: 3306,
timezone: 'Z',
// debug: true,
multipleStatements: true,
// ...azureCertificate && sslOptions,
};
const pool = mysql.createPool(options);
// on each function, get a connection from the pool using this function
getConnection() {
return new Promise((resolve, reject) => {
if (pool === null) {
return reject(new Error(`MySQL connection didn't established. You must connect first.`));
}
pool.getConnection((err, connection) => {
if (err) {
if (connection) {
connection.release();
}
return reject(err);
}
return resolve(connection);
});
});
}
Hope this helps.
This example was made using npm package mysql: https://www.npmjs.com/package/mysql
I am still new to nodejs and Javascript, I am sorry if my question appear to be very simple but I am struggling a lot and I can't seem to find an answer on the net.
What I want to do is basically calling a script (sqlRequest.js) and send an integer while calling it. This script will send an sql request to my database and will return the result (an object) to the original file.
Here are the codes:
router.post('/request', function(req, res, next){
var id = req.body.id;
var essai = require('./sqlRequest.js');
console.log("INDEX: "+essai.sendSQL(id)); });
And now the sqlRequest.js code:
exports.sendSQL = function(id) {
var mysql= require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'bcombes',
password : 'bertrand1994',
database : 'totalkpi'
});
connection.connect();
var sql ="SELECT * FROM tra_ticket where id=?";
var insert=[id];
sql=mysql.format(sql, insert);
connection.query(sql, function(err, rows, fields) {
if (err) {
console.log('Error while performing Query.');
connection.end();
}
else {
connection.end();
console.log(rows);
return rows;
}
});};
On the console I can see that the console.log("INDEX: "+essai.sendSQL(id)); appears to be undefined and is displayed before the console.log(rows).
Is it possible that the server does not wait for the function to finish and display the variable anyway ?
Anyway thank you for taking the time to help.
Your logic to pass a variable between files is fine. The reason your seeing essai.sendSQL(id) return undefined is because connection.query(...) is called asynchronously and, as you've mentioned in your question, the console.log fires before the DB query completes.
To fix that issue you just need to refactor your code slightly:
var essai = require('./sqlRequest.js');
router.post('/request', function(req, res, next){
var id = req.body.id;
// send callback to sendSQL
essai.sendSQL(id, function(index) {
// this will only fire once the callback has been called
console.log("INDEX: " + index)
})
});
And then in sqlRequest.js:
exports.sendSQL = function (id, cb) {
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'bcombes',
password: 'bertrand1994',
database: 'totalkpi'
});
connection.connect();
var sql = "SELECT * FROM tra_ticket where id=?";
var insert = [id];
sql = mysql.format(sql, insert);
connection.query(sql, function (err, rows, fields) {
if (err) {
console.log('Error while performing Query.');
connection.end();
}
else {
connection.end();
console.log(rows);
// call the callback
cb(rows);
}
});
};
Following is the Server.js File, here I am Fetching The Details From Table which working Good. I need to Get a Variable From k.php which is in the Same Folder.Iam using npm exec-php module to get the Values From Php File. But The Variable is Showing Undefined.
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
express=require('express'),
session=require('express-session'),
mysql = require('mysql'),
execPhp = require('exec-php'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test',
port: 3306
}),
POLLING_INTERVAL = 3000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function(err) {
// connected! (unless `err` is set)
if (err) {
console.log(err);
}
});
// creating the server ( localhost:8000 )
app.listen(8000);
// on server started we can load our client.html page
function handler(req, res) {
fs.readFile(__dirname + '/client.php', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.php');
}
res.writeHead(200);
res.end(data);
});
}
execPhp('k.php', function(error, php, outprint){
// Here I expected The outprint Will be 'One' but it print undefined
console.log(outprint);
php.my_function(1, 2, function(err, result, output, printed){
//this my_function is also showing Error
});
});
var pollingLoop = function() {
// Doing the database query
var query = connection.query('SELECT * FROM users where user_id=1'),
users = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function(err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
updateSockets(err);
})
.on('result', function(user) {
// it fills our array looping on each user row inside the db
users.push(user);
})
.on('end', function() {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
users: users
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
};
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8000');
the main Problem is in these Lines
execPhp('k.php', function(error, php, outprint){
// Here I expected The outprint Will be 'One' but it print undefined
console.log(outprint);
php.my_function(1, 2, function(err, result, output, printed){
//this my_function is also showing Error
});
});
The Following is k.php in the same folder
<?php
echo "One";
function my_function($arg1, $arg2){
echo "Two";
return $arg1 + $arg2;
}
?>
This is the Error
I have created an application using Node.js to connect with SQL Server. Below is the code:
app.get('/SalesStatistics', function (req, res) {
var Connection = require('tedious').Connection;
// config for your database
var config = {
user: "****",
password: "*****",
server: "abc",
database: "xyz"
};
var connection = new Connection(config);
connection.on('connect', function (err) {
// If no error, then good to proceed.
console.log("Connected");
executeStatement();
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
function executeStatement() {
request = new Request("select * from employee;", function (err) {
if (err) {
console.log(err);
}
});
var result = "";
request.on('row', function (columns) {
columns.forEach(function (column) {
if (column.value === null) {
console.log('NULL');
} else {
result += column.value + " ";
}
});
console.log(result);
result = "";
});
request.on('done', function (rowCount, more) {
console.log(rowCount + ' rows returned');
});
connection.execSql(request);
}
});
Received the below error in console:
message: 'Requests can only be made in the LoggedIn state, not the Connecting state'
code: EIINVALIDSTATE
Also tried the sample from Github site, but still I could not connect to SQL Server. Please let me know if any other possibility.
I just encountered the same problem awhile ago running the same code above with similar environment.
It turn out that I did not configure the sql server (using Sql Server Management Manager) to accept TCP connection to port (1433). After I done that, everything work fine.