Do I need the promise in my MySQL statement? - mysql

Below is a MySQL statement in my Node.js app. I used a promise in MySQL function to get API endpoint to work. Is this a typical pattern for Node.js and MySQL?
const express = require('express');
const app = express();
app.use(express.static('client'));
const config = require('./config')
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.HOST,
user: config.USER,
password: config.PASSWORD,
database: config.DATABASE
});
function GetConsumers(req, res) {
return new Promise(function (resolve, reject) {
con.connect(function (err) {
if (err) throw err;
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) throw err;
//console.log(result);
resolve(result);
});
});
}).then(rows => res.send(rows));
}
app.get('/consumers', GetConsumers);
module.exports = app;

As George commented, you don't really need to return a promise here.
function GetConsumers(req, res) {
con.connect(function (err) {
if (err) {
res.send(err)
};
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) {
res.send(err)
};
//console.log(result);
res.send(result)
});
});
}
If you really want to use promises, it is always a good practice to catch the exceptions.
function GetConsumers(req, res) {
return new Promise(function (resolve, reject) {
con.connect(function (err) {
if (err){
reject(err);
}
con.query("SELECT * FROM " + config.DATABASE + ".Contracts",
function (err, result, fields) {
if (err){
reject(err);
}
//console.log(result);
resolve(result);
});
});
})
}
Call GetConsumers function where ever you want it.
GetConsumers(req,res).then(rows => res.send(rows))
}).catch(err =>{
console.log("Handle your error here");
res.send("error")
})
Mysql npm has good documentation of how to use the module. You can refer it more here

Related

Node JS Express MySQL , can not get all users

I can't get all users, but if write manually it works.
class User {
static getAll(result) {
let sql = `SELECT * FROM users`;
sql.query(sql, (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
console.log("users: ", res);
result(null, res);
});
}
}
exports.findAll = (req, res) => {
User.getAll = (err, data) => {
if (err) return res.status(500).send({ message: err.message || "Some error occurred while retrieving users." });
res.send(data);
}
}
query() is a method of a mysql connection, you are using it as a string method:
let sql = 'SELECT * FROM users';
sql.query()
You should first create the connection with your database, and then use that connection object to make your queries, something like this:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM users", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});

Connect to MySql in node.js project with mvc architecture

I have a node.js project with mvc architectures,
I am trying to connect it to mysql database, and write a query,
I get the query result, but when I try to call the function that declare the query, I get an empty result,
I guess so it because of the query calling is async.
in my model:
exports.getAllUsers = function () {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
return result;
}
});
});
}
in my controller:
exports.get_all_users = function (req, res) {
var arr = UserModel.getAllUsers();
res.send(arr);
}
the arr in get_all_users function is always undefined,
what can be the problem???
There are three options you could use in node.js.
These are simple code for demo three style, they still have a lot space for improvement.
callback style
exports.getAllUsers = function (callback) {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
callback(result);
}
});
});
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers((result) => {
res.send(result);
});
}
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers().then(result) => {
res.send(result);
});
}
async-await style
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = async function (req, res) {
const result = await UserModel.getAllUsers();
res.send(result);
}

Nodejs mysql transaction rollback not working

I am using Nodejs MySQL and tried to create database level transaction so that I can execute a bunch of statements in a batch and rollback if there is an error in any step. I tried to follow this tutorial.
My database module is:
let mysql = require('mysql')
let keys = require('../config/keys')
let util = require('util')
let pool = mysql.createPool({
connectionLimit: 20,
host: keys.connection.host,
user: keys.connection.user,
password: keys.connection.password,
database: keys.connection.database,
dateStrings: true
// debug:true //Set this to true for verbose debugging. Leaving this to default for now cause it is creating too many messages at my console
})
pool.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.')
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.')
}
}
if (connection) connection.release()
return
})
pool.query = util.promisify(pool.query)
const connection = () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) reject(err);
console.log("MySQL pool connected: threadId " + connection.threadId);
const query = (sql, binding) => {
return new Promise((resolve, reject) => {
connection.query(sql, binding, (err, result) => {
if (err) reject(err);
resolve(result);
});
});
};
const release = () => {
return new Promise((resolve, reject) => {
if (err) reject(err);
console.log("MySQL pool released: threadId " + connection.threadId);
resolve(connection.release());
});
};
resolve({
query,
release
});
});
});
};
// const query = (sql, binding) => {
// return new Promise((resolve, reject) => {
// pool.query(sql, binding, (err, result, fields) => {
// if (err) reject(err);
// resolve(result);
// });
// });
// };
module.exports = {
pool,
connection
}
In my route, I am trying to use the connection which should allow transaction:
const mysql = require('../../middleware/database')
async function buildCoreSchemas(){
const connection = await mysql.connection();
try{
await connection.query("START TRANSACTION");
await connection.query(`CREATE TABLE adjustreason (
AdjustID int NOT NULL AUTO_INCREMENT,
AdjustReason varchar(100) NOT NULL,
PRIMARY KEY (AdjustID)
)`)
await connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`)
await connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`)
await connection.query("COMMIT");
}
catch(err){
await connection.query("ROLLBACK");
console.log(err)
return false
}
finally {
await connection.release();
}
As you can see I my second insert statement is wrong as there is no column name called FAKE COLUMN. So, the error gets caught and I get the error message in my console:
Unknown column 'FAKECOLUMN' in 'field list
But when I go and look at my database the transaction is not rollbacked because I can see that the first record is still there. What am I doing wrong?
Ciao, try to modify code in this way:
connection.beginTransaction(function(err) {
if (err) { throw err; }
connection.query(`CREATE TABLE adjustreason (
AdjustID int NOT NULL AUTO_INCREMENT,
AdjustReason varchar(100) NOT NULL,
PRIMARY KEY (AdjustID)
)`, function (error, results, fields) {
if (error) {
return connection.rollback(function() {
throw error;
});
}
connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`, function
(error, results, fields) {
if (error) {
return connection.rollback(function() {
throw error;
});
}
connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`, function
(error, results, fields) {
if (error) {
return connection.rollback(function() {
throw error;
});
}
connection.commit(function(err) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
});
so you call connection.query inside connection.beginTransaction and if one of those query fails, you call connection.rollback. Otherwise connection.commit

NodeJs Restful Api Using MySQl

I have tried it through MongoDB, but I can't to use JOIN Query in mongoDB and my project is wide enough. So, Want to Create Restful API in node js in MySQL.
Can anyone suggest the solution
For creating REST API you can go with express JS
var express = require('express');
var app = express();
app.get('/', function (req, res) {
//BELOW-CODE
});
You can connect Mysql by following this code:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
);
});
Note: Install expressJS framework to get started
Happy coding :-)
For MySQL with NodeJS you can use Sequelize, it's an ORM kinda like doctrine in symfony
http://docs.sequelizejs.com/
`'user strict';
var sql = require('./db.js');
//Task object constructor
var Task = function(task){
this.task = task.task;
this.status = task.status;
this.created_at = new Date();
};
Task.createTask = function createUser(newTask, result) {
sql.query("INSERT INTO tasks set ?", newTask, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
Task.getTaskById = function createUser(taskId, result) {
sql.query("Select task from tasks where id = ? ", taskId, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
result(null, res);
}
});
};
Task.getAllTask = function getAllTask(result) {
sql.query("Select * from tasks", function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
console.log('tasks : ', res);
result(null, res);
}
});
};
Task.updateById = function(id, task, result){
sql.query("UPDATE tasks SET task = ? WHERE id = ?", [task.task, id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
Task.remove = function(id, result){
sql.query("DELETE FROM tasks WHERE id = ?", [id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
module.exports= Task;

If I console.log my results it shows up, but if I return it it doesn't

My return result doesn't make it all the way back to API endpoint.
Do you see what I'm doing wrong?
app.js
const express = require('express');
const app = express();
app.use(express.static('client'));
var GetContracts = require('./contractsService');
app.get('/contracts', async (req, res) => {
var results = await GetContracts.get();
console.log(results);
res.send(results);
});
module.exports = app;
contractsService.js
var mysql = require('mysql');
const config = require('./config')
var con = mysql.createConnection({
host: config.HOST,
user: config.USER,
password: config.PASSWORD,
database: config.DATABASE
});
exports.get = function () {
con.connect(function (err) {
if (err) {
throw new Error('Error by Rodney')
};
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) {
throw new Error('Error by Rodney')
};
return result;
//console.log(result); //works
});
});
}
query method accepts error-first callback that isn't affected by returned value. GetContracts.get doesn't return a promise, and awaiting won't do anything.
It should be promisified in order to be used in promise control flow:
exports.get = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err) {
reject(new Error('Error by Rodney'))
};
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) {
reject(new Error('Error by Rodney'));
} else
resolve(result);
});
});
});
}
Or preferably, use existing promise-based MySQL library like promise-mysql, something like:
var mysql = require('promise-mysql');
const conPromise = mysql.createConnection({
host: config.HOST,
user: config.USER,
password: config.PASSWORD,
database: config.DATABASE
});
exports.get = async () => {
const con = await conPromise;
const result = await con.query("SELECT * FROM " + config.DATABASE + ".Contracts");
return result;
};