sqlite3 callbacks (node.js) - javascript

I'm trying to compare an entered email on my website, to ones in the database to see whether it already exists. If it does, then the function returns false and an error is displayed.
var db = new sqlite3.Database('users_db.db');
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (rows == undefined ){
global.returnvalue2 = false;
}
}
);
What I want is for the function to be run immediately after the selection, so that the returned value is false, and the user record is not created.
At the moment I realise that the callback is being called after everything, so its just making the selection and carrying on throughout the rest of the program until the end.
How can I check if there are any existing records with the same email?

Make use of the async features in javascript, so your code would look something like this;
var db = new sqlite3.Database('users_db.db');
function checkemail(email, cb) {
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (err || rows == undefined ){
cb("bad email", null)
} else {
cb(null,rows)
}
});
}
function checkpassword(pw,cb) {....}
function checkclass(cls,cb) {....}
and then write you code like this;
checkemail(myemail, function(err,rows) {
if (err) return alert(err);
checkpassword(pw, function(err, msg) {
if (err) return alert(err);
checkclass(cls, function(err, msg) {
if (err) return alert(err);
alert("Congratulation you passed all the checks");
});
});
});

Here's a little one I made.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('iHacks.db');
function get_user_credentials (email, password)
{ return new Promise((rs, rj) => {
function callback (err, User)
{
if (err) rj(err);
rs(User);
}
db.get('select * from users where email=? and password=?', [email, password], callback);
}); }
function login (email, password)
{ return new Promise ((rs, rj) => {
// Hashing the password.
password = sha256(password + 'EzSalt');
// Creating an Error
const err = new Error('Email or password did not match!');
// Callback functions
function check (User)
{
rs(User);
}
function fail (err)
{
rj(err);
}
// Getting the user credentials
get_user_details(email, password).then(check).catch(fail);
}); }
login()
.then(/* Continue code */)
.catch(err => {throw new Error(err); })
;

Related

How to keep Waiting the nested function to return value to parent function

Below is the piece of code. I'm always getting initial value of valid variable as the last return statements run before the DB Query completely executes.
async login(username, password, ctx) {
let sql = 'SELECT * FROM users WHERE username=?;'
let valid = false; //I'm always getting this value
await this.db.query(sql, [username], function(err, rows, fields){
console.log(rows);
if(rows.length > 0)
{
console.log('coming into');
console.log(JSON.stringify(rows));
valid = bcrypt.compare(password, rows[0].pass)
console.log('valid is ', valid);
if(valid === false) throw new Error(`invalid password for account "${username}"`)
ctx.session.user_id = rows[0].id
ctx.session.authorised = true
return ctx.redirect(`/secure?msg=you are now logged in...`)
}
else
throw new Error(`username ${username} not found ${JSON.stringify(rows)}`);
return valid;
});
}
One way to fix this is to wrap the db-call in a promise and wait for this promise to resolve/reject. Then, you can either set the authorised-flag and redirect the user or handle the error:
async login(username, password, ctx) {
try {
const rows = await new Promise((resolve, reject) => {
let sql = 'SELECT * FROM users WHERE username=?;'
this.db.query(sql, [username], function (err, rows, fields) {
if (rows && rows.length > 0) {
console.log('coming into');
console.log(JSON.stringify(rows));
valid = bcrypt.compare(password, rows[0].pass)
console.log('valid is ', valid);
if (valid === false) {
reject(new Error(`invalid password for account "${username}"`));
}
return resolve(rows);
}
reject(new Error(`username ${username} not found ${JSON.stringify(rows)}`); )
});
});
ctx.session.user_id = rows[0].id
ctx.session.authorised = true
return ctx.redirect(`/secure?msg=you are now logged in...`)
} catch (err) {
// handle your error, e.g. ctx.redirect('/error-page')
}
}

Trouble setting a players ID and Username through callback

With an HTML5 game I am developing at the moment, I get the player's username and ID through a token sent in by the client which are all stored in a database. Everything was working perfectly up until I had to actually set the values for the player.
I've been searching all over the internet for similar problems that I am facing, and have come up with nothing. I am not sure if this is a variable scope problem or if I am taking the wrong approach to doing this.
Anyways, here's both the socket.player and getUserSession function
var newUserID;
var newUsersName;
socket.player = {
id: newUserID,
x: randomInt(100,400),
y: randomInt(100,400),
username: newUsersName
}
function getUserSession(sessionKey, callback){
var sql = "SELECT * FROM game_sessions WHERE unique_key=? AND still_active=?";
var stillActive = 1;
var returnData = [];
db.query(sql, [sessionKey, stillActive], function(err, result){
if (err){
throw err;
}
var numFound = result.length;
if (numFound == 1) {
//session was found
var userID = result[0].user_id;
returnData.push(result[0].user_id);
var sql2 = "SELECT * FROM users WHERE id=?";
db.query(sql2, [userID], function(err, result){
if (err){
throw err;
}
var uName = result[0].username;
returnData.push(result[0].username);
return callback(returnData);
});
}
});
}
And the callback function:
getUserSession(data.token, function(result){
newUserID = result[0];
newUsersName = result[1];
socket.broadcast.emit('newclient',socket.player);
});
I would do something like this:
function sqlQuery(sql, params) {
return new Promise((resolve, reject) => {
db.query(sql, params, function(err, result) {
if (err) {
return reject(err);
}
return resolve(result);
});
});
}
function getUserSession(sessionKey, callback){
const sql = "SELECT * FROM game_sessions WHERE unique_key=? AND still_active=?";
const stillActive = 1;
let returnData = [];
try {
return sqlQuery(sql, [sessionKey, stillActive])
.then(result => {
if (result.length === 1) {
//session was found
const userID = result[0].user_id;
returnData.push(result[0].user_id);
const sql2 = "SELECT * FROM users WHERE id=?";
return sqlQuery(sql2, [userID])
.then(result => {
const uName = result[0].username;
returnData.push(result[0].username);
return callback(returnData);
})
}
})
} catch (err) {
//handle err
}
}
Edit: if the callback function being passed in is an aync function, you'll probably need to modify the above snippet to await it.

How to check if the db connection is success or not in node js and mysql

I'm using mysql connection pool to create connection. The code looks like the following.
var pool = mysql.createPool(connectionProps);
by accessing pool, I'll get the an Object, even if the connection is not Successful. I checked it with starting and stopping mysql.
What I want is that, I need to check connection is successful or not as follows.
if(pool){ // mysql is started && connected successfully.
console.log('Connection Success');
doSomething();
}else{
console.log('Cant connect to db, Check ur db connection');
}
I want something like this. So how can we do this with the mysql pool Object. Can someone please help me?
Thanks n Regards
Commonly you would do something like select something arbitrary from the db, and catch an error if that failed. Example from the docs.
const pool = mysql.createPool(connectionProps);
pool.query('SELECT 1 + 1 AS solution', (error, results, fields) => {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
var pool = mysql.createPool(config.db);
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
And require to use it like:
db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id)
.on('result', function (row) {
setData(row);
})
.on('error', function (err) {
callback({error: true, err: err});
});

How can I avoid logging into SalesForce databases on every router in Express.js?

I need to do this to log into SalesForce Databases and pass a query. Now I will be passing a lot of queries on many routers of express.js and its a real pain to login in every router. Please let me know if you know how I can avoid this.
var conn = new jsforce.Connection({
oauth2 : salesforce_credential.oauth2
});
var username = salesforce_credential.username;
var password = salesforce_credential.password;
// I want to avoid this login on every router
conn.login(username, password, function(err, userInfo) {
if (err) {
return console.error(err);
}
conn.query("SELECT id FROM Sourcing__c WHERE id = 'req.session.ref'",function(err, result) {
if (err) {
return console.error(err);
}
if(result.records.length === 0){
req.session.ref = "";
}
var body = {
"Auth__c": req.user.id,
"Stus__c": "Pending - New Hire",
"Record": "012lvIAC",
"Sourcing__c": req.session.ref
};
conn.sobject("SFDC_Employee__c").create(body, function(err, ret) {
if (err || !ret.success) {
return console.error(err, ret);
}
console.log("Created record id : " + ret.id);
// ...
});
});
});
You may save the login status and check it every time when do a query,
here I add a property on conn (the instance of 'jsforce.Connection'), I'm not sure but I think there may be a method or property that show the login status of the 'conn', you may dig into its documents.
var conn = new jsforce.Connection({
oauth2 : salesforce_credential.oauth2
});
var username = salesforce_credential.username;
var password = salesforce_credential.password;
conn._isLogin = false;
// here in your route handler
if (!conn._isLogin) {
conn.login(username, password, function(err, userInfo) {
if (err) {
return console.error(err);
}
conn._isLogin = true;
doQuery(conn);
});
} else {
doQuery(conn);
}
function doQuery (conn) {
conn.query("SELECT id FROM Sourcing__c WHERE id = 'req.session.ref'",function(err, result) {
if (err) {
return console.error(err);
}
if(result.records.length === 0){
req.session.ref = "";
}
var body = {
"Auth__c": req.user.id,
"Stus__c": "Pending - New Hire",
"Record": "012lvIAC",
"Sourcing__c": req.session.ref
};
conn.sobject("SFDC_Employee__c").create(body, function(err, ret) {
if (err || !ret.success) {
return console.error(err, ret);
}
console.log("Created record id : " + ret.id);
// ...
});
});
}

Node-sqlite3 asynchronous callback

I am writing a simple script to retrieve a password from the table and validate in node.js Here is the script
module.exports = {
login: function (email, pass) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?", email, function(err, row) {
if (err !== null) {
console.log("An error has occured");
return "error";
} else if(row.password === pass) {
console.log("success");
return "success";
} else {
console.log("Incorrect password");
return "failure";
}
});
}
};
The console log statements are correct when the if else cases are evaluated. However the return value is undefined.
I do not understand why the return value is undefined if the logging is done correctly.
You can't return values from a callback because doing so is meaningless. You have to pass in a callback to your login() function and call that with (err, result) inside your db.get() callback:
module.exports = {
login: function (email, pass, cb) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?",
email,
function(err, row) {
if (err)
return cb(err);
cb(null, row.password === pass);
});
}
};

Categories