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

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();

Related

Q: Writing GraphQL resolver that uses mysql2 query

Noob question. I'm trying to write an Apollo Server GraphQL resolver that will query and return a user from a MySQL database.
This is what I have so far:
const UserQueries = {
user: (_, args, { pool }) => {
let data = {};
pool.query(
"SELECT * FROM user_table WHERE `id` = ?",
[args.id],
(err, rows) => {
if (err) throw err;
else {
data.id = rows[0].id;
data.name = rows[0].name;
data.username = rows[0].username;
data.email = rows[0].email;
}
}
);
return data;
},
};
pool is the mysql2 connection pool. If I console log inside that else statement I am getting the correct data back from the database. The problem is I can't make it go into that variable. If I move the return statement inside the else statement it still doesn't work.
Definitely a noob question but I'm totally stuck. Thanks.
I think it should work, you should check your typedef, whether the response (data object fields) matches with the respective typedef fields or not.

Node mysql in Discord.js returns empty result/array

I'm trying to make a command that get the selected queries from a table where the id is the one i use in the command, for example: !db 1 but I'm having a problem.
The problem is that the result is empty.
My code:
const Discord = require('discord.js');
const mysql = require('mysql');
module.exports.run = async (bot, message, args, connection) => {
const asd = args.slice(1,2).join(' ');
let querystring = `SELECT * FROM test WHERE id = '${asd}'`
connection.query(querystring, function (err, results, rows) {
if (err) throw err;
console.log(results);
});
}
module.exports.help = {
name: "db"
}
I appreciate any help! Thanks!
From the screenshot you posted earlier, your id column is a type INT. This code is searching as if the column is a VARCHAR.
Try this:
const id = args.slice(1, 2).join(' ');
if (isNaN(id)) { return; } // if the input isn't a number
connection.query(`SELECT * FROM test WHERE id = ${Number.parseInt(id)}`, (err, res, rows) => {
if (err) throw new Error(err);
console.log(res);
});
Important: This code allows SQL Injection. Template literals do not protect against this.

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);

Nested Queries not being called in MariaDB using nodeJS

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)); ... }

rely on the result of a query to run another nodejs mysql

Hey guys I have the following node code and it works fine
import express from 'express';
import connection from '../index.js'
const router = express.Router();
router.get('/allTemplates', function (req, res) {
let queryString="select count(*) as exist from users where userName='bob'";
let query = connection.query(queryString, (error, result) => {
if(error) {throw error;}
res.json(result);
})
});
module.exports = router;
what I want to do is react to this with something like
if(exists==1){error='sorry but that user already exists';} else {
queryString="insert into users (userName, email, address) values('bob', 'emailAddress#email.com', 'address')";
let query = connection.query(queryString, (error, result) => {
if(error) {throw error;}
res.json(result);
})
}
I come from a php background so this is all very new and the async of node freaks me out but I have to use it for my new job. How would I react to a result of one query and run another one based on the outcome.
I put the mysql library in a variable called database and I am using async await to run queries. In the database file I connect to the database and set up my variables like so:
const mysql = require("mysql");
const util = require("util");
const awsConfig = {
host: process.env.RDS_HOST,
user: process.env.RDS_USER,
password: process.env.RDS_PASSWORD,
database: process.env.RDS_DATABASE
};
const connection = mysql.createConnection(awsConfig);
connection.query = util.promisify(connection.query.bind(connection));
connection.end = util.promisify(connection.end.bind(connection));
module.exports = connection;
Than i use async await to run queries and use the results to run or not run others. like so:
let result;
let sqlStatement ="";
result = await database.query(sqlStatement);
let userExists = result[0].exist;
sqlStatement =
"SELECT COUNT(*) AS exist FROM user where userName=" +
database.escape(req.body.userName);
if(userExists==0){
result = await database.query("INSERT INTO user SET ?", [req.body]);
}
hope this helps someone else