Convert Promise to async - javascript

I am trying to convert mySQL connection from promise to asycn await so far I have the following setup:
const mysql = require("mysql");
const pool = mysql.createPool({
connectionLimit: 10,
password: "",
user: "root",
database: "usersdb",
host: "localhost",
port: "3306",
});
let usersDB = {};
usersDB.all = () => {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users", (err, results) => {
if (err) {
return reject(err);
}
return resolve(results);
});
});
};
usersDB.one = (id) => {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users WHERE id = ?", [id], (err, results) => {
if (err) {
return reject(err);
}
return resolve(results[0]);
});
});
};
module.exports = usersDB;
Is there a way to convert this codes:
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users", (err, results) => {
if (err) {
return reject(err);
}
return resolve(results);
});
to async await and make the code more compress or succint?
UPDATE: on my router, I have these codes:
const router = express.Router();
router.get("/", async (req, res) => {
try {
let results = await db.all();
res.json(results);
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
router.get("/:id", async (req, res) => {
try {
let results = await db.one(req.params.id);
res.json(results);
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
So it just fine calling async await twice?

You can convert any callback function to promise by using util.promisify
const util = require('util')
// ....
const query = util.promisify(pool.query)
// ... inside some async function
const users = await query("SELECT * FROM users;")
// or promise style
query("SELECT * FROM users;")
.then((users) => {
console.log(users)
})
.catch(console.error)

usersDB.one = (id) => {
try {
const users = pool.query("SELECT * FROM users WHERE id = ?", [id]);
return users;
} catch (e) {
throw e;
}
};
Or more simply,
usersDB.one = (id) => pool.query("SELECT * FROM users WHERE id = ?", [id]);

What you want to do is to promisify the DB call. You can acheive this by factorisation :
const mysql = require("mysql");
const pool = mysql.createPool({
connectionLimit: 10,
password: "",
user: "root",
database: "usersdb",
host: "localhost",
port: "3306",
});
function promisify(...args){
return new Promise((resolve, reject) => {
pool.query(...args, (err, result) => {
if(err) reject(err);
resolve(result);
});
});
}
let usersDB = {};
//Then you can call it this way :
usersDB.all = async () => {
return await promisify("SELECT * FROM users");
//Note that you can avoid to await there.
};
usersDB.one = async (id) => {
return await promisify("SELECT * FROM users WHERE id = ?", [id]);
};
module.exports = usersDB;

Related

Making a jest test file for mysql database calls

I'm very new to testing with Jest. I want to make a test to see if the following function returns user data from the database I have:
let dbConnect = require('../config/dbConnect');
let findUserByEmail = (email) => {
return new Promise(async (resolve, reject) => {
try {
dbConnect.query("SELECT * FROM user_login WHERE email = ?", email, function (error, results) {
if (error) reject(error);
let user = results[0];
if(user == undefined){
resolve()
}
resolve(user);
})
} catch (e) {
reject(e);
}
})
}
How would I go about making mock data to use in testing?
EDIT: Here is dbConnect:
let mysql = require('mysql');
let dotenv = require('dotenv');
dotenv.config({path: '../.env'});
let db = mysql.createConnection({
host: process.env.DATABASE_HOST,
database: process.env.DATABASE,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
});
db.connect(function (error) {
if (error) console.log(error);
else console.log("MYSQL Connected...");
});
module.exports = db;
Edit: fixed mistake
const mysql = require('mysql')
const mockQuery = jest.fn()
jest.mock('mysql', () => ({
createConnection: () => ({
connect: () => undefined,
query: mockQuery
}),
}))
describe('findUserByEmail', () => {
it('should resolve with the user when query suceeds', async () => {
mockQuery.mockImplementationOnce((sql, email, callback) => callback(null, ['TEST USER']));
expect(await findUserByEmail()).toBe('TEST USER');
})
});

learning and implementing async await

I've been reading about async and await in JS and tried to implement them in my code (which I totally messed up).
Here is my JS.
var express = require('express');
var router = express.Router();
var jsforce = require('jsforce');
const SEC_TOKEN = 'SEC_TOKEN';
const USER_ID = 'USER_ID';
const PASSWORD = 'PWD';
const { default: axios } = require('axios');
router.get("/", async (req, res, next) => {
await initConnect;
await soqlData;
await slackPostTest;
});
initConnect = async () => {
var conn = new jsforce.Connection({
loginUrl: 'https://login.salesforce.com'
});
await conn.login(USER_ID, PASSWORD + SEC_TOKEN, (err, userInfo) => {
if (err)
console.log(err);
else {
console.log(userInfo.Id);
}
});
}
soqlData = async () => {
await conn.query('Select Id, Name from Account LIMIT 1', (err, data) => {
if (err)
console.log(err);
else
return data.records[0];
})
}
slackPostTest = async () => {
await axios.post('SLACK_WEBHOOK', {
"text": "soqlRes"
})
}
module.exports = router;
What I am trying to achieve?
Initialize my connection by passing in SEC_TOKEN, USER_ID, PASSWORD to my initConnect function this will give me a connection (conn).
Use this conn and query my salesforce instance and get some other data.
post some message(currently irrelevant, but will hook up with the above response later) to my slack endpoint.
Also can someone please give me a little detailed explanation of the solution (in terms of async/await)?
Thanks
Assuming everything else about your JsForce API usage was correct (I have no experience with it, so I can't say), here's how to promisify those callback-based APIs and call them.
var express = require("express");
var router = express.Router();
var jsforce = require("jsforce");
const SEC_TOKEN = "SEC_TOKEN";
const USER_ID = "USER_ID";
const PASSWORD = "PWD";
const { default: axios } = require("axios");
router.get("/", async (req, res, next) => {
const { conn, userInfo } = await initConnect();
const data = await soqlData(
conn,
"Select Id, Name from Account LIMIT 1",
);
await slackPostTest(data.records[0]);
});
function initConnect() {
const conn = new jsforce.Connection({
loginUrl: "https://login.salesforce.com",
});
return new Promise((resolve, reject) => {
conn.login(USER_ID, PASSWORD + SEC_TOKEN, (err, userInfo) => {
if (err) return reject(err);
resolve({ conn, userInfo });
});
});
}
function soqlData(conn, query) {
return new Promise((resolve, reject) => {
conn.query(query, (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
}
function slackPostTest(soqlRes) {
return axios.post("SLACK_WEBHOOK", {
text: soqlRes,
});
}
module.exports = router;

Can't to get connection to PostgreSQL from Node.js

During the launch my website i can't connection to my database. It doesn't get errors and the page is loading infinitely. Who know answer on this question give me some advise.
I work in (Node.js,PostgreSQL,Express)
from file config_db
const client_admin1 = {
user:'a_role',
database:'road_db',
password: '12345',
host:'localhost',
port:5432,
max:10,
idleTimeoutMillis: 30000
}
const pg = require("pg")
const client_login = require("../config/config_db");
searchUser(req, res) {
const db = new pg.Pool(client_login.client_admin1)
db.connect(function(err, client, done){
if(err){
return console.error('connection problems')
}
client.query('SELECT * FROM login_phone WHERE phone = $1 AND password1 = $2',[req.body.login, req.body.password], function(err, result){
done()
if (err || result.rowCount <= 0){
res.render('error_login_choice')
return console.error("")
}
if(result.rows[0].role_name === "client")
{
cln.getClients(req,res)
}
})
}
try this executeQuery method
const pg = require('pg');
const pgconfig = {
user: process.env.DATA_BASE_USER,
database: process.env.DATA_BASE_NAME,
password: process.env.DATA_BASE_PASSWORD,
host: process.env.DATA_BASE_HOST,
port: process.env.DATA_BASE_PORT,
};
console.log(`DB | Settings: ${JSON.stringify(pgconfig)}`);
const pool = new pg.Pool(pgconfig);
pool.on('connect', () => {
console.log('DB | new client connection establish.');
});
pool.on('error', err => {
console.error(`idle client error, ${err.message} | ${err.stack}`);
});
pool.connect(err => {
if (err) {
console.error(`PostgreSQL input: ${err}`);
} else console.log('DB | connection establish.');
});
const executeQuery = async(sql, data) => {
logger.debug(`sqlToDB() sql: ${sql} | data: ${data}`);
try {
const result = await pool.query(sql, data);
return result;
} catch (error) {
console.error(error.message);
}
};
module.exports = {
executeQuery,
};
usage:
const dbHandler = require('./db');
const getLogedInUser = login,password => {
const selectFieldsQuery = `'SELECT * FROM login_phone WHERE phone = $1 AND password1 = $2'`;
return dbHandler.executeQuery(selectFieldsQuery, [login,password]).then(e => e.rows);
};

How to properly use async await on a database query

This is the very basic route I am using:
router.get('/:date', async (req, res) => {
let tracks = []
let query = 'SELECT * from `tracks` where `playlistDate` = \''+req.params.date+'\''
let result = await pool.query(query)
console.log(result)
})
I know this by itself won't work, but what do I need to do to be able to use await on the query function like this?
This is the pool, with the credentials and addr changed.
var pool = mysql.createPool({
poolLimit : 10,
host : 'HOST',
user : 'USER',
password : 'PASS',
database : 'DB'
});
Maybe this logic would help. It depends on how you structured it.
var pool = mysql.createPool({
poolLimit : 10,
host : 'HOST',
user : 'USER',
password : 'PASS',
database : 'DB'
});
const getTracks = (date) => {
return new Promise((resolve, reject) => {
let query = 'SELECT * FROM tracks WHERE playlistDate = ?'
pool.query(query, [date], (err, res) => {
if (err) {
reject(err);
return;
}
resolve(res);
})
})
};
router.get('/:date', async (req, res) => {
try {
let tracks = await getTracks(req.params.date);
return res.status(200).json(tracks);
} catch (err) {
return res.status(400).json(err);
}
})

"syntax error at or near \"SET\"" when creating a user using node with Postgresql

I'm trying to translate my old mysql app to Postgresql, it was very difficult to connect to the server, but when i think it worked, this message appears on insomnia.
The message
I tried using different methods that i found on Google but they didn't work for me.
I think that the problem is how i'm connecting to the server.
I'm new using postgresql.
const { Pool, Client } = require("pg")
const config = require("../config")
const connection = new Pool({
host: config.postgresql.host,
user: config.postgresql.user,
password: config.postgresql.password,
database: config.postgresql.database,
port: "5432",
ssl: true
})
function list(table) {
return new Promise((resolve, reject) => {
connection.query(`SELECT * FROM ${table}`, (err, data) => {
if (err) return reject(err)
resolve(data)
})
})
}
function get(table, id) {
return new Promise((resolve, reject) => {
connection.query(`SELECT * FROM ${table} WHERE id=${id}`, (err, data) => {
if (err) return reject(err)
resolve(data)
})
})
}
function insert(table, data) {
return new Promise((resolve, reject) => {
connection.query(`INSERT INTO ${table} SET ${data}`, (err, result) => {
if (err) return reject(err)
resolve(result)
})
})
}
function update(table, data) {
return new Promise((resolve, reject) => {
connection.query(
`UPDATE ${table} SET ${data} WHERE id=${data.id}`,
(err, result) => {
if (err) return reject(err)
resolve(result)
}
)
})
}
const upsert = async (table, payload) =>
new Promise((resolve, reject) => {
connection.query(
`INSERT INTO ${table} SET ${payload} ON DUPLICATE KEY UPDATE ${payload}`,
(error, data) => {
console.log("UPDATE DATA: ", data)
if (error) {
return reject(error)
}
resolve(data)
}
)
})
function query(table, query, join) {
let joinQuery = ""
if (join) {
const key = Object.keys(join)[0]
const val = join[key]
joinQuery = `JOIN ${key} ON ${table}.${val} = ${key}.id`
}
return new Promise((resolve, reject) => {
connection.query(
`SELECT * FROM ${table} ${joinQuery} WHERE ${table}.${query}`,
(err, res) => {
if (err) return reject(err)
resolve(res[0] || null)
}
)
})
}
module.exports = {
list,
get,
upsert,
query
}
The insert query is wrong, Please change it to the below syntax. You cannot use SET in insert. SET should be used in update.
Wrong:
connection.query(`INSERT INTO ${table} SET ${data}`, (err, result)
Insert query syntax:
INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)
VALUES (value1, value2, value3,...valueN);

Categories