Error in connecting database (mongo and nodejs) - mongodb

I want build a class for wrapping database connection. This is my code ('db.js' file):
var mongodb = require('mongodb');
var Class = function() {
this.db = null;
var server = new mongodb.Server('127.0.0.1', 27017, {auto_reconnect: true});
db = new mongodb.Db('myDB', server);
db.open(function(error, db) {
if (error) {
console.log('Error ' + error);
} else {
console.log('Connected to db.');
this.db = db;
}
});
};
module.exports = Class;
Class.prototype = {
getCollection: function(coll_name) {
this.db.collection(coll_name, function(error, c){ // <--- see error below
return c;
});
}
}
exports.oid = mongodb.ObjectID;
Then, my test code ('test.js' file):
var DB = require('./db');
var myDB = new DB();
myDB.getCollection('myCollection'); // <--- error: Cannot call method 'collection' of null

You are missing "this" in front of "db". eg:
this.db = new mongodb.Db('myDB', server);
And the line next to it.

Related

ES6 promise will not work always with mongodb replication set

I did follow How to use MongoDB with promises in Node.js?. The answer 4 by(https://stackoverflow.com/users/5371505/pirateapp), works well with regular mongodb server. But it will not work always with a mongoDB replication set.
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
// the url talking to replicaSet does not work, while the url with regular mongoDB sever seems working for me.
// const url = 'mongodb://alexlai:alex1765#arch16GMongo01.yushei.me:27017,arch16GMongo02.yushei.me:27017,arch16GMongo03:27017/YuShei?replicaSet=odroid00&connectTimeoutMS=300000';
url = 'mongodb://172.16.1.108/YuShei';
let db = {
open : open,
}
function open(){
return new Promise((resolve, reject)=>{
MongoClient.connect(url, (err, db) => {
if (err) {
reject(err);
} else {
resolve(db);
}
});
});
}
function close(db){
if(db){
db.close();
}
}
// module.exports = db;
// const db = require('./mongoDBServer.js');
const assert = require('assert');
const collectionName= 'yuTsaiLpr20161021'; // a collection contains 500 docs.
// this will hold the final array taht will be sent to browser
// a global variable will be declared with upper camel
let Array = [];
// this will hold database object for latter use
let Database = '';
// global query string and projection
let Query = {};
let Projection = {};
let Collection ={};
let checkoutCarPromise = new Promise((resolve, reject)=>{
Database = null;
db.open() // no ';' semi-column this is a promise, when successful open will be reolved and return with db object, or reject
.then((db)=>{
Database = db; // save it globally
return db.collection(collectionName);
})
.then((collection)=>{
if(collection == 'undefined') reject('collection not found!!');
Collection = collection; //seave it globally
return(collection);
})
.then((collection)=>{
return collection.find(); // return a cursor
})
.then((cursor)=>{
return cursor.toArray();
})
.then((array)=>{
console.log('array[499]: ', array[499]);
Array.push(array[499]);
})
.then(()=>{ // reread to find this car
return Collection.find({plateText:{$regex: /8920/}});
})
.then((cursor)=>{
return cursor.toArray();
})
.then((array)=>{
Array.push(array);
resolve(Array);
})
})
.catch((err)=>{
return(err);
console.error('the checkoutCarPromiserror is: ', err);
})
Promise.all([checkoutCarPromise]).then(results => {
console.log('checkoutCarPromise last resolve value: ', results[0]);
console.log('Array: ', Array);
Database.close();
})
// this will get you more infos about unhandled process
process.on("unhandledRejection", (reason) => {
console.log(reason)
})

nightwatch custom command callback

I'm trying to create a custom command in nightwatch that runs a query on a Postgres database and returns the result. The query runs just fine and outputs the result to the console but then the execution of the test stops. I don't understand how callbacks work. How can I fix this custom command?
exports.command = function(sql, callback) {
var self = this;
var pg = require('pg');
var conString = self.globals.testinfo.connectionString;
var db = new pg.Client(conString);
db.connect(function(err) {
if(err) {
console.error('could not connect', err);
}
else {
db.query(sql, function(err, result) {
if(err) {
console.log('error running query', err);
}
else {
console.log(result.rows.length);
db.end();
}
});
}
}),
function(result) {
if (typeof callback === 'function') {
callback.call(self, result);
}
}
return this;
};
I had to wrap the database connection in a perform command to get this working. I'm not sure if this is the best way to handle the callback, but it works. Here's the updated version of the custom command:
exports.command = function(sql,callback) {
var self = this;
var pg = require('pg');
var cs = self.globals.testinfo.connectionString;
self.perform(function(self,done) {
pg.connect(cs,function(err,db,done) {
if(err) {
return console.error(err);
}
db.query(sql, function(err,result) {
done();
if(err) {
return console.error(err);
}
console.log(result.rows.length);
callback(result.rows[0]);
});
});
pg.end();
done();
});
};
Here's how I call the custom command in the test:
browser.myCustomCommand('select * from table limit 1;', function(row) {
browser.assert.deepEqual(row.column,'some value');
});
Can you try this:
exports.command = function(sql, callback) {
var self = this;
var pg = require('pg');
var conString = self.globals.testinfo.connectionString;
var db = new pg.Client(conString);
var cb= function(result) {
if (typeof callback === 'function') {
callback.call(self, result);
}
};
db.connect(function(err) {
if(err) {
console.error('could not connect', err);
cb(false);
}
else {
db.query(sql, function(err, result) {
if(err) {
console.log('error running query', err);
cb(false);
}
else {
console.log(result.rows.length);
db.end();
cb(true);
}
});
}
}),
return this;
};
And in your test :
'test' : function(browser){
browser.yourCommandName(sql,function(result){
console.log(result); //if connect is good result would be true and false if fail to connect.
});
}
Ps: the result in callback can be as an object(contain rows or anything you want), instead of boolean only in this example.
And Nightwatch is used for end-to-end testing, it is not aimed for Database testing,i think you should find another framework to test database connection.

Nodejs mongoclient collection export

This is connection.js
var MongoClient = require('mongodb').MongoClient;
var db_singleton = null;
var getConnection= function getConnection(callback) {
if (db_singleton) {
callback(null,db_singleton);
} else {
var connURL = "mongodb://localhost:27017/testdb";
MongoClient.connect(connURL,function(err,db){
if(err)
console.log("Error creating new connection "+err);
else
{
db_singleton=db;
console.log("created new connection");
}
callback(err,db_singleton);
});
}
};
module.exports = getConnection;
And this is product.js
var getConnection = require('../../connection.js');
var products = null;
getConnection(function(err,db) {
var collection = db.collection("products");
collection.find().toArray(function(err, productsDB) {
products = productsDB;
})
});
console.log(products);
module.export = products;
console.log(products) is always null.
But it should be object.I would like to cache variable when server starts.

How avoid "Can't set headers after they are sent."

I use mongodb and in mongodb I put my username and password.
The code is:
var mongodb = require('mongodb');
var http = require('http');
var fs=require('fs');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
app.post('/prova', function(req, res) {
// res.send('You sent the name "' + req.body.username + '".');
var MongoClient = mongodb.MongoClient;
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/utente';
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);
var collection = db.collection('login');
// var prova1=({name:"documento1",url:"sadsad",tag:"dc1"});
// do some work here with the database.
var cursor = collection.find();
cursor.each(function (err, doc) {
if (err) {
console.log(err);
} else {
// console.log('Fetched:', doc);
var username=0;
var password=0;
for(valore in doc){
if(valore!="_id"){
if(valore=="username"){
if(doc[valore]==req.body.username){
username=1;
}
}
if(valore=="password"){
if(doc[valore]==req.body.password){
password=1;
}
}
}
}
if(username==1 && password==1){
console.log("entra");
// res.end();
}else{
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\paginaRifiuto.html', function (err, html) {
if (err) {
}
res.writeHeader(200, {"Content-Type": "text/html"});
res.write(html);
res.end(html);
});
}
}
});
//Close connection
}
});
});
http.createServer(function(request, response) {
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\home.html', function (err, html) {
if (err) {
}
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
});
}).listen(8000);
I call first http://localhost:8000 and I put in a text field the wrong value of username and password and after I click login I see my "login fail page" but I obtain this error:
Connection established to mongodb://localhost:27017/utente
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.writeHead (_http_server.js:195:21)
at ServerResponse.writeHeader (_http_server.js:233:18)
at C:\Users\Eventi\Desktop\Node.js\Progetti\ProveNodeJS\NodeJSProve\HelloWord.js:67:23
at fs.js:334:14
at FSReqWrap.oncomplete (fs.js:95:15)

Check how many rows retrieved in PostgreSQL (node.js)

I would like to know how can you check the row count of the query in PostgreSQL in node.js
I have this code for the meantime.
var client = new pg.Client(conString);
client.connect();
var query = client.query("SELECT * FROM users");
query.on('row', function(row) {
console.log(row);
});
var client = new pg.Client(conString);
client.connect();
client.query("SELECT * FROM users", function(err, result) {
console.log("Row count: %d",result.rows.length); // n
});
Another options is to use the rowCount property! Like this:
var pg = require('pg');
var pgClient = new pg.Client();
pgClient.connect();
var pgQuery = pgClient.query("SELECT * FROM information_schema.tables;");
pgQuery.on('error', function(err) {
pgClient.end();
console.error(err);
});
pgQuery.on('end', function(result) {
pgClient.end();
console.log(result.rowCount);
});
or like this:
var pg = require('pg');
var pgClient = new pg.Client();
pgClient.connect();
var pgQuery = pgClient.query("SELECT * FROM information_schema.tables;", function(err, result) {
pgClient.end();
if (err) return console.error(err);
console.log(result.rowCount);
});