How can I load an extension on sqlite3 in nodejs? - node.js

This my connection code :
`
var sqlite3 = require('sqlite3').verbose()
const DBSOURCE = "db_path";
let db = new sqlite3.Database(DBSOURCE, (err) => {
if (err) {
console.error(err.message)
throw err
}else{
console.log('Connected to the SQLite database.');
}
});
module.exports = db`
I found something here, but I dont know its the correct way to do or to make it work :
https://github.com/mapbox/node-sqlite3/wiki/Extensions#databaseloadextensionpath-callback
tried this :
` let params = [];
db.all(`select load_extension('./config/math.dll')`, params, (err, rows) => {
console.log(err);
if (err) {
res.status(400).json({ StatusCode: 400, error: err.message });
return;
}
console.log(rows)
})`
and got error : Error: SQLITE_ERROR: not authorized
I couldn't find any sources for loading extension in node.js .

Using SELECT load_extension(...) is disabled by default for security reasons. However, you can load an extension like this:
const db = new sqlite3.Database('db.sqlite3');
db.loadExtension('./lib/uuid.dll');
db.all('SELECT uuid()', (error, rows) => {
console.log(rows);
});
db.close();
Notice the file name uuid.dll is not accidental. In my case, the uuid extension contains entry-point function called sqlite3_uuid_init, therefore the file must be called uuid.<extension> to make it work out of box. You can read more in SQLite documentation.

Related

Firebase Storage file download stops working after a while

I have a simple trigger set on file upload to Firebase. It reads uploaded file, process it and saves results to database. It works for a while, after that it crashes and stops working. Usually uploading function helps. Does anybody have an idea what might be the reason? Am I getting out of memory or ... ?
Here is the code :
const {Storage} = require('#google-cloud/storage');
const path = require('path');
const storage = new Storage();
exports.processLogs = functions
.region('europe-west1')
.storage
.object()
.onFinalize(async (object) => {
const filename = path.basename(object.name);
const bucket = storage.bucket(object.bucket);
try {
await bucket.file(filename).download(async (err, contents) => {
if (err) {
console.log('error', err);
return null
}
//Proces file and store into db
// (...)
bucket.file(filename).delete();
});
} catch(e){
console.log('error',e)
}
});
Error I am getting is :
Anonymous caller does not have storage.objects.get access to project-name.appspot.com/CrTwBuyNR2-log-2020-1-16-12-18.csv.'
thanks
As you are using Firebase, I recommend initialising the bucket from firebase-admin instead of #google-cloud/storage directly. This will sort out permissions so that security rules are skipped.
In your code you have also incorrectly mixed the callback and async/await APIs. Because this code is running in a Cloud Function, I recommend exclusively using Promises and async/await.
The code below is a rewrite with the following changes:
Code has been split into logical blocks
No callback API usage (see File#download)
Each block will log and throw errors separately for easier debugging
One-line log messages (i.e. no stack trace)
Leaves full error logging to Cloud Functions (makes finding erroneous runs easier)
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp();
exports.processLogs = functions.region('europe-west1').storage.object()
.onFinalize(async (object) => {
const bucketRef = admin.storage().bucket(object.bucket);
const fileRef = bucketRef.file(object.name);
console.log('Processing "' + object.id + '"...');
// 1) DOWNLOAD
let [contents] = await fileRef.download()
.catch((err) => {
console.log('DOWNLOAD FAILED: ', (err.code ? err.code + ': ' : '') + err.message);
throw err;
});
// 2) PARSE
let dataToUpload = {};
try {
// Transform file contents
dataToUpload = JSON.parse(contents);
} catch (err) {
console.log('PARSE FAILED: ', (err.code ? err.code + ': ' : '') + err.message);
throw err;
}
// 3) DATABASE SET
const dbRef = admin.database().ref('path/to/data');
await dbRef.set(dataToUpload)
.catch((err) => {
console.log('DATABASE SET FAILED: ', (err.code ? err.code + ': ' : '') + err.message);
throw err;
});
// 4) CLEANUP
await fileRef.delete()
.catch((err) => {
console.log('CLEANUP FAILED: ', (err.code ? err.code + ': ' : '') + err.message);
throw err;
});
// 5) LOG SUCCESS
console.log('SUCCEEDED');
});
The log messages above can also be bundled into a helper function if desired:
function logAndRethrowError(err, name) {
console.log((name || 'ERROR') + ': ', ((err.code ? err.code + ': ' : '') + err.message) || err);
throw err;
}
// Usage:
let [contents] = await fileRef.download()
.catch(err => logAndRethrowError(err, 'DOWNLOAD FAILED'));
try {
// ...
} catch (err) { logAndRethrowError(err, 'PARSE FAILED') }
This looks like a problem with Security Rules not being set properly? Please try this document or video.
For starters try this:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
And if it proves successful set Storage Rules properly.

Path issue with node.js and SQLLite

i have the following code (shortened it a bit)
dbInterface.js
const sqlConnection = require('sqlite3').verbose()
const data = require('./data.js')
//open database --> uses create/readwrite per default
let db = new sqlConnection.Database('./db/test_db.db', (err) => {
if (err) {
console.error('Error connecting to database')
}
console.log('Connected to the chinook database.')
})
exports.dbFunctions = {
userPresent: userPresent,
createTable: createTable,
tablePresent: tablePresent,
dropTable: dropTable,
dropAll: dropTable,
addUser: addUser,
deleteUser: deleteUser,
showTableContent: showTableContent,
addHistory: addHistory,
clearHistory: clearHistory,
removeLastHistoryEntry: removeLastHistoryEntry,
getHistory: getHistory
}
function userPresent (id) {
// noinspection SqlResolve
const statement = 'SELECT * FROM user WHERE pk_user_id == ' + id
return new Promise((resolve, reject) => {
db.all(statement, (err, row) => {
if (err) {
console.log('reject')
reject(false)
return
}
console.log('resolve')
resolve(true)
})
})
}
When I access the exported functions on the same folder level everything works fine.
As soon as I call the functions from another level like /tests/db_tests.js
I can work with for example userPresent but the database cannot establish a connection unless I change it to:
let db = new sqlConnection.Database('../db/test_db.db', (err) => {
if (err) {
console.error('Error connecting to database')
}
console.log('Connected to the chinook database.')
})
See I changed the path location from ./db/test_db.db to ../db/test_db.db
Since my app access the dbInterface from many different locations I feel very stuck to solve this issue.
I also tried it with an index.js that is on the same level lile the dbInterface.js and contained only this
exports.dbInterface = require('./dbInterface')
But this also didn't work.
Can anyone help out please?
try absolute path
const path = require('path');
let dbPath = path.join(process.cwd(), 'db', 'test_db.db');

sqlite3 create database with callback using Node

I've searched on how to create a sqlite3 database with a callback in Node.js and have not been able to find any links. Can someone point me towards documentation or provide a 2-3 line code sample to achieve the following:
Create a sqlite3 database and catch an error if the creation fails for any reason.
Here is what I've tried:
let dbCreate = new sqlite3.Database("./user1.db", sqlite3.OPEN_CREATE, function(err){
if(!err){
logger.infoLog("Successfully created DB file: " + dbFileForUser + " for user: " + username );
} else {
logger.infoLog("Failed to create DB file: " + dbFileForUser + ". Error: " + err );
}
});
dbHandler[username] = dbCreate;
When I execute this, I get the following error:
"Failed to create DB file: ./database/user1.db. Error: Error: SQLITE_MISUSE: bad parameter or other API misuse"
This call without callback works just fine.
var customDB = new sqlite3.Database("./custom.db", sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
But in this, I will not know if I run into any errors while creating the Database.
Try this:
let userDB = new sqlite3.Database("./user1.db",
sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
(err) => {
// do your thing
});
Example.
#Irvin is correct, we can have a look at http://www.sqlitetutorial.net/sqlite-nodejs/connect/ and
check it says if you skip the 2nd parameter, it takes default value as sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE
and in this case if database does not exist new database will be created with connection.
sqlite3.OPEN_READWRITE: It is to open database connection and perform read and write operation.
sqlite3.OPEN_CREATE : It is to create database (if it does not exist) and open connection.
So here is the first way where you have to skip the 2nd parameter and close the problem without an extra effort.
const sqlite3 = require("sqlite3").verbose();
let db = new sqlite3.Database('./user1.db', (err) => {
if (err) {
console.error(err.message);
} else {
console.log('Connected to the chinook database.|');
}
});
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection.');
});
And this is the 2nd way to connect with database (already answered by #Irvin).
const sqlite3 = require("sqlite3").verbose();
let db = new sqlite3.Database('./user1.db', sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE
, (err) => {
if (err) {
console.error(err.message);
} else {
console.log('Connected to the chinook database.');
}
});
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection.');
});

Serverless - AWS Lamda with MongoDB Atlas Queries Not Running

I've created an AWS account and want to use MongoDB Atlas with AWS Lambda.
The only dependency I've downloaded is mongodb locally.
npm install mongodb
Driver based connection string given from mongoDB Atlas for Nodejs is
var uri = "mongodb+srv://kay:myRealPassword#cluster0.mongodb.net/test";
MongoClient.connect(uri, function(err, client) {
const collection = client.db("test").collection("devices");
// perform actions on the collection object
client.close();
});
I think the connection is successful, because err parameter is NULL.
But I cannot figure out how to create collection, how to find results, how to insert documents.
I've tried this code
module.exports.hello = (event, context, callback) => {
var MongoClient = require('mongodb').MongoClient;
var uri = "mongodb+srv://kay:myRealPassword#cluster0.mongodb.net/test";
MongoClient.connect(uri, function(err, client) {
const collection = client.db("test").collection("devices");
collection.insert( { "msg" : "My First Document" } );
var results = client.db("test").collection("devices").find();
console.log(results);
client.close();
callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
});
};
but it returns (in Windows console) a huge Object in JSON format, its like a configuration data (not a query result)
enter image description here
I'm executing this code locally by
sls invoke local --function hello
The general idea is to check if there is an error in the connection, the insert, and so on. Take at look at this error checking:
if (error) return 1;
There are more sophisticated methods, but for your case this should do the work.
This is a example of how it show look your script:
MongoClient.connect(uri, (error, client) => {
if (error) return 1; // Checking the connection
console.log('Connection Successful');
var db = client.db('mydb'); // Your DB
let newDocument = { "msg" : "My First Document" }; // Your document
db.collection('mycollection').insert(newDocument, (error, results) => { // Your collection
if (error) return 1; // Checking the insert
console.log('Insert Successful');
})
db.collection('mycollection')
.find({})
.toArray((error, accounts) => {
if (error) return 1; // Checking the find
console.log('Find Successful');
console.log(accounts);
return 0;
})
})
And you should have an output like this:
Connection Successful
Insert Successful
Find Successful
[ { _id: 5a857dd2c940040d85cbe5f2, msg: 'My First Document' } ]
If your output is not like this, well the missing log would point the place where you have your error.

MongoError : selector must be a valid JavaScript object

I am using mongodb driver for nodejs.
I am getting below error while updating a record.
{"name":"MongoError","message":"selector must be a valid JavaScript
object","driver":true}
Here is my script :
MongoClient.connect(url, function (err, db) {
if (err)
{
console.log('Unable to connect to the mongoDB server. Error:', err);
return;
}
var collName = "bank";
var SelectParas = {"name":"ABC"};
var UpdateValues = {"name":"PQR"};
db.collection(collName).update(collName,SelectParas,{$set:UpdateValues},function (err,numUpdated){
if(err)
{
console.log('err');
console.log(err);
return;
}
if(numUpdated)
{
console.log('Updated Successfully %d document(s).', numUpdated);
}
db.close();
});
});
I can write the below line in mongo console & it works.
db.bank.update({"name":"ABC"},{$set:{"name":"PQR"}})
You are passing collecion name i.e. a string as find query of the update. Need not pass collecton name there.
db.collection(collName).update(collName,SelectParas,{$set:UpdateValues},function (err,numUpdated)
// collName need not pass in the update function.
Need to use
db.collection(collName).update(SelectParas,{$set:UpdateValues},function (err,numUpdated) instead.

Resources