how can i stop mysql from updating a table automatically - mysql

am running a cronjob to update a user table every midnight, when I stop the Nodejs application, the table keep updating by itself, and have already stop the application.
here is the nodejs code I use for the job
const CronJob = require('cron').CronJob;
const logger = require("../helpers/logger");
const { updateUser } = require("../helpers/user");
const db = require("../models/db");
const job = new CronJob('* * * * *', async function() {
db.query("UPDATE sponsored_posts SET post_status = 0", (err, data) => {
if (err) logger.debug(err)
});
db.query("DELETE FROM sponsored_posts", (err, data) => {
if (err) logger.debug(err)
});
//EXPIRING USER
db.query("SELECT * FROM all_users WHERE membership_expired > 0", async (err, data) => {
if (data.length > 0) {
//FIlter Through All User
//Deduct While They Havent Expired
await data.map(async user => {
await updateUser({
uid: parseInt(user.uid),
membership_expired: user.membership_expired - 1
})
})
}
})
db.query("SELECT * FROM all_users WHERE membership_expired = 0", async (err, data) => {
if (data.length > 0) {
//FIlter Through All User
//Set Can Purchase To 1
await data.map(async user => {
await updateUser({
uid: parseInt(user.uid),
can_purchase: 1
})
})
}
});
}, null, false, "Africa/Lagos");
job.start();

Related

NodeJS with MySQL - Return blank Array

I have initialized an array "userTasklist". I have pushed the object in this array in .map function. After .map, I have console this Array but array is blank.
Than I have console the object in .map function and all the value print successfully but in Array there are no value. Don't know why.
exports.allUserList = (req, res) => {
let userID = req.params.userid;
const ghusersQuery = "SELECT user_id, name, employee_code FROM users WHERE under_gh = ?";
conn.query(ghusersQuery, [userID], (err, userdata) => {
if (err) {
res.send({ message: err })
} else {
if (userdata && userdata.length > 0) {
let userTasklist = [];
userdata.map((datauser) => {
var objtask = {};
const userDataQuery = "SELECT * FROM tasklist WHERE user_id = ?";
conn.query(userDataQuery, [datauser.user_id], (errnew, taskdata) => {
if (taskdata && taskdata.length > 0) {
objtask = {
userid: datauser.user_id,
tasklist: taskdata
}
userTasklist.push(objtask);
}
})
})
console.log(userTasklist)
res.send({ message: "user list fetched", userdata: userdata, tasklistdata: userTasklist })
} else {
res.send({ message: "Data not found!" })
}
}
})
}
Simplified solution using mysql21 for handling queries as Promises.
exports.allUserList = async (req, res) => {
const { userid } = req.params
const users = await connection.query('SELECT user_id, name, employee_code FROM users WHERE under_gh = ?', [userid])
if (!users.length)
return res.send({ message: "Data not found!" })
// better fetch all relevant tasks in bulk
const tasks = await connection.query('SELECT * FROM tasklist WHERE user_id IN (?)', [users.map(r => r.user_id)])
res.send({ message: "user list fetched", users, tasks })
}

When I try to take the id it takes it as an undefined variable

When I try to take the id it takes it as an undefined variable, but if I just do the res.send () there is no problem Well, I can't think of what to do, have I made several attempts during days, any recommendations?
router.get('/products/:id', (req, res) => {
const id = req.params.id;
const idsiguiente = req.params.id + 1;
const idanterior = req.params.id - 1;
var numero_de_articulos = 16;
const iniciar = (id - 1) * numero_de_articulos;
console.log(req.params.id);
conexion.query('SELECT COUNT(*) AS cuenta_productos FROM Products', (error, cuenta_productos) => {
if (error) throw error;
var paginas = cuenta_productos[0]['cuenta_productos'] / numero_de_articulos;
paginas = Math.ceil(paginas);
conexion.query('SELECT * FROM Products limit ?,?', [iniciar, numero_de_articulos], (error, productos) => {
if (error) throw error;
//res.send(productos);
res.render('products', {
products: productos,
id: id,
paginas: 1,
siguiente: idsiguiente,
anterior: idanterior
});
})
})
});

check if username and email already exists with expressjs validator and mysql

I want to check if email already exist in mysql database using express-validator package to do this. The example about checking email is not for mysql database.
The code is submitting form values successfully but the checks are being skipped. This is a middleware but the middleware is not been implemented before inserting into the database.
The solution I currently implemented is from stackoverflow. But still not working for me
router.post("/register",[
body('username').not().isEmpty().isLength({ min: 4 }).trim().escape(),
//check if email is aleady existing in the database
body('email').not().isEmpty().isEmail().normalizeEmail().custom(async (email, {req})=>{
const getEmails = "SELECT * FROM users WHERE email=" + req.body.email;
return await con.query(getEmails, [email], (error, rows, fields)=>{
if(error){
console.log("the email is not ok",error)
}else{
if (rows.length != 0) {
res.redirect('/guests/register');
return Promise.reject("user already exists.");
}else{
return true;
}
}
})
}),//end check if email already exit
body('phone').not().isEmpty().isLength({ min: 6 }),
body('password').not().isEmpty().isLength({ min: 6 }),
//check if password match
body('passwordConfirmation').not().isEmpty().isLength({ min: 6 }).custom((value, { req }) => {
if (value !== req.body.password) {
throw new Error('Password confirmation does not match password');
}
return true;
}),
//check if password match
], async function(req, res, next) {
try{
var usernames = req.body.username;
var emails = req.body.email;
var phones = req.body.phone;
const hashedPassword = await bcrypt.hash(req.body.password, 10);
let sql = "INSERT INTO `users` (username, email, phone, password) VALUES ('" + usernames + "', '" + emails + "', '" + phones + "', '" + hashedPassword + "')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted, ID: " + result.insertId);
res.redirect('/guests/login');
})
}catch{
//console.log("something is wrong", error)
res.redirect('/guests/register');
}
});
This code works for me:
const express = require('express');
const router = express.Router();
const { check,validationResult } = require('express-validator');
const bcrypt = require('bcrypt');
const bcryptRounds = 10;
router.post('/register', [
check('username')
.exists()
.trim()
.matches(/^[a-zA-Z\ö\ç\ş\ı\ğ\ü\Ö\Ç\Ş\İ\Ğ\Ü ]{3,16}$/)
.withMessage('Invalid username!'),
check('mentionName')
.exists()
.trim()
.matches(/^(?=.*[a-z])[a-z0-9_]{3,15}$/)
.custom(async mentionName => {
const value = await isMentionNameInUse(mentionName);
if (value) {
throw new Error('Mention name is already exists!!!');
}
})
.withMessage('Invalid mention name!!!'),
check('email')
.exists()
.isLength({ min: 6, max: 100 })
.isEmail()
.normalizeEmail()
.trim()
.custom(async email => {
const value = await isEmailInUse(email);
if (value) {
throw new Error('Email is already exists!!!');
}
})
.withMessage('Invalid email address!!!'),
check('password')
.exists()
.isLength({ min: 6, max: 16 })
.escape()
.trim()
.withMessage('Invalid password!!!'),
check('rePassword').exists().custom((value, { req }) => {
if (value !== req.body.password) {
throw new Error('The passwords is not same!!!');
}
return true;
})
],
function (req, res) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
} else {
console.log("----->START USER REGISTRATION");
const username = req.body.username;
const mentionName = '#'+req.body.mentionName;
const email = req.body.email;
const pass = req.body.password;
bcrypt.hash(pass, bcryptRounds, function(err, hash) {
console.log("HASH PASS : "+hash);
//INSERT USER
});
}
});
function isMentionNameInUse(mentionName){
var conn = require('../../modules/mysql_db');
return new Promise((resolve, reject) => {
conn.query('SELECT COUNT(*) AS total FROM users_table WHERE m_name = ?', [mentionName], function (error, results, fields) {
if(!error){
console.log("MENTION COUNT : "+results[0].total);
return resolve(results[0].total > 0);
} else {
return reject(new Error('Database error!!'));
}
}
);
});
}
function isEmailInUse(email){
var conn = require('../../modules/mysql_db');
return new Promise((resolve, reject) => {
conn.query('SELECT COUNT(*) AS total FROM users_table WHERE email = ?', [email], function (error, results, fields) {
if(!error){
console.log("EMAIL COUNT : "+results[0].total);
return resolve(results[0].total > 0);
} else {
return reject(new Error('Database error!!'));
}
}
);
});
}

How to get return values from Async/await function when fetching the data from mySQL in Nodejs

I am fetching some exchange data from DB, then extracting the name of distinct exchanges and passing again into MYSQL query to fetch data from a different table.
The problem I am facing is that async await does not return the value rather just return Promise { }.
Below is the code that I am trying, wondering where I am going wrong.
//Function that fetches the exchanges from DB
const getExchange = () => {
return new Promise((resolve, reject) => {
db.connection.query(`
SELECT *
FROM,
(
SELECT
exchange,
COUNT(pair) as noOfMarkets
FROM ticker_data
) as t
`, (err, resp) => {
if (!err) {
resolve(resp)
} else {
reject(err)
}
})
})
}
// push unique exchanges to an array.
const getExchangesData = async () => {
const allExchanges = await getExchanges();
let exchanges = []
allExchanges.forEach(item => {
let exchange = {
exchange: item.exchange
}
exchanges.push(exchange)
})
return await exchanges
}
// mapping through an array of exchanges and passing to DB query to get data from the DB.
const getSingleExchange = async () => {
const exchanges = await getExchangesData()
await Promise.all(exchanges.map(async (item) => {
db.connection.query(`
SELECT
exchange_rank,
name
volume24hUSD
(
SELECT
volume24hUSD as tradingVolYesterday
FROM exchanges
WHERE name = '${item.exchange}'
AND createdAt >= now() -interval 1 day
AND createdAt < now() -interval 1 day + interval 120 second
LIMIT 1
) volumeDay1
FROM exchanges
WHERE name = '${item.exchange}'
`, (err, resp) => {
if (!err) {
console.log(resp) // getting all the values
let volData = {
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
}
return volData
}
})
}))
}
const data = getSingleExchange()
console.log(data) // returning Promise { <pending> }
Edit
After making changes suggested in an answer, I still have an issue:
//Function that fetches the exchanges from DB
const getExchange = () => {
return new Promise((resolve, reject) => {
db.connection.query(`
SELECT *
FROM,
(
SELECT
exchange,
COUNT(pair) as noOfMarkets
FROM ticker_data
) as t
`, (err, resp) => {
if (!err) {
resolve(resp)
} else {
reject(err)
}
})
})
}
// push unique exchanges to an array.
const getExchangesData = async () => {
const allExchanges = await getExchanges();
let exchanges = []
allExchanges.forEach(item => {
let exchange = {
exchange: item.exchange
}
exchanges.push(exchange)
})
return await exchanges
}
// mapping through an array of exchanges and passing to DB query to get data from the DB.
const getSingleExchange = async () => {
const exchanges = await getExchangesData()
await Promise.all(exchanges.map((item) => {
return new Promise((resolve, reject) => {
db.connection.query(`...`, (err, resp) => {
if (!err) {
resolve(resp)
} else {
reject(err)
}
}).then(resp => {
console.log(resp)
let volData = {
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
}
return volData
})
})
}))
}
getSingleExchange().then(data => {
console.log(data)
});
I now get this error:
(node:30583) UnhandledPromiseRejectionWarning: TypeError: db.connection.query(...).then is not a function
at Promise (/getExchanges.js:217:16)
at new Promise ()
at Promise.all.exchanges.map (/getExchanges.js:145:16)
at Array.map ()
at getSingleExchange (/getExchanges.js:144:33)
The main issue is in this part:
await Promise.all(exchanges.map(async (item) => {
That map callback is not returning anything, and it has no await, so using async makes no sense.
Instead remove async:
await Promise.all(exchanges.map((item) => {
... and return a promise in the callback function, much like you had done in the first function:
return new Promise((resolve, reject) => {
db.connection.query(`...`), (err, resp) => {
if (!err) {
resolve(resp)
} else {
reject(err)
}
})
}).then(resp => {
console.log(resp)
let volData = {
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
}
return volData
});
You would benefit from writing one generic function that promisifies query, so that you don't have to do that new Promise-thing for every single query you need.
Finally, you cannot expect to get an asynchronous result synchronously: async functions do not return the asynchronous result synchronously, but return a promise for it. So your last lines (main code) should still await. So either do this:
(async () => {
const data = await getSingleExchange()
console.log(data)
})(); // immediately executing (async) function expression
Or:
getSingleExchange().then(data => {
console.log(data)
});
NB: doing return await exchanges in the second function makes no sense (exchanges is not a promise), so you can just do return exchanges.

How to insert records in the database and then update some fields?

I want to do a multiplication of items that are separated into groups in my database a certain number of times but when doing the multiplication I need to change the value of a field called GroupNumber.
For this, I am making two HTTP requests within a looping (FOR).
The first one does the copy of what I need and the second one does an UPDATE in the GroupNumber field.
image 1
As you can see the copy is done 3 times, but the value of GroupNumber (Group #) assumes the value of the group of products copied +1 (in case '2') and remains so. I would like the copy to be shown below.
Image 2
Follow the code for review:
products.component.ts
copyProductsOfGroup() {
const quoteID = + this.activatedRoute.snapshot.paramMap.get('id');
const groupNumber = this.copyGroupProductsForm.get('copyGroup').value
const multiplier = this.copyGroupProductsForm.get('multiplier').value
for (let i = 0; i < multiplier; i++) {
this.productService.copyGroupProduct(quoteID, groupNumber)
.subscribe(
(cloneProductsInfos) => {
this.cloneProductsInfos = cloneProductsInfos
console.log(this.cloneProductsInfos)
},
(err) => {
console.log(err)
},
() => {
this.productService.updateCopyGroupProduct(this.groupNumber, this.cloneProductsInfos.insertId, this.cloneProductsInfos.affectedRows)
.subscribe(
(data) => {
console.log(data)
},
(err) => {
console.log(err)
},
() => {
this.getQuotesProducts()
this.filterGroupNumber()
this.modalService.dismissAll()
}
)
}
)
}
}
Service:
product.service.ts
copyGroupProduct(quoteID: number, groupNumber: number): Observable<CloneProductsModel> {
const url = `http://localhost:9095/copy-group/${quoteID}/${groupNumber}`
return this.http.get<CloneProductsModel>(url)
}
updateCopyGroupProduct(newGroupNumber: number, insertID: number, affectedRows: number): Observable<CloneProductsModel> {
const url = `http://localhost:9095/copy-group-update/${newGroupNumber}/${insertID}/${affectedRows}`
return this.http.get<CloneProductsModel>(url)
}
Nodejs and MySQL:
// Copy productGroup
app.get('/copy-group/:quoteID/:groupNumber', function (req, res) {
let quote_id = req.params.quoteID;
let groupNumber = req.params.groupNumber;
mydb.query(`
INSERT INTO products (
ProductName,
ProductElement,
ProductAttribute,
ProductAttributeValue,
Quantity,
ProductNotes,
FK_ID_QUOTE,
ID_POF,
ID_POE
)
(
SELECT
ProductName,
ProductElement,
ProductAttribute,
ProductAttributeValue,
Quantity,
ProductNotes,
FK_ID_QUOTE,
ID_POF,
ID_POE
FROM products AS P
WHERE P.FK_ID_QUOTE = ${quote_id} AND P.GroupNumber = ${groupNumber}
)`,
function (error, results, fields) {
if (error) throw error;
console.log(results)
return res.send(results);
});
});
app.get('/copy-group-update/:newGroupNumber/:insertID/:affectedRows', function (req, res) {
let newGroupNumber = req.params.newGroupNumber;
let insertID = req.params.insertID;
let affectedRows = req.params.affectedRows;
console.log(newGroupNumber)
console.log(insertID)
console.log(affectedRows)
mydb.query(`
UPDATE products AS P
SET P.GroupNumber = ${newGroupNumber}
WHERE P.ID BETWEEN ${insertID} AND (${insertID} + ${affectedRows} - 1)
`,
function (error, results, fields) {
if (error) throw error;
console.log(results)
return res.send(results);
})
})