How I can access multiple DB using ExpressJS? - javascript

I have a server with 3 databases with identical tables.
DB1, DB2 and DB3.
When I work with a database I use:
app.js
var cnxDB= require('./routes/cnxDB');
app.post('/userSave', cnxDB.userSave);
cnxDB.js:
var sql = require('mssql');
var qs = require('querystring');
var colors = require('colors');
var config = {user: 'user',password: 'pass',server: '127.0.0.1',database: nameDB',
options: {
encrypt: false
}
};
sql.connect(config, function(err) {
//Connection
});
exports.userSave = function(req, res) {
//response
};
When initializing the application immediately makes the connection to the database.
I need to know how you can do to choose the database.
app.post('/selectBD', function(req, res){
var body = req.body; // accede a la informaciĆ³n enviada por el socket
console.log(body);
if(body.cnx == 1)
{
var cnx = require('./routes/bdUno');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 2)
{
var cnx = require('./routes/bdDos');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 3)
{
var cnx = require('./routes/bdTres');
app.get('/yuri', cnx.findall);
}
res.status(200).json("Ok");
});
Thank you.

In cnxDB.js set up 3 connections:
var connections = {
<dbname>: null,
<dbname>: null,
<dbname>: null
}
go to mssql and look at "Quick Example". It creates a connection and saves it in a variable. You'd want to do that 3 times for each db and save them in connections under the corresponding db name.
Then the functions you export from cnxDB.js should have a way to know which db you want them to use. By the looks of it you want to have some indication of what db needs to be used in the body of that request. You can use that to pick the db.

Related

Storing current session in variable to use in MySQL Query

I want to fetch some values from the current user Session and use them in MySQL query. I am working on Node.js and using redis to manage sessions.
File Name:User.js
var sessionUtils = require('./../services/sessionUtils');
var Constants = require('./../constants');
var config = require('./../config');
var databaseUtils = require('./../services/databaseUtils');
var redisUtils = require('./../services/redisUtils');
var util = require('util');
showUserPage: function* (next){
var queryString = "";
var query = "";
/*Do something to store session in variable*/
queryString = "select * from table where state='%s' and city='%s';";
query = util.format(queryString,/*state variable here*/, /*city variable
here*/);
var user = yield databaseUtils.executeQuery(query);
console.log(query);
yield this.render('user', {
user:user
});
}
File Name: sessionUtils.js
var redisUtils = require('./redisUtils');
var uuid = require('uuid');
var thunkify = require('thunkify');
saveUserInSession: function(user, cookies) {
var sessionId = uuid.v1(); // uuid: uniqe id every time
var sessionObj = {user: user};
redisUtils.setItemWithExpiry(sessionId, JSON.stringify(sessionObj), 86400); // 86400: for 1 day
cookies.set("SESSION_ID", sessionId);
},
getCurrentUser: thunkify(function(sessionId, callback) {
var currentUser;
if(sessionId) {
redisUtils.getItemWithCallback(sessionId, function(err, res) {
if(err) {
logger.logError(err);
}
if(res == null) {
callback(currentUser);
} else {
callback(err, JSON.parse(res).user);
}
});
} else {
callback(currentUser);
}
})
I am using line below in Login.js file to save user in session .
sessionUtils.saveUserInSession(results[0], this.cookies);
Help me out with this.
I have solved this problem by placing following code in place of /* Do something to store session in variable */
var sessionId = this.cookies.get("SESSION_ID");
var currentUser = yield sessionUtils.getCurrentUser(sessionId);
and used it in MySQL query as given below:
queryString = "select * from table where state='%s' and city='%s';";
query = util.format(queryString,currentUser.state, currentUser.city);
Hope, it helps others too.

Cannot read property 'insert' of undefined when trying to put data in MongoDB

I'm getting this error: "Cannot read property 'insert' of undefined" when trying to insert data into a database. The error shows on:
db.coordinates.insert({ "x" : "data.x", "y" : "data.y"})
Database name - "node5"
Collection name - "coordinates"
// Including libraries
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var static = require('node-static'); // for serving files
//db connection
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/node5');
var url = 'mongodb://localhost:27017/node5';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
db.close();
});
// This will make all the files in the current folder
// accessible from the web
var fileServer = new static.Server('./');
// This is the port for our web server.
// you will need to go to http://localhost:8080 to see it
app.listen(8080);
// If the URL of the socket server is opened in a browser
function handler(request, response) {
request.addListener('end', function () {
fileServer.serve(request, response);
}).resume();
}
// Delete this row if you want to see debug messages
io.set('log level', 1);
// Listen for incoming connections from clients
io.sockets.on('connection', function (socket) {
// Listen for mouse move events
socket.on('post', function (data) {
console.log('posted');
console.log(data);
socket.broadcast.emit('posted', data); // Broadcasts event to everyone except originating client
db.coordinates.insert({ "x" : "data.x", "y" : "data.y"})
});
});
When writing an answer, please note that I'm new to node.js and I might not understand if you tell the answer in a complex way:)
If you are using monk for your project, then you can drop the mongodb module, since it's functionality is being wrapped up by monk. From Monk's documentation, you should be doing something like:
const monk = require('monk');
const db = monk('localhost:27017/node5')
const coordinates = db.get('coordinates');
Now that you have a reference to your coordinates collection, you can use it later in your code:
coordinates.insert({ x: data.x, y: data.y });
I hope this is easy enough to understand. If it is still confusing, then please comment below and I'll elaborate further :)

nodejs sends empty response before data retrieved from mongodb

When I use jQuery ajax to retrieve data from nodejs (with express4), nodejs sends empty response back before data loaded from mongodb.
This is the message from nodejs console:
GET /query?uid=1 - - ms - -
And this is the error message from Chrome console:
GET http://192.168.1.105:3000/query?uid=1 net::ERR_EMPTY_RESPONSE
I can confirm that data are correctly loaded from mongodb because data can be printed on nodejs console after nodejs sent the empty response. And this is exactly the problem. Why nodejs sends reponse to client before data have been prepared?
I know nodejs is asynchronous and I pay much attention to this great feature, but I still have this problem.
This is my client code:
$.getJSON('/query', {uid:1}, function(response) { console.log('finished!'); });
And this is my server code:
var express = require('express');
var mongodb = require('mongodb');
var GeoJSON = require('geojson');
var strftime = require('strftime');
var router = express.Router();
var MongoClient = mongodb.MongoClient;
router.get('/query', function(req, res, next) {
var url = "mongodb://localhost/example_db";
var collection_name = "example_collection";
var poi = req.query.poi ? req.query.poi.split("||") : null;
var time = req.query.time;
var uid = req.query.uid;
var condition = {};
if (poi) condition.poiname = {$in: poi};
if (time) condition.checkin_time = {$gte:new Date(time.start_time), $lte:new Date(time.end_time)};
if (uid) condition.uid = parseInt(uid);
MongoClient.connect(url, function(err, db) {
if (err) console.log('connection error');
var collection = db.collection(collection_name);
collection.find(condition).sort({checkin_time:1}).toArray(function(err, result) {
if (err) {
console.log(err);
return res.send('error!');
}
if (!result) return res.send('no data');
//This line prints the result after empty response has been sent.
console.log(result);
var data = {};
data['geojson'] = GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']});
res.json(data);
db.close();
});
});
My data are a little bit large, 12G stored in mongodb. So it usually takes about 3 minutes or more to complete the query. When I use findOne to retrieve only a single document, this is no problem.
Does the data size cause the problem?
Try GeoJSON.parse with callback
var data = {};
GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']}, function (geojson) {
data['geojson'] = geojson;
res.json(data);
db.close();
});

How to execute the function return the value to called function across node js files

I have 3 node js files :
mysqlconnection.js to store the database connection properties:
var mysql = require('mysql');
var cjson = require('cjson');
var yaml_config = require('node-yaml-config');
// project files
var config = yaml_config.load(__dirname + '/billingv2.yaml');
exports.execute = function(callback){
var connection = mysql.createConnection(
{
host : config.host,
user : config.user,
password : config.password,
database : config.database,
}
);
connection.connect();
return callback(null,connection);
}
subscriptionRestService.js to handle the REST api calls:
var express = require('express');
var app = express();
app.use(express.bodyParser());
var fs = require('fs');
// Project files
var mysql = require('./mysqlRestService.js');
// Get Resource Subscription data by Resourceuri
app.post('/pricingdetails', function(req, res) {
var workload = req.body;
if(workload.elements && workload.elements.length > 0)
{
var arr = [];
for(var index in workload.elements)
{
arr[index] = workload.elements[index].uri;
}
var resourceIdentifiers = arr.join(',');
}
console.log(resourceIdentifiers);
mysql.getPricingDetail(function(resourceIdentifiers,callback){
});
});
mysqlRestService.js to handle mysql queries/stored procedures:
// packages
var mysql = require('mysql');
var cjson = require('cjson');
var fs = require('fs');
var yaml_config = require('node-yaml-config');
// project files
var dbconnection = require('./mysqlconnection');
exports.getPricingDetail = function (resourceIdentifiers,callback){
console.log('entered into mysql function');
console.log(resourceIdentifiers);
var pricingDetail = {};
dbconnection.execute(function(err,response){
if(err){
throw err;
}
else
{
var selectqueryString = "call SP_ExposePricingDetailforUI('" + resourceIdentifiers + "')";
response.query(selectqueryString, function(err,pricingDetail){
if(err) {
throw err;
}
else
{
console.log(pricingDetail);
pricingDetail = pricingDetail;
}
});
}
});
//console.log('printing pricing details');
//console.log(pricingDetail);
};
problems faced
Unable to send the variable resourceIdentifiers from subscriptionRestService to mysqlRestService.js
Unable to return the pricingdetail from mysqlRestService.js to calling function in subscriptionRestService.
Any guidance greatly appreciated.
Unable to send the variable resourceIdentifiers from subscriptionRestService to mysqlRestService.js
Well, you didn't send it. It currently is a parameter of your callback function in the invocation, not an argument for the parameter of getPricingDetails. Use
mysql.getPricingDetail(resourceIdentifiers, function callback(result){
// use result here
});
Unable to return the pricingdetail from mysqlRestService.js to calling function in subscriptionRestService.
I've got no idea what pricingDetail = pricingDetail; was supposed to do. You have to call (invoke) back the callback here! Use
callback(pricingDetail);

How can I set req.session from this scope?

I'm writing a Node.js application using Express and a PostgreSQL database using node-postgres. I want to look up the current user's username and real name based on their email, and set them in req.session. However, if I set them where I am in the code below, they are undefined when we leave that block (i.e. the first console.log statements print the correct info, the second set prints undefined. How can I solve this?
var client = new pg.Client(app.conString);
var realname = "";
var username = "";
client.connect();
var query = client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email]
);
query.on('row', function(row) {
req.session.realname = row.realname;
req.session.username = row.username;
console.log(req.session.realname);
console.log(req.session.username);
});
console.log(req.session.realname);
console.log(req.session.username);
query.on('end', function() {
client.end();
});
The second pair of console.log will execute before the query-results are available (in the row event handler).
If your code is going to be used in an Express route, you would use something like this:
app.get('/', function(req, res) {
var client = new pg.Client(app.conString);
var realname = "";
var username = "";
client.connect();
var query = client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email]
);
query.on('row', function(row) {
req.session.realname = row.realname;
req.session.username = row.username;
});
query.on('end', function() {
client.end();
res.send(...); // <-- end the request by sending back a response
});
});
An alternative for using the EventEmitter interface for node-postgres would be to just pass a callback to query (which looks better with Express IMHO):
client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email],
function(err, results) {
if (err)
// handle error
else
if (results.length)
{
req.session.realname = results[0].realname;
req.session.username = results[0].username;
}
res.send(...); // done
});

Categories

Resources