Nested Queries not being called in MariaDB using nodeJS - mysql

This is my first project using MySQL and NodeJS, I am used to Mongo, so I might be doing something stupid here. Locally everything works fine (using MySQL) but when I deploy the following code to my hosting (that uses MariaDB) only the parent query inserts into the table (leads). The other table stays empty. Another issue is I don't have access to the NodeJS logs when it is deployed, but as far as I can tell the nested queries never get called.
var mysql = require('mysql');
global.db = mysql.createPool({
host : 'localhost',
user : 'client',
password : '******',
database : 'db'
});
router.post('/', function(req, res){
const d = req.body
let subscribe = (d.subscribe ? 1 : 0)
global.db.getConnection((err, conn) => {
if (err) {
res.end(JSON.stringify(err));
} else {
let lead = [null, d.voornaam, d.achternaam, d.email, d.postcode, d.opmerkingen, d.soort, subscribe]
let sql = 'INSERT INTO leads VALUES ?';
conn.query(sql, [[lead]], (err, results) => {
if (err) {
res.end(JSON.stringify(err));
conn.release();
} else {
const lead_id = results.insertId
d.types.forEach(w => {
let wens = [null, lead_id, w.woningType, w.slaapkamers, w.prijs, w.oplevering]
let sql = 'INSERT INTO wensen VALUES ?';
conn.query(sql, [[wens]], (err, results) => {
if(err) {
res.end(JSON.stringify(err));
conn.release();
}
})
})
res.end('True');
conn.release();
}
})
}
})
});

Check syntax. Note parens:
'INSERT INTO leads VALUES (?)'
Did this fail to tell you that?
if (err) { res.end(JSON.stringify(err)); ... }

Related

How to handle a full pool of mysql connections in nodejs

In my Node script I use MySQL and to be able to handle multiple connections I use a connection pool.
Today I forgot to release a connection in the mysql pool. It took me a long time to figure out what the problem was because there was no error shown anywhere.
My code:
const mysql = require('mysql');
const pool = mysql.createPool({
host : 'x',
user : 'x',
password : '#x',
database : 'x',
connectionLimit: 2
});
function executeQuery(){
pool.getConnection((err, connection) => {
if(err) console.log(err);
let query = mysql.format("SELECT * FROM users WHERE id = ?", 1);
connection.query(query, (err, rows) => {
if(err) console.log(err);
console.log(rows);
});
});
}
executeQuery(); // outputs the user as expected
executeQuery(); // outputs the user as expected
executeQuery(); // there is no output in the console, it just looks like nothing happened
My question: How to find out if there are still connections available and if there are no connection available anymore show an error or handle it in a different way?
You forgot to release your connection:
function executeQuery(){
pool.getConnection((err, connection) => {
if(err) console.log(err);
connection.query("SELECT * FROM users WHERE id = ?", [ 1 ], (err, rows) => {
connection.release(); // Give it back or else it gets lost
if(err) console.log(err);
console.log(rows);
});
});
}
There's also no reason to grab the connection like that, you can just use the pool:
function executeQuery() {
pool.query("SELECT * FROM users WHERE id = ?", [ 1 ], (err, connection) => {
if(err) console.log(err);
console.log(rows);
});
}

Node.js Mysql stopped querying after a few minutes

I have a Discord.js bot with a MySQL as a database. The problem I'm having is that the SQL stopped querying after a random amount of times, the only way that I could fix this is by restarting the node.js app
My bot involves a lot of sql querying inside of an sql query similar to :
sql.query(`SELECT xxxxx` , (err, res) => {
sql.query(`SELECT xxxxx`, (err, result) => {}
}
And my SQL pool code is :
const mysql = require('mysql');
const pool = mysql.createPool({
host : "localhost",
port : 3306,
user : "x",
password: "x",
database: 'x'
});
let sql = {};
sql.query = function(query, params, callback) {
pool.getConnection(function(err, connection) {
if(err) {
if (callback) callback(err, null, null);
return;
}
connection.query(query, params, function(error, results, fields) {
connection.release();
if(error) {
if (callback) callback(error, null, null);
return;
}
if (callback) callback(false, results, fields);
});
});
};
module.exports = sql;
My VPS is running fine, my SQL server is running fine as well. I'm not sure what's causing the problem.
My current solution is running a cronjob every 30 minutes to restart the application, I'm not sure if this is a good practice or not.

Using MySQL db functions (?) with SQLite (Node.js)

I'm using a tutorial to do JWT/bcryptjs auth and then INSERT into a SQlite
table.
Thing is the tutorial is for MySQL and I get errors like db.query is not a function
and db.escape is not a function
The db :
const sqlite3 = require('sqlite3').verbose()
const DBSOURCE = "./src/db/db.sqlite"
let db = new sqlite3.Database(DBSOURCE, (err) => {
if (err) {
// Cannot open database
console.error(err.message)
throw err
}else{
console.log('Connected to the SQLite database.')
}
});
module.exports = db
Example query :
db.query(
`SELECT * FROM users WHERE LOWER(username) = LOWER(${db.escape(
req.body.username
)});`,
(err, result) => {
if (result.length) {
return res.status(409).send({
msg: 'This username is already in use!'
});
} else { .........
My best guess is that the functions are different?
How do I get this right?
There are a lot of proprietary functions in MySQL that will not work with standard SQL in other database systems.
That is just the beginning of the differences between Mysql and SQLite
Provide some query examples and we may be able to assist you with each one.
-- update after your addition of query code...
Here is an example of sqlite-nodejs
const sqlite3 = require('sqlite3').verbose();
// open the database
let db = new sqlite3.Database('./db/chinook.db');
let sql = `SELECT * FROM users WHERE LOWER(username) = LOWER(?)`;
db.all(sql, [req.body.username], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.name);
});
});
// close the database connection
db.close();

Node JS MySQL wait for results

I'm quite new to Node JS, and I'm trying to build an API based on MySQL.
In one of my routers I'm trying to inject an insert query and based on it, get the new generated task id from mysql.
The problem is that the second query is not waiting for the response and sometimes I'm getting an error because taskId variable is undefined because it still didn't get the results from the first query.
the problematic variable that is not getting it's value correctly is taskId.
I'm attaching my code for your review, thanks for your help!
As requested: I'm attaching my required moudle as well:
const dotenv = require('dotenv');
const mysql = require('mysql');
dotenv.config();
var connection = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_TABLE,
port: process.env.DB_PORT
});
module.exports = connection;
router.post('/new', auth, async (req, res) => {
const uid = req.body.uid;
const taskName = req.body.taskName;
const description = req.body.description;
const createdDate = req.body.createdDate;
const estimatedDate = req.body.estimatedDate;
const status = req.body.status;
let taskId = '';
addTaskQuery = `INSERT INTO task (title,description,status) VALUES ('${taskName}','${description}','${status}')`;
findTaskIdQuery = `SELECT id FROM task WHERE title = '${taskName}'`;
try {
// Injecting into task table
await connection.query(addTaskQuery, (err, results) => {
if(err) {
console.log(err);
return res.send(JSON.stringify({data: err}));
}
})
// Getting the new inserted task id
await connection.query(findTaskIdQuery, (err, results) => {
if(err) {
console.log(err);
return res.send(JSON.stringify({data: err}));
}
taskId = JSON.stringify(results[0].id);
})
// Injecting into havetask table
await connection.query(`INSERT INTO havetask (id,userId,taskId) VALUES (${taskId},${uid},${taskId})`, (err, results) => {
if(err) {
console.log(err);
return res.send(JSON.stringify({data: err}));
}
})
}
catch(err) {
console.log(err);
return res.status(401).json({ msg: 'An error occured while tried to add task'});
}
})
The mysql package you use does not support Promises (=== it doesn't do async / await). So your await statements don't wait, they just fall through.
You need to try a package that handles async / await. This one might do the trick.

discord.js/node.js make code wait until sql query returns result

I am working on a discord.js bot, and I'm storing a bunch of information on various servers in a database. The problem is, that the code doesn't wait for the database to return the results. In the current situation, I'm trying to check if the server specific prefix checks out.
I tried using async and await at various places, but those didn't work. If I could, I'd rather not use .then(), because I don't really want to put all the commands inside a .then().
const { Client, Attachment, RichEmbed } = require('discord.js');
const client = new Client();
const mysql = require("mysql");
const config = require("./config.json")
var con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'botdb'
})
client.on("ready", () => {
console.log("I'm ready")
})
client.on("message", message => {
if (message.author.bot) return;
if (message.channel.type === 'dm') return;
let msg = message.content.split(" ");
let command = msg[0];
let prefix;
con.query(`SELECT * FROM serversettings WHERE ServerID = ${message.guild.id}`, (err, rows) => {
if (err) throw err;
prefix = rows[0].Prefix;
console.log(prefix)
})
console.log(`Prefix: ${prefix}, Command: ${command}`)
if (command === `${prefix}examplecommand`) {
//Do something
}
//Other code that uses prefix and command
}
It should log the prefix first, and then the Prefix: ${prefix}, Command: ${command} part, but it does it the other way around, so the examplecommand doesn't work.
Your result is caused by the fact that what's outside your query callback is executed immediately after the call. Keep in mind the mysql module is callback-based.
Possible Solutions
Place the code inside the callback so it's executed when the query is completed.
Wrap the query in a promise and await it.
function getGuild(guildID) {
return new Promise((resolve, reject) => {
con.query(`SELECT * FROM serversettings WHERE ServerID = '${guildID}', (err, rows) => {
if (err) return reject(err);
resolve(rows);
});
});
}
const [guild] = await getGuild(message.guild.id) // destructuring 'rows' array
.catch(console.error);
console.log(guild.prefix);
Use a Promise-based version of a MySQL wrapper, like promise-mysql. You could use it the same way as the code above, without worrying about coding your own Promises.
const [guild] = await con.query(`SELECT * FROM serversettings WHERE serverID = '${message.guild.id}'`)
.catch(console.error);
console.log(guild.prefix);