Search code examples
javascriptnode.jsnode-sqlite3

NodeJs How to export a SQLite connection


I'm running an express app, in which I want to initialise/open a DB connection before I start listening on a port.

server.js:

const express = require('express');
const morgan = require('morgan');
const db = require('./database/dbUtils');

db.init();
const app = express();
...
app.listen(PORT, () => console.log(`Server running on port ${PORT}.`));

Then, my idea was that I can use that connection in my model to do CRUD operations. For instance, I have a User model that can create a user.

user.js:

const db = require('./database/dbUtils');

async function createUser(user) {
    await db.exec("INSERT INTO users ...");
}

How can I export the connection? I know that exporting is synchronous, so it's impossible to export the DB directly. How do I do that in a conventional way (promise and/or callback)?

dbUtils.js:

const sqlite = require('sqlite3');
const sql = require('sqlite');

async function init() {
    try {
        return await sql.open({
            filename: './database/database.db',
            driver: sqlite.Database 
        });    
    } catch (e) {
        console.error(e);
    }
}

module.exports = init();

Note, in this case, dbUtils.js won't work as it's exporting an async. Even if it worked, it's creating a new connection every time it's imported.


Solution

  • Note, in this case, dbUtils.js won't work as it's exporting an async. Even if it worked, it's creating a new connection every time it's imported.

    It shouldn't be.

    You're exporting the result of calling this async function, which is going to be a Promise. init() is only getting called once. While you do need to await this everywhere you use it (or use .then()), once a Promise is resolved, future .then or await will resolve immediately to the same value.

    In your other files....

    const dbPromise = require('./database/dbUtils');
    
    async function createUser(user) {
      const db = await dbPromise;
      await db.exec(...);
    }