Working with Express and SQLite (connection and disconnection) Node.js - javascript

I have a question about the integration of SQLite (but in general of the DB) with Node.js with and Express framework.
From what I know, it is always good to open and close a connection to the db. But in Node.js, the processes are asynchronous (some times).
router.get("/", (req, res) => {
let db = new sqlLite.Database(path.resolve("data.db"), (err) => {
if (err) {
console.error(err.message);
}
console.log("Connected to the chinook database.");
});
db.get(`SELECT * FROM data WHERE key = '${req.query.data}'`, (err, row) => {
res.json(row);
});
db.close((err) => {
if (err) {
console.error(err.message);
}
console.log("Close the database connection.");
});
});
in this example, I open and close the connection directly within the route, so that it only handles the event in that case. Is this approach correct? what do you recommend?

In most cases, the better approach is to use some kind of connection pool, but depending on your application that may or may not matter.
That said, two things that will matter. First, you really need to close the connection during the callback, not subsequent to the query call:
router.get("/", (req, res) => {
let db = new sqlLite.Database(path.resolve("data.db"), (err) => {
if (err) {
console.error(err.message);
}
console.log("Connected to the chinook database.");
});
db.get(`SELECT * FROM data WHERE key = '${req.query.data}'`, (err, row) => {
db.close((err) => {
if (err) {
console.error(err.message);
}
console.log("Close the database connection.");
});
res.json(row);
});
});
Second, though not related to your question, is that template strings are not safe from SQL injection attacks. So you really should not take direct user input from req.body or req.query or similar and concatenate it with your query, unless you're comfortable with a malicious user destroying your DB.
To avoid the injection problem, it's a good idea to both validate that the user input falls into an acceptable range of values but also use prepared statements to properly escape potentially malicious values.

Related

How do I get the information from the database before sending a message

I'm currently making a discord bot with discord.js v13. Right now I have a database where the guild.id and the standard prefix of a server are stored in. Now I want to rewrite a command which gets triggered by the prefix and the name of the command, like this '!somecommand'. Currently my prefix is defined in the file with a const variable, but I want the bot to check the database for the prefix the server has, and use this one instead. I'm checking the prefix in the database with this part of code:
pool.getConnection(function(err, connection) {
if (err) throw err;
let sql = `SELECT * FROM custom_prefix WHERE guild_id = '${message.guild.id}'`;
connection.query(sql, async function (err, result) {
if (err) throw err;
console.log(result[0].prefix)
connection.release();
});
});
The output is the current prefix of the server where the command was triggered, so far everything works fine.
But as I said I want the output of the code above to be the prefix with which the bot gets triggered.
I already tried to do it, but I'm always making a mistake.
Most of the time the bot is checking the database too slow and the result will be 'undefined'.
I dont know how I make the bot to wait for the result from the database, check if this result is really the prefix and then execute the command.
I am happy about any answer :-)
If you need any more information please let me know.
I'm guessing you did put the code that uses the result outside of the callback.
pool.getConnection(function(err, connection) {
if (err) throw err;
let sql = `SELECT * FROM custom_prefix WHERE guild_id = '${message.guild.id}'`;
connection.query(sql, async function (err, result) {
if (err) throw err;
console.log(result[0].prefix)
connection.release();
//
// Put your code that uses result[0].prefix here
//
});
});
//
// Do not put your code that uses result[0].prefix here
//

Proper error handling in node using try catch

Im new to javascript programming and i am required to make a web app. Node.js will be used as the js runtime environment. In order to minimize the amount of time needed for debugging as the app develops I would like to implement a robust error handling scheme. However, due to my limited background I am not sure if what I am implementing is best practise or if it is even adequate. So any feedback will be accepted.
The function is asynchronous and will use catch to detect if any errors occurred while operating. A try-catch statement will be used to catch any errors. This was done in order to allow for individual error identification from the functions. My aim is to propagate the errors up to the calling function that will handle it in the highest level catch statement (in my case where it is logged *this will change eventually). Any feedback?
create: async function(req, res) {
let data = JSON.parse(req.body.data);
let result;
let request_body;
let sub_networks_lora;
try {
request_body = sub_network_api_request_data(data, 1);
result = await lora_app_server.create_applications(request_body)
.catch(err => {
//Error updating application on lora app server
throw err;
});
await db_sub_networks.create_sub_network(result.data.id, data.sub_network_name, data.network_id)
.catch(err => {
throw err;
//Error creating sub network in database
});
sub_networks_lora = await get_sub_networks()
.catch(err => {
throw err;
//Error getting networks from lora app server
})
sub_networks_lora = JSON.stringify(sub_networks_lora);
res.status(200).send({
sub_networks_lora
});
} catch (err) {
console.log(err)
} finally {}
}

RethinkDB - Run query one after another

I am having trouble running multiple queries inside a single connection with RethinkDB. I have tried the r.do as seen in this question, however no success. I have also tried working with the conditional update queries. What I am looking to do is:
Open the connection.
Query to see if my field is there and if it is, perform some tasks.
Query to see if a counts field is there, subtract it by one.
What would be the best way to go about this? It seems I might be missing something?
r.connect(config.rethinkdb, function(err, conn) {
if (err) {
throw err;
}
else {
console.log('Connected.');
app.set('rethinkdb.conn', conn);
}
r.table('upcs').filter({AcceptedUPC:data}).run(conn, (err, cursor) => {
if (err) throw err;
console.log(data);
cursor.toArray((err,resu) => {
if (err) throw err;
//make a csv with some information
})
})
And in the same connection run
r.table('upcs').filter({AcceptedUPC:data}).filter(r.row.hasFields("UPCCount")).update({UPCCount: r.row("UPCCount").sub(1)}).run(conn, (err,cursor) => {
if (err) throw err;
});
Running this in NodeJS
I'm going to assume you are using this library for node.
You can that they actually allow you to do either callbacks or promises. I would recommend promises to avoid brackets of hell.
For promises you can use the bluebird library to make life easy.
You can do it by doing the following.
r.connect(config.rethinkdb).then(() => {
console.log("Connected");
app.set("rethinkdb.conn", conn);
return r.table('upcs').filter({AcceptedUPC:data}).run(conn);
}).then((cursor) => {
console.log(data); //maybe this should be cursor but I don't use rethinkDB
return cursor.toArray();
}).then((resu) => {
//make a csv with some information
}).catch((err) => {
throw err;
});

NodeJS, doesn't close mysql connection

I actually use this MYSQL Client and when I close a connection is actually never closes , so I can see in the status.
router.get('/test', function (req, res, next) {
var conn = mysql.createConnection(config);
conn.connect();
conn.query('select * from invoices ', function (err, result) {
if (err) {
throw err;
}
res.status(200).json({result: result});
conn.end();// || conn.destroy();
});
});
Move conn.end() out of the query callback - as described in node-mysql's documentation:
Every method you invoke on a connection is queued and executed in sequence.
Closing the connection is done using end() which makes sure all remaining queries are executed before sending a quit packet to the mysql server.
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
connection.end();
Also you can use pool.
Check this link.
Connections can be pooled to ease sharing a single connection, or
managing multiple connections.
When you are done with a connection, just call connection.release()
and the connection will return to the pool, ready to be used again by
someone else.
pool.end(function (err) {
// all connections in the pool have ended
});

Basic node/mongo/mongoose connection not working

I'm new to MEAN stack development. I've created a database in MongoDB called 'framework' and a collection called 'users' with some json in. I can see that's all there and happy using mongo commands through Mac terminal.
Now I'm writing some Mongoose in my application and to test everything is working, I just want to get a list of the collection names. I tried this:
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/framework");
mongoose.connection.db.collectionNames(function (err, names) {
if (err) console.log(err);
else console.log(names);
});
But when I run that file through the command line, it doesn't log anything at all. What am I doing wrong here?
Make it as a callback function after the connection is successfully established. Without it being inside a callback method, it may get executed before the connection to the database is successfully established due to its asynchronous nature.
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/framework");
mongoose.connection.on('connected', function () {
mongoose.connection.db.collectionNames(function (err, names) {
if (err) console.log(err);
else console.log(names);
});
})
mongoose.connection.db.collectionNames is deprecated. Use this code to get the list of all collections
const mongoose = require("mongoose")
mongoose.connect("mongodb://localhost:27017/framework");
mongoose.connection.on('open', () => {
console.log('Connected to mongodb server.');
mongoose.connection.db.listCollections().toArray(function (err, names) {
console.log(names);
});
})
If you are not pretty sure of what should be the URL string for your mongoose.connect method. No worries, go to your command prompt, type mongo.
This starts the application where you can see the connection details like
Then use the same URL with your db-name appended like
const mongoose = require('mongoose');
mongoose.connect("mongodb://127.0.0.1:27017/db-name").then(
()=> console.log('connected to db')
).catch(
(err)=> console.error(err)
);
Hope this helps !!

Categories

Resources