Cannot use .query commands leaves to an error in nodejs - mysql

Problem:
I have created a node application there I am adding admin to the database like this in userModal.js file.
var bcrypt = require('bcryptjs');
var sql = require('../db.js');
module.exports.save_admin = (new_admin,callback) =>{
bcrypt.genSalt(10,(err, salt)=> {
bcrypt.hash(new_admin.password, salt, (err, hash)=> {
new_admin.password = hash;
if(err){
throw err;
}
else{
console.log(new_admin.password);
sql.query("INSERT INTO administrators set ?", new_admin, callback);
}
});
});
}
This is how I am calling this function from the controller.
var admin = {
first_name: req.body.first_name,
last_name: req.body.last_name,
organization: req.body.organization,
admin_level: req.body.admin_level,
user_identity: req.body.identity,
username: req.body.username,
password: req.body.password
};
User.save_admin(admin, (err,user) => {
if (!err) {
res.json({ state: true, msg: "data Inserted" });
} else {
res.json({ state: false, msg: "data Is Not Inserted" });
}
});
This is how I have configured the database in db.js file.
'user strict';
var mysql = require('mysql');
//local mysql db connection
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'mydatabase'
});
connection.connect(function(err) {
if (!err){
console.log("Database connection succeeded...!");
}
else{
console.log('Error in DB connection :'+JSON.stringify(err,undefined, 2));
}
});
module.exports = connection;
module.exports = {
"secret": "myapplicationsecret"
};
This setup leaves me this error.
sql.query("INSERT INTO administrators set ?", new_admin, callback);
^
TypeError: sql.query is not a function

Related

How to create a awaitable connection with mysql using node.js

I'm new with Node.js and I'm trying to create a async method with Node.js, because I need to check a row inside of my database and then decide what to do with it. So I created a file called sql-service.js
const sql = require('mysql');
var connection = sql.createConnection({
host: '0.0.0.0',
user: 'foo',
password: 'fooo'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
console.log(connection.state);
module.exports.SignUpUser = (email,password)=>{
connection.query('select * from usuario', function(error, results, fields) {
console.log(results);
});
}
And inside of my Controller :
const sqlService = require('../services/sql-service');
exports.post = async(req,res,next)=>{
const Email = req.body.Email;
const Passw = req.body.Password;
console.log(dateT.getdate());
if (fluentValidation.validateEmail(Email) && fluentValidation.isValidLenght(Passw)) {
try {
await sqlService.SignUpUser(Email,Passw);
//emailService.send(req.body.Email,'Nome','Bem vindo ao hanggu');
} catch (error) {
console.log(error);
}
res.status(201).send({
Email: "Valid " + req.body.Email,
Password: Passw.length,
Send: 's '//Date : dateT.getDateTime()
});
} else {
res.status(500).send({
Error: "Email invalid"
})
}
}
It does connect but the result that I got it's undefined, I tried
console.log('The solution is: ', results[0].usuario);
But still.
what schema you select?
var connection = sql.createConnection ({
host: '0.0.0.0',
user:'foo',
password : 'fooo',
database : 'you_db'
});
test

NodeJS + Socket.IO + Mysql

I'm using socket.io in order to send message to the user when he join my site and initializing his details using cookie sent by the client. After a while and few refreshes performed my queries stop working.
Here's my code:
io.on('connection', function(socket) {
var user = false;
socket.on('hash', function(hash, gameType) {
socket.join(gameType);
query('SELECT * FROM `users` WHERE `hash` = ' + pool.escape(hash), function(err, row) {
if((err) || (!row.length)) return socket.disconnect();
user = row[0];
users[user.steamid] = {
socket: socket.id,
balance: parseInt(row[0].balance)
}
socket.emit('message', {
balance: row[0].balance,
type: 'hello',
user: row[0].steamid
});
}
}
function query(sql, callback) {
console.log(callback);
if (typeof callback === 'undefined') {
callback = function() {};
}
pool.getConnection(function(err, connection) {
if(err) return callback(err);
logger.info('DB Connection ID: '+connection.threadId);
connection.query(sql, function(err, rows) {
if(err) return callback(err);
connection.release();
return callback(null, rows);
});
});
}
log4js.configure({
appenders: [
{ type: 'console' },
{ type: 'file', filename: 'logs/site.log' }
]
});
var logger = log4js.getLogger();
var pool = mysql.createPool({
connectionLimit : 10,
database: 'test',
host: 'localhost',
user: 'root',
password: 'pw'
});
process.on('uncaughtException', function (err) {
logger.trace('Strange error');
logger.debug(err);
});
my guess is the reason is you exhaust the connection pool.
if(err) return callback(err); << after some erros here
connection.release(); << not released if there is an error
just release the connection before this line

How do I create a MySQL connection pool while working with NodeJS and Express?

I am able to create a MySQL connection like this:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
But I would rather like to initiate a pool and use it across my project.
Just to help some one in future, this worked for me:
I created a mysql connector file containing the pool:
// Load module
var mysql = require('mysql');
// Initialize pool
var pool = mysql.createPool({
connectionLimit : 10,
host : '127.0.0.1',
user : 'root',
password : 'root',
database : 'db_name',
debug : false
});
module.exports = pool;
Later you can simply include the connector in another file lets call it manageDB.js:
var pool = require('./mysqlConnector');
And made a callable method like this:
exports.executeQuery=function(query,callback){
pool.getConnection(function(err,connection){
if (err) {
connection.release();
throw err;
}
connection.query(query,function(err,rows){
connection.release();
if(!err) {
callback(null, {rows: rows});
}
});
connection.on('error', function(err) {
throw err;
return;
});
});
}
You can create a connection file, Let's called dbcon.js
var mysql = require('mysql');
// connect to the db
dbConnectionInfo = {
host: "localhost",
port: "3306",
user: "root",
password: "root",
connectionLimit: 5, //mysql connection pool length
database: "db_name"
};
//For mysql single connection
/* var dbconnection = mysql.createConnection(
dbConnectionInfo
);
dbconnection.connect(function (err) {
if (!err) {
console.log("Database is connected ... nn");
} else {
console.log("Error connecting database ... nn");
}
});
*/
//create mysql connection pool
var dbconnection = mysql.createPool(
dbConnectionInfo
);
// Attempt to catch disconnects
dbconnection.on('connection', function (connection) {
console.log('DB Connection established');
connection.on('error', function (err) {
console.error(new Date(), 'MySQL error', err.code);
});
connection.on('close', function (err) {
console.error(new Date(), 'MySQL close', err);
});
});
module.exports = dbconnection;
Now include this connection to another file
var dbconnection = require('../dbcon');
dbconnection.query(query, params, function (error, results, fields) {
//Do your stuff
});
There is some bugs in Utkarsh Kaushik solution:
if (err), the connection can not be released.
connection.release();
and when it has an err, next statement .query always execute although it gets an error and cause the app crashed.
when the result is null although query success, we need to check if the result is null in this case.
This solution worked well in my case:
exports.getPosts=function(callback){
pool.getConnection(function(err,connection){
if (err) {
callback(true);
return;
}
connection.query(query,function(err,results){
connection.release();
if(!err) {
callback(false, {rows: results});
}
// check null for results here
});
connection.on('error', function(err) {
callback(true);
return;
});
});
};
You do also can access the Mysql in a similar way by firstly importing the package by entering npm install mysql in the terminal and installing it & initialize it.
const {createPool} = require("mysql");
const pool = createPool({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
)};
module.exports = pool;

Terminating a callback in nodejs

I am very new to nodejs. I am using mysql node module. This is how I use it:
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'sample'
});
connection.connect(function (err) {
if (!err) {
console.log("Database is connected ... \n\n");
} else {
console.log("Error connecting database ... \n\n");
}
});
var post = {PersonID: 1, Name: 'Prachi', City: 'Blore'};
var query = connection.query('INSERT INTO Persons SET ?', post, function(error, result) {
if (error) {
console.log(error.message);
} else {
console.log('success');
}
});
console.log(query.sql);
This node code works functionally. As in, it adds data to the table. But it doesn't terminate. What is the mistake which I am making?
Take a closer look at the official documentation, you have to close the connection :
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
connection.end();
Use connection.end() to close the connection
var query = connection.query('INSERT INTO Persons SET ?', post, function(error, result) {
connection.end();
if (error) {
console.log(error.message);
} else {
console.log('success');
}
});

How to provide a mysql database connection in single file in nodejs

I need to provide the mysql connection for modules. I have a code like this.
var express = require('express'),
app = express(),
server = require('http').createServer(app);
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'chat'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
});
app.get('/save', function(req,res){
var post = {from:'me', to:'you', msg:'hi'};
var query = connection.query('INSERT INTO messages SET ?', post, function(err, result) {
if (err) throw err;
});
});
server.listen(3000);
But how we provide one time mysql connection for all the modules.
You could create a db wrapper then require it. node's require returns the same instance of a module every time, so you can perform your connection and return a handler. From the Node.js docs:
every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.
You could create db.js:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'chat'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
Then in your app.js, you would simply require it.
var express = require('express');
var app = express();
var db = require('./db');
app.get('/save',function(req,res){
var post = {from:'me', to:'you', msg:'hi'};
db.query('INSERT INTO messages SET ?', post, function(err, result) {
if (err) throw err;
});
});
server.listen(3000);
This approach allows you to abstract any connection details, wrap anything else you want to expose and require db throughout your application while maintaining one connection to your db thanks to how node require works :)
I took a similar approach as Sean3z but instead I have the connection closed everytime i make a query.
His way works if it's only executed on the entry point of your app, but let's say you have controllers that you want to do a var db = require('./db'). You can't because otherwise everytime you access that controller you will be creating a new connection.
To avoid that, i think it's safer, in my opinion, to open and close the connection everytime.
here is a snippet of my code.
mysq_query.js
// Dependencies
var mysql = require('mysql'),
config = require("../config");
/*
* #sqlConnection
* Creates the connection, makes the query and close it to avoid concurrency conflicts.
*/
var sqlConnection = function sqlConnection(sql, values, next) {
// It means that the values hasnt been passed
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection(config.db);
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
}
});
connection.query(sql, values, function(err) {
connection.end(); // close the connection
if (err) {
throw err;
}
// Execute the callback
next.apply(this, arguments);
});
}
module.exports = sqlConnection;
Than you can use it anywhere just doing like
var mysql_query = require('path/to/your/mysql_query');
mysql_query('SELECT * from your_table where ?', {id: '1'}, function(err, rows) {
console.log(rows);
});
UPDATED:
config.json looks like
{
"db": {
"user" : "USERNAME",
"password" : "PASSWORD",
"database" : "DATABASE_NAME",
"socketPath": "/tmp/mysql.sock"
}
}
Hope this helps.
I think that you should use a connection pool instead of share a single connection. A connection pool would provide a much better performance, as you can check here.
As stated in the library documentation, it occurs because the MySQL protocol is sequential (this means that you need multiple connections to execute queries in parallel).
Connection Pool Docs
From the node.js documentation, "To have a module execute code multiple times, export a function, and call that function", you could use node.js module.export and have a single file to manage the db connections.You can find more at Node.js documentation. Let's say db.js file be like:
const mysql = require('mysql');
var connection;
module.exports = {
dbConnection: function () {
connection = mysql.createConnection({
host: "127.0.0.1",
user: "Your_user",
password: "Your_password",
database: 'Your_bd'
});
connection.connect();
return connection;
}
};
Then, the file where you are going to use the connection could be like useDb.js:
const dbConnection = require('./db');
var connection;
function callDb() {
try {
connection = dbConnectionManager.dbConnection();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (!error) {
let response = "The solution is: " + results[0].solution;
console.log(response);
} else {
console.log(error);
}
});
connection.end();
} catch (err) {
console.log(err);
}
}
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'yourip',
port : 'yourport',
user : 'dbusername',
password : 'dbpwd',
database : 'database schema name',
dateStrings: true,
multipleStatements: true
});
// TODO - if any pool issues need to try this link for connection management
// https://stackoverflow.com/questions/18496540/node-js-mysql-connection-pooling
module.exports = function(qry, qrytype, msg, callback) {
if(qrytype != 'S') {
console.log(qry);
}
pool.getConnection(function(err, connection) {
if(err) {
if(connection)
connection.release();
throw err;
}
// Use the connection
connection.query(qry, function (err, results, fields) {
connection.release();
if(err) {
callback('E#connection.query-Error occurred.#'+ err.sqlMessage);
return;
}
if(qrytype==='S') {
//for Select statement
// setTimeout(function() {
callback(results);
// }, 500);
} else if(qrytype==='N'){
let resarr = results[results.length-1];
let newid= '';
if(resarr.length)
newid = resarr[0]['#eid'];
callback(msg + newid);
} else if(qrytype==='U'){
//let ret = 'I#' + entity + ' updated#Updated rows count: ' + results[1].changedRows;
callback(msg);
} else if(qrytype==='D'){
//let resarr = results[1].affectedRows;
callback(msg);
}
});
connection.on('error', function (err) {
connection.release();
callback('E#connection.on-Error occurred.#'+ err.sqlMessage);
return;
});
});
}
try this
var express = require('express');
var mysql = require('mysql');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
console.log(app);
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "admin123",
database: "sitepoint"
});
con.connect(function(err){
if(err){
console.log('Error connecting to Db');
return;
}
console.log('Connection established');
});
module.exports = app;
you can create a global variable and then access that variable in other files.
here is my code, I have created a separate file for MySQL database connection called db.js
const mysql = require('mysql');
var conn = mysql.createConnection({
host: "localhost",
user: "root",
password: "xxxxx",
database: "test"
});
conn.connect((err) => {
if (err) throw err;
console.log('Connected to the MySql DB');
});
module.exports = conn;
Then in the app.js file
const express = require('express');
const router = express.Router();
// MySql Db connection and set in globally
global.db = require('../config/db');
Now you can use it in any other file
const express = require('express');
const router = express.Router();
router.post('/signin', (req, res) => {
try {
var param = req.body;
var sql = `select * from user`;
// db is global variable
db.query(sql, (err, data) => {
if (err) throw new SyntaxError(err);
res.status(200).json({ 'auth': true, 'data': data });
});
} catch (err) {
res.status(400).json({ 'auth': false, 'data': err.message });
}
});