I am currently working on implementing Knex transactions into my project using the relevant files provided below. However, I am encountering the following error:
KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call? at Client_SQLite3.acquireConnection (/c/Users/Raj/Projects/testserver/node_modules/knex/lib/client.js:347:26)
auth/methods.js
const bcrypt = require("bcrypt");
const knex = require("../db/connection");
const passport = require("./passportLocalStrategy");
async function createUser(req, res) {
console.log("we're in createUser");
try {
const errors = validateData(req);
if (errors.length > 0) throw errors;
const salt = bcrypt.genSaltSync();
const hash = bcrypt.hashSync(req.body.password, salt);
console.log("trying to insert user with knex");
const trxProvider = knex.transactionProvider();
const trx = await trxProvider();
return trx("users").insert({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: hash,
});
} catch (errors) {
console.log("error when inserting user with knex");
// return 400 error
return errors;
}
}
function validateData(req) {
console.log("validating data");
let errors = [];
if (!req.body.name) errors.push({ text: "Please enter name" });
if (!req.body.email) errors.push({ text: "Please enter email" });
if (!req.body.username) errors.push({ text: "Please enter username"})
if (req.body.password != req.body.password_confirm)
errors.push({ text: "Passwords do not match" });
if (req.body.password < 4)
errors.push({ text: "Password must be at least 4 characters" });
return errors;
}
async function login(req, res, next) {
console.log("logging in");
await passport.authenticate("local", function (err, user, info) {
if (err) {
console.log("error 1")
return next(err);
}
if (!user) {
console.log("error 2")
return res.redirect("/login");
}
req.login(user, function (err) {
if (err) {
console.log("error 3")
return next(err);
}
const user_data = {
email: req.user.email,
username: req.user.username,
name: req.user.name,
user_since: req.user.created_at,
};
console.log("returning user_data")
return user_data;
});
})(req, res, next);
}
module.exports = {
createUser,
selectByUsername,
login,
};
auth/passportLocalStrategy.js
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const init = require("./passportSessionConfig");
const knex = require("../db/connection");
const authUtils = require("./utils");
// const options = {};
init();
console.log("passport localstrategy loaded");
passport.use(
new LocalStrategy(
{
usernameField: "email",
passwordField: "password",
},
function (username, password, done) {
console.log("we're in passportLocalStrategy");
console.log(username);
// check to see if the username exists
knex("users")
.where({ email: username })
.orWhere({ username })
.first()
.then((results) => {
console.log("line 24 ", results);
console.log("within passportstrategy");
if (!results) {
console.log("no results");
return done(null, false);
}
if (!authUtils.comparePass(password, results.password)) {
console.log("PASSWORD DOESNT MATCH!");
return done(null, false);
} else {
console.log("PASSWORD MATCHES!!");
return done(null, results);
}
})
.catch((err) => {
console.log("caught an error!!!");
return done(err);
});
}
)
);
module.exports = passport;
routes/users.js
const express = require("express");
const router = express.Router();
const knex = require("../db/connection");
const passport = require("../auth/passportLocalStrategy");
const authUtils = require("../auth/utils");
const authMethods = require("../auth/methods");
router.post("/api/register", async (req, res, next) => {
try {
const ids = await authMethods.createUser(req, res);
console.log("got ids: ")
console.log(ids)
const currentUser = authMethods.login(req, res, next);
return res.status(200).send({ currentUser });
} catch (errors) {
// return 500 error
console.log("500 error")
console.log(errors)
return res.status(500).send({ errors });
}
});
router.post("/api/login", (req, res, next) => {
return authMethods.login(req, res, next);
});
router.post("/api/logout", (req, res) => {
console.log("inside logout");
req.logout();
req.flash("success_msg", "Logout successful");
return res.send({});
});
module.exports = router;
This is the code snippet from Knex's docs that I'm trying to incorporate into my project:
// Does not start a transaction yet
const trxProvider = knex.transactionProvider();
const books = [
{title: 'Canterbury Tales'},
{title: 'Moby Dick'},
{title: 'Hamlet'}
];
// Starts a transaction
const trx = await trxProvider();
const ids = await trx('catalogues')
.insert({name: 'Old Books'}, 'id')
books.forEach((book) => book.catalogue_id = ids[0]);
await trx('books').insert(books);
// Reuses same transaction
const sameTrx = await trxProvider();
const ids2 = await sameTrx('catalogues')
.insert({name: 'New Books'}, 'id')
books.forEach((book) => book.catalogue_id = ids2[0]);
await sameTrx('books').insert(books);
Can you help me identify the issue with my code?