I have a syntax problem in a module, I fail to do the SQL query.
I initialize the module database in file.js, it responds with console.log 'Connected to the database', then sends the data to the module in Database.newData(data), when it enters in runQuery nothing happens, no errors or result, nothing!
I look in runQuery if this query was ok and if this, I think what happens is that there is an error in my logic of node, the idea is to connect to the database and use runQuery to run any query that you pass.
file.js
var DB = require('./modules/database');
var Database = new DB();
Database.newData(data);
database.js
var mysql = require('mysql'),
queries = require('./queries'),
connection;
var DB = function(){
var db_config = {
host: 'localhost',
user: 'diegoug',
password: 'qwertyuiop',
database: 'test'
};
connection = mysql.createConnection(db_config);
connection.connect(function(err) {
if(err) {
console.log('error when connecting to database:', err);
}
console.log('Connected to the database');
});
}
DB.prototype.runQuery = function(Query,Data,cb){
// Here not pass nothing
connection.query(
Query,
Data,
function(err, results){
debugger;
if (err)throw err;
cb(results);
}
);
// look here if the query was well written and if it is, what happens is that it's simply not running anything in the connection
}
DB.prototype.newData = function(data){
var Query = queries.SQLNEWDATA,
data = [data];
var res = this.runQuery(Query,data);
console.log(res);
}
module.exports = DB;
Related
I want to develop a task in node js which fetch data from table in sql server and insert into table in mysql. This task need to run continuously after certain time period (say after each 5 seconds). Please guide me to achieve this.
JS code
var sql = require('mssql');
var mysql = require("mysql");
var config = {
user: 'user',
password: '*****',
server: 'url',
database: 'DB',
stream: true //work with large amount of rows
}
var connection1 = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'test'
});
connection1.connect();
var connection = new sql.Connection(config, function(err) {
if(err)
console.log(err);
var request = new sql.Request(connection);
//request.stream = true; // You can set streaming differently for each request
request.query('select TOP 100000 * FROM ShipmentAuditLog with (nolock)'); // or request.execute(procedure);
console.time('Time-Taken');
request.on('recordset', function(recordset) {
// Emitted once for each recordset in a query
//console.log(recordset);
});
request.on('row', function(row) {
// Emitted for each row in a recordset
//console.log(row);
syncing(row);
});
request.on('error', function(err) {
console.log(err);
});
request.on('done', function(returnValue) {
// Always emitted as the last one
console.log('Completed');
console.timeEnd('Time-Taken');
connection.close();
});
});
var syncing = function(row){
connection1.query('INSERT INTO shipmentauditlog SET ?',row,function(err,res){
if(err)
console.log(err);
});
}
I would like to connect to mongodb first, then run everything else in my application.
To do it I have to write something like:
MongoClient.connect("mongodb://localhost/test", function(err, connection) {
if (err) { console.error(err); }
db = connection;
var app = express();
// Include API V1
require("./apiv1.js")(app, db);
app.listen(3000, function(err) {
if (err) { console.error(err); } else { console.log("Started on *:3000"); }
});
});
This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.
I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.
How can I do?
You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.
The best way to do it is to adopt some wrapper around node-mongodb-native driver.
Take a look at the following modules.
mongojs
var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');
mongoskin
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});
monk
var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')
Of course, internally all of them are establishing MongoDB connection asynchronously.
Using the async library, you can aleve some of these issues.
For example in my server startup I do the following :
async.series([
function(callback){
// Initialize the mongodb connection and callback on completion in init.
db.init(function(){
callback();
});
},
function(callback){
// Listen on requests etc.
webServer.init(function(){
callback();
});
},
function(callback){
// Set up anything else that I need
callback();
}
]);
If you are using Node 6 and up versions, you can do something like this:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();
//your code
async function getdb() {
db = await MongoClient.connect(url);
}
Bring the mongodb library.
Declare the url constant .
Declare the variable db as null.
Call the getdb function.
Create the getdb function which has firt the async word
Assign to the db variable the result of the connection with the key word await.
You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.
const MongoClient = require('mongodb').MongoClient;
const thunky = require('thunky');
var connect = thunky(function(cb){
let url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, client){
console.log('connecting')
cb(err, client);
})
})
connect( (err, client) => {
console.log('connection 1')
})
connect( (err, client) => {
console.log('connection 2')
})
connect( (err, client) => {
console.log('connection 3')
console.log('closing')
client.close();
})
*Note: I am using latest 3.x mongodb driver
I am working on a nodejs / mongodb app using 'mongodb' module. The app is launched with
node main.js
In main.js, I connect to the db and keep the connection in the 'db' global variable. 'db' is then used in inner methods of 'server'. I want to avoid having 'db' as a global variable but did not found the correct way to do.
My current main.js:
var server = require('./lib/server');
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
var mongoClient = new MongoClient(new Server(HOST, PORT));
db = null;
// Database connection
mongoClient.open(function(err, mongoClient) {
if(!err){
// Database selection
db = mongoClient.db(DB);
// Launch web server
server.start(); // usage of 'db' in this part
} else {
console.log(err.message);
process.exit(1);
}
});
Any idea of a cleaner way ?
UPDATE
I finally created a module in connection.js:
var config = require('../config/config');
var url = 'mongodb://' + config.db.host + ':' + config.db.port + '/' + config.db.name;
var MongoClient = require('mongodb').MongoClient;
var db = null;
module.exports = function(cb){
if(db){
cb(db);
return;
}
MongoClient.connect(url, function(err, conn) {
if(err){
console.log(err.message);
throw new Error(err);
} else {
db = conn;
cb(db);
}
});
}
Each time I need to get the connection I call:
var connection = require('./connection');
connection(function(db){
// doing some stuff with the db
});
This is working very well.
Any potential failure with this approach ?
I typically include a project utilities file that contains a number of these things, just to make it easy. It functions as a pseudo global, but without many of the usual problems globals entail.
For example,
projectUtils.js
module.exports = {
initialize: function(next){
// initialization actions, there can be many of these
this.initializeDB(next);
},
initializeDb: function(next){
mongoClient.open(function(err, mongoClient) {
if(err) return next(err);
module.exports.db = mongoClient.db(DB);
next();
});
}
}
app.js
var projectUtils = require('projectUtils');
// (snip)
projectUtils.initialize(function(err) {
if(err) throw err; // bad DB initialization
// After this point and inside any of your routes,
// projectUtils.db is available for use.
app.listen(port);
}
By using an asynchronous initialize() function, you can be sure that all database connections, file I/O, etc., are done before starting up the server.
You can create a wrapper something like a provider and put it in provider.js, for instance.
Provider = function (db_name, host, port, username, password) {
var that = this;
var conn = generate_url(db_name, host, port, username, password); // you need to implement your version of generate_url()
MongoClient.connect(conn, function (err, db) {
if (err) {
throw err;
}
that.db = db;
});
};
//add the data access functions
Provider.prototype.getCollection = function (collectionName, callback) {
this.db.collection(collectionName, collectionOptions, callback);
};
exports.Provider = Provider;
This is how you use the provider:
var db = new Provider(db_name, host, port, username, password);
db.getCollection('collection name', callback);
I am trying to figure out the best way to pass a mysql connection (using node-mysql) between my routes for express.js. I am dynamically adding each route (using a for each file loop in routes), meaning I can't just pass in the connection to routes that need it. I either need to pass it to every route or none at all. I didn't like the idea of passing it to ones that dont need it so I created a dbConnection.js that the routes can individually import if they need. The problem is that I dont think I am doing it correctly. As of now, my dbConnection.js contains:
var mysql = require('mysql');
var db = null;
module.exports = function () {
if(!db) {
db = mysql.createConnection({
socketPath: '/tmp/mysql.sock',
user: '*********',
password: '*********',
database: '**********'
});
}
return db;
};
And I am importing it into each route using:
var db = require('../dbConnection.js');
var connection = new db();
But I would like to do it like this:
var connection = require('../dbConnection.js');
When I try it like this, however, I get an error saying connection has no method 'query' when I try to make a query.
I find it more reliable to use node-mysql's pool object. Here's how I set mine up. I use environment variable for database information. Keeps it out of the repo.
database.js
var mysql = require('mysql');
var pool = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASS,
database: process.env.MYSQL_DB,
connectionLimit: 10,
supportBigNumbers: true
});
// Get records from a city
exports.getRecords = function(city, callback) {
var sql = "SELECT name FROM users WHERE city=?";
// get a connection from the pool
pool.getConnection(function(err, connection) {
if(err) { console.log(err); callback(true); return; }
// make the query
connection.query(sql, [city], function(err, results) {
connection.release();
if(err) { console.log(err); callback(true); return; }
callback(false, results);
});
});
};
Route
var db = require('../database');
exports.GET = function(req, res) {
db.getRecords("San Francisco", function(err, results) {
if(err) { res.send(500,"Server Error"); return;
// Respond with results as JSON
res.send(results);
});
};
your solution will work if use db() instead of new db(), which returns an object and not the db connection
var db = require('../dbConnection.js');
//var connection = new db();
var connection = db();
I am writing nodeunit tests for operations around a mongodb. When I execute my test with nodeunit (nodeunit testname.js), the test runs through and goes green but the nodeunit command line doesn't return (I need to hit ctrl-c).
What am I doing wrong? Do I need to close my db connection or the server or is my test wrong?
Here is a cutdown sample test.
process.env.NODE_ENV = 'test';
var testCase = require('/usr/local/share/npm/lib/node_modules/nodeunit').testCase;
exports.groupOne = testCase({
tearDown: function groupOneTearDown(cb) {
var mongo = require('mongodb'), DBServer = mongo.Server, Db = mongo.Db;
var dbServer = new DBServer('localhost', 27017, {auto_reconnect: true});
var db = new Db('myDB', dbServer, {safe:false});
db.collection('myCollection', function(err, collectionitems) {
collectionitems.remove({Id:'test'}); //cleanup any test objects
});
cb();
},
aTest: function(Assert){
Assert.strictEqual(true,true,'all is well');
Assert.done();
}
});
Michael
Try putting your cb() within the remove() callback after you close you connection:
var db = new Db('myDB', dbServer, {safe:false});
db.collection('myCollection', function(err, collectionitems) {
collectionitems.remove({Id:'test'}, function(err, num) {
db.close();
cb();
});
});
You need to invoke cb function after the closure of db (during the tearDown):
tearDown: function(cb) {
// ...
// connection code
// ...
db.collection('myCollection', function(err, collectionitems) {
// upon cleanup of all test objects
db.close(cb);
});
}
This works for me.