How to share connection pool between modules in node.js? - node.js

I have a little or no knowledge at how to properly implement postgres connection pool in node.js modules.
My question is : Is it problem when I am creating new Pool in every module where I need a connection to pg ?
Is there a way to create pool globally for a whole app ?
Thanks.

Define the pool in a file say pgpool.js
var pg = require('pg');
var pool;
var config = {
user: 'foo',
database: 'my_db',
password: 'secret',
port: 5432,
max: 10,
idleTimeoutMillis: 30000,
};
module.exports = {
getPool: function () {
if (pool) return pool; // if it is already there, grab it here
pool = new pg.Pool(config);
return pool;
};
Use it like this:
var db = require('./a/path/to/pgpool.js');
var pool = db.getPool();

I would suggest to not export the pool, but a function that provides a connection to it. Using promise-mysql
var mysql = require('promise-mysql');
var connectionPool = mysql.createPool({
host : "127.0.0.1",
user : '******',
password : '******',
database : '******',
port : '3306'
});
module.exports={
getConnection: function(){
return new Promise(function(resolve,reject){
connectionPool.getConnection().then(function(connection){
resolve(connection);
}).catch(function(error){
reject(error);
});
});
}
}
I have made a simple blog post about MySQL pool sharing, where you can read more

Related

sql.Connection is not a constructor [nodejs expressjs and SqlServer] ---

I am trying to write a backend API in node and express JS to connect to SQL Server[with windows authentication] and fetch data. The error message is --
const poolPromise = new sql.Connection(config)
TypeError: sql.Connection is not a constructor
The relevant config file code is dbConfig.js :
const sql = require('msnodesqlv8')
const config = {
database: 'ApiDemoDB',
server: '.\\SQLEXPRESS',
driver: 'msnodesqlv8',
options: {
trustedConnection: true
}
}
const poolPromise = new sql.Connection(config) <-------this line error
.connect()
.then(pool => {
console.log('Connected to MSSQL')
return pool
})
.catch(err => console.log('Database Connection Failed! Bad Config!: ', err))
module.exports = {
sql, poolPromise
}
What is the meaning of this error message? sql.Connection is not supposed to take any parameter[config]? I don't get it, what am I supposed to do differently here? What additional code changes do I have to make in order to get this working? Can you please help me solve this problem so that the API can connect to the mssql database? As you can see, as of now I have very little code. Barebones.
Thanking you in advance.
*********************************** EDIT ***********************************
I have changed the code around quite a bit.
My dbconfig.js file is now as:
const sql = require('mssql');
const msnodesqlv8=require('msnodesqlv8');
var dbconfig = {
server: 'localhost',
database: 'ApiDemoDB',
driver: 'msnodesqlv8',
options: {
enableArithAbort:true,
trustedConnection: true,
instancename:'SQLEXPRESS'
},
port:1433
}
module.exports=dbconfig;
And then a separate dbconnect.js file as:
var sql = require("mssql/msnodesqlv8")
var dbConfig = require("./dbConfig")
var dbConnect = new sql.connect(dbConfig,
function(err)
{
if(err){
console.log("Error while connecting to database: " + err)
}else{
console.log("connected to database: " + dbConfig.server)
}
}
)
module.exports = dbConnect
Now, the error that I have is ->
Error while connecting to database: ConnectionError: Failed to connect to localhost:1433 - Could not connect (sequence)
What does this even mean. It's pointing to the dbconfig file, but what changes to be written there, can you suggest me? Thanks

How can I use the same mongodb connection throughout the app?

I'm trying this approach, but I'm not sure if that creates a new connection every time.
getMongoClient.js
const { MongoClient } = require('mongodb');
const serverURL = process.env['mongoServerURL']
module.exports = async function (){
const mongoClient = await new MongoClient(serverURL);
await mongoClient.connect();
return mongoClient;
}
then in the app.js
const getMongoClient = require("./_helpers/getMongoClient.js")
module.exports = getMongoClient();
then in a database service.js
async function syncGuilds(client){
const mongoClient = await require("../app.js")
... some database operations
}
module.exports = syncGuilds
Node modules are singleton by themselves, you don't need to worry about them. When your modules is once evaluated, it won't be evaluated again. So you will always receive same instance of the module i.e it won't create multiple instance of mongo connection.
You can check this and this link for more details.
It won't create a new connection every time, If you want you can specify max connection pool size in options default value is 5. Check below link
https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#connection-pool-configuration
const mongodb = require("mongodb");
let client = new mongodb.MongoClient(
"url",
{
tls: true,
auth: { user: "myuser", password: "mypassword" },
useNewUrlParser: true,
useUnifiedTopology: true,
poolSize: 1,
maxPoolSize: 1,
}
);

Correct way to implement a single instance in a module

I am trying to initialize a DB connection in a module and pass to other modules.
My DB connection module (rdsconnection.js) is:
const { Pool } = require('pg');
let dbParams = require('./configparams').getDbParams();
let schema = (dbParams.db_schema === "" || dbParams.db_schema === undefined) ? "public." : dbParams.db_schema + ".";
// Connect to AWS RDS
let pool;
if(!pool)
{
console.log("PG pool not initialized. Initializing now.");
pool = new Pool({
user: dbParams.username,
host: dbParams.host,
database: dbParams.dbname,
password: dbParams.password,
port: dbParams.port
});
}
else
{
console.log("PG already initialized.");
}
module.exports = { pool, schema }
I want to do to
const { pool, schema } = require('../modules/rdsconnection');
in multiple modules and want to return only a single pool connection object.
I am assuming the if/else I am doing is wrong way to go about this.
What is the proper way to initialize an object only once in a module?
Does the code in the module gets run each time another module calls require()?
Thank you very much.
You're overcomplicating it. Node.js modules are only loaded once and then cached for reuse if they are requireed multiple times in a program. You can simplify it to this:
const { Pool } = require('pg');
const dbParams = require('./configparams').getDbParams();
const schema = `${dbParams.db_schema || 'public'}.`;
// Connect to AWS RDS
const pool = pool = new Pool({
user: dbParams.username,
host: dbParams.host,
database: dbParams.dbname,
password: dbParams.password,
port: dbParams.port
});
module.exports = { pool, schema };

How to connect openshift Phpmyadmin database using Nodejs Server?

How to connect "openshift phpmyadmin database" using nodejs server
Below is my code ... I am not getting result from the database ...
log :
Success{"fieldCount":0,"affectedRows":0,"insertId":0,"serverStatus":2,"warningCo
unt":0,"message":"","protocol41":true,"changedRows":0}
var connection = mysql.createConnection({
OPENSHIFT_NAMMAOORU_DB_HOST :'127.4.188.2',
OPENSHIFT_NAMMAOORU_DB_PORT :'3306',
OPENSHIFT_NAMMAOORU_DB_USERNAME:'adminfxxxxx',
OPENSHIFT_NAMMAOORU_DB_PASSWORD:'xxxxxxxxx',
OPENSHIFT_NAMMAOORU_DB_URL:'mysql://adminxxxx:xxxxxxx#127.4.188.2:3306',
//database:'nammaooru'
});
connection.connect(function(err,success){
if (err) {
throw err;
console.log("Error"+JSON.strinerr);
}
else
{
console.log("Success"+JSON.stringify(success));
}
});
app.get('/city',function(req,res){
try{
//var id = req.query.id;
/*var t=req.query.id;
console.log(t);
*/ /* var data = {
"error":1,
"Books":""
};*/
console.log(req.params.cityid);
var t=1;
connection.query("SELECT * from city",function(err, rows, fields){
console.log("success"+JSON.stringify(rows));
//console.log("success"+JSON.stringify(fields));
//console.log(JSON.stringify(rows));
res.send(JSON.stringify(err));
//console.log("success"+JSON.stringify(err));
});
}
catch(e)
{
console.log(e);
}
});
Local Rest url http://localhost:8000/city
{ code: "ER_NO_DB_ERROR", errno: 1046, sqlState: "3D000", index: 0 }
I don't think you are creating the mysql connection properly:
var connection = mysql.createConnection({
host: '127.4.188.2',
user: 'adminfxxxxx'',
password: 'xxxxxxxxx',
port: 3306
});
Try this just add database name as below
var connection = mysql.createConnection({
host :'127.4.188.2',
port :'3306', // if this doesn't work try removing port once
user:'adminfxxxxx',
password:'xxxxxxxxx',
database:'xxxxxxxxx', //specify database Name

How to export prototypes in node.js

In my db library file, I have:
exports.slave = ->
connection = mysql.createConnection
host: config.database.slave.host
user: config.database.slave.username
password: config.database.slave.password
database: config.database.slave.database
connection.connect()
return connection
which returns connection if I run db.slave().query("WHATEVER") and executes properly. How can I extend and export a prototype, so I can just use: db.slave.query("WAHTEVER") instead?
The standard node convention is to export a single object. This object can whatever you want
var config = {
database: ...
}
var mysql = require('mysql')
function setupSlave() {
var connection = mysql.createConnection
host: config.database.slave.host
user: config.database.slave.username
password: config.database.slave.password
database: config.database.slave.database
connection.connect()
return connection
}
var slave = setupSlave()
module.exports = slave
If you instead want to export slave() instead of slave you can do that as well
var config = {
database: ...
}
var mysql = require('mysql')
function setupSlave() {
var connection = mysql.createConnection
host: config.database.slave.host
user: config.database.slave.username
password: config.database.slave.password
database: config.database.slave.database
connection.connect()
return connection
}
var slave = setupSlave()
module.exports = slave()

Resources