I'm sorry, but I used a translator. I hope you understand.
I got curious while using mysql module. look at the code first.
db_promise.js
Create a pool.
const mysql = require('mysql2');
const config = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PW,
database: process.env.DB_NAME,
connectionLimit: 100,
queueLimit: 10000,
multipleStatements: true,
waitForConnections: true,
dateStrings: 'date'
}
const createPool = mysql.createPool(config, (err)=>{
console.error(err);
});
const pool = createPool.promise();
module.exports = pool;
run.js
Function A creates a connection, passes it to Function B after use, and continues to use it.
const pool = require('./db_promise.js');
const A = async ()=>{
let conn;
try {
conn = await pool.getConnection();
await conn.query('do stuff1..');
await B(conn);
return;
}catch(e){
console.error(e);
} finally {
conn.release();
}
}
const B = async (conn)=>{
try {
await conn.query('do stuff2..');
return;
}catch(e){
throw e;
}
}
creating connections for each function would be a waste. Can only one connection be reused when it is an associated function?
Related
I need to create a mysql connection in nodejs , but the credentials for the mysql comes from a third party credential manager service. Can somebody suggest me a way to achieve this?
database.js - i am using connection from this file in all other database operations
const mysql = require("mysql");
const {env} = require('./globals')
const connection = mysql.createConnection({
host: env.DATABASE.HOST,
user: env.DATABASE.USER,
password: env.DATABASE.PASSWORD,
database: env.DATABASE.NAME,
multipleStatements: true
});
connection.connect(function (err) {
if (err) {
console.log("Error in DB connection");
console.log("err", err);
} else console.log("Connected!");
});
module.exports = connection
globals.js
const {getSecret} = require('../src/service')
require("dotenv").config();
async function getCredentials() {
const result = await getSecret()
return JSON.parse(result?.SecretString || {})
}
const credentials = getCredentials() // not working, and i can't use await here
const env = {
DATABASE: {
HOST: credentials.ip_address,
PASSWORD: credentials.password,
NAME: credentials.dbname,
USER: credentials.username,
},
SKU: process.env.SKU
}
module.exports.env = env
Your 2 main options are:
Don't export connection but export an async function that returns a connection.
Write an init() function that sets up your database connection, and ensure it's one of the first things your application calls before anything else.
Well first, you need to fix up that globals.js file. Logic that depends on an async function must be async itself. You can just move everything into the async function like so:
const {getSecret} = require('../src/service')
require("dotenv").config();
async function getCredentials() {
const result = await getSecret()
const credentials = JSON.parse(result?.SecretString || {})
return {
DATABASE: {
HOST: credentials.ip_address,
PASSWORD: credentials.password,
NAME: credentials.dbname,
USER: credentials.username,
},
SKU: process.env.SKU
}
}
module.exports = { getCredentials }
And since even your database connection in database.js depends on this async function, it will have to be async as well:
const mysql = require("mysql");
const {getCredentials} = require('./globals')
const getConnection = getSecret().then(function (env) {
const connection = mysql.createConnection({
host: env.DATABASE.HOST,
user: env.DATABASE.USER,
password: env.DATABASE.PASSWORD,
database: env.DATABASE.NAME,
multipleStatements: true
});
connection.connect(function (err) {
if (err) {
console.log("Error in DB connection");
console.log("err", err);
} else console.log("Connected!");
});
return connection;
})
module.exports = getConnection
Having the following code
connection.js
import pkg from "pg";
const { Client } = pkg;
let connection = undefined;
export async function connect() {
const client = new Client({
user: "postgres",
host: "localhost",
database: "dbname",
password: "password",
port: "5432",
});
connection = await client.connect();
}
export async function query(text, values) {
try {
await connection.query(text, values);
} catch (error) {
console.error(error.message);
}
}
I intend that when calling the connect function a value is assigned to the connection variable that will then be used in the query function
This is how I call the connect method
index.js
import { connect } from "./src/connection.js";
import { handleStep1 } from "./src/step1.js";
async function init() {
await connect();
await handleStep1();
}
init();
And I intend to call the query function from another file as follows
step1.js
import { query } from "./connection.js";
export async function handleStep1() {
const results = await query("SELECT * FROM public.user", []);
console.log(results);
}
But here when calling the query function it gives me the following error message Cannot read property 'query' of undefined
What is the correct way to assign a value to a variable that will later be used in different script calls?
Thanks in advance
You can simply export a variable which is intialized and import it anywhere you want.
export async function connect() {
const client = new Client({
user: "postgres",
host: "localhost",
database: "dbname",
password: "password",
port: "5432",
});
connection = await client.connect();
}
export async function query(text, values) {
try {
await connection.query(text, values);
} catch (error) {
console.error(error.message);
}
}
// export let connection = connect();
// import it in other files. like import{ connection } from from "./connection.js";
//if you need to all connect only once. just update the line to
let connection = connect(); //remove the connection imports in other files.
I am trying to connect my application to the database using the connection pool method, its connecting fine, and data insertion is happening fine without any issues but other queries in the same file are slowing down.
I have tried with release() method also not working properly.
How can release the pool to the next query once it's executed the current query?
Below is my dbpool.js file code where I am writing a common generalized database connection,
var pg = require('pg');
var PGUSER = 'postgres';
var PGDATABASE = 'test_database';
var config = {
user: PGUSER, // name of the user account
host: 'localhost',
database: PGDATABASE, // name of the database
password: 'password#AWS',
port: 5432,
max: 10,
idleTimeoutMillis: 10000
};
const pool = new pg.Pool(config);
const DB = {
query: function(query, callback) {
pool.connect((err, client, done) => {
if(err){ return callback(err); }
client.query(query, (err, results) => {
// done();
client.release();
// if(err) { console.error("ERROR: ", err) }
if(err) { return callback(err); }
callback(null, results.rows);
})
});
}
};
module.exports = DB;
I tried with both the done() and client.release() method but no luck. If I use both then I am getting an error message client is already released.
Below is my socket.js file code:
var express = require('express');
const connection = require('./dbpool.js');
if(arData == '0022'){
const queryText = "INSERT INTO alert(alert_data) VALUES('"+arData+"')";
connection.query(queryText,(err, res) => {
if(err){
console.log(err.stack);
}
});
}
if(arData == '0011'){
const queryText = "INSERT INTO table2(alert_data) VALUES('"+arData+"')";
connection.query(queryText,(err, res) => {
if(err){
console.log(err.stack);
}
});
}
function ReverseCommunication(){
const select1 = "SELECT * FROM alert WHERE action = '0' ORDER BY alert_id ASC LIMIT 1";
connection.query(select1, (err, res) =>{
if(err) {
console.log("Error1");
res.json({"error":true});
}
else{
console.log("res==",res);
}
});
}
setInterval(function(){
ReverseCommunication();
}, 2000)
With pool you shouldn't need to close the connection. With pool it will reuse the connection pool for subsequent request so you don't have to connect to the DB each time.
(i'm not a PG expert here, sure other could expand on that way better then I )
What works for us is to set up the dbpool file you have like this
const {Pool,Client} = require('pg');
const pool = new Pool({
user: process.env.POSTGRES_USER,
host: process.env.POSTGRES_URL,
database: process.env.POSTGRES_DATABASE,
password: process.env.POSTGRES_PASSWORD,
port: process.env.POSTGRES_PORT,
keepAlive: true,
connectionTimeoutMillis: 10000, // 10 seconds
max: 10
});
pool.connect()
.then(() => console.log('pg connected'))
.catch(err => console.error(err))
module.exports = pool
Then use the pool.query like you have now with pool.connect
Also, just a side note what lib are you using for PG? Noticed your queries are dynamic, you may want to adjust those to prevent possible SQL-injection.
Im trying to connect mongodb in node.js and take the link to client to the outer variable.
I need to create a module that would return a result of .find() method. How can i do this?
const MongoClient = require('mongodb').MongoClient
let client
mongoClient = new MongoClient('mongodb://localhost:27017/', {useUnifiedTopology: true, useNewUrlParser: true})
mongoClient.connect((err, db) => {
if (err) {
return console.log(err)
}
client = db
})
const database = client.db('db')
const collection = database.collection('collection')
client.close()
And the error
const database = client.db('db')
^
TypeError: Cannot read property 'db' of undefined
As the comment suggests, you can use async/await to wait for the connection to be established, and do the error handling with a try/catch statement:
try {
const client = await mongoClient.connect()
const database = client.db('db')
const collection = database.collection('collection')
} catch(e) {
console.log(e)
}
Don't forget to use it in an async function.
Update
An async function example, you may want to return the collection:
const getData = async () => {
try {
mongoClient = new MongoClient('mongodb://localhost:27017/', {useUnifiedTopology: true, useNewUrlParser: true})
const client = await mongoClient.connect()
const database = client.db('db')
const collection = database.collection('collection')
client.close()
return collection
} catch(e) {
console.log(e)
}
}
after uri you must define db name
mongoClient = new MongoClient('mongodb://localhost:27017/', {useUnifiedTopology: true, useNewUrlParser: true})
like this
mongoClient = new MongoClient('mongodb://localhost:27017/shop', {useUnifiedTopology: true, useNewUrlParser: true})
I have the following code written. I am not sure if it works but basically am trying to create a function that inserts a new todo with a description unless that description is bad todo. Obviously this is just for testing but I want to call this function I created in my express app.
BEGIN;
CREATE OR REPLACE FUNCTION perntodo.createTodo(
description perntodo.todoDescription%Type)
RETURNS VARCHAR AS
$$
DECLARE
BEGIN
IF description == 'bad todo' THEN
RAISE EXCEPTION 'Cannot post this todo!';
ELSE
INSERT INTO TODO VALUES(description);
END IF;
END;
COMMIT;
My controller looks like this...
router.post('/', async (req, res) => {
try {
const { description } = req.body;
// const newTodo = await pool.query(
// 'INSERT INTO todo (description) VALUES($1) RETURNING *',
// [description]
// );
const newTodo = await pool.func('perntodo.createTodo', [description]);
res.json(newTodo.rows[0]);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error...');
}
});
The commented out code works. But the pool.func says it's not a function. What am I doing wrong.
This is how I connected to my database
const Pool = require('pg').Pool;
const user = './user';
const DBPASSWORD = './pass';
const pool = new Pool({
user: user,
password: DBPASSWORD,
host: 'localhost',
port: 5432,
database: 'perntodo',
});
module.exports = pool;