Use database in child_process - javascript

I try to execute in another process some database operations, so I used child_process for that.
But I cannot update my database from this process: there is no connection.
app.js
...
mongoose.connect(mongodb://localhost/myDb);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database');
});
// When the connection is disconnected
db.on('disconnected', function () {
console.log('disconnected');
});
child_express.exec('node ' + __dirname + '/path/to/my/my-service.js', (err, stdout, stderr) => {
if(err) console.error(stderr);
else console.log(stdout);
});
my-service.js
MyModel = require('../models/my-model');
...
myModel.updateBook(book);
my-model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// console.log(mongoose.connection.readyState); => 0
var bookSchema = new Schema({..});
var Book = mongoose.model('Book', bookSchema);
exports.updateBook = function(book) {
Book.find({ bookId: book.bookId }, function (err, book) {
console.log(book);
});
};
How can I get the connection from child_process?

Related

Cannot retrieve all entries from MongoDB collection

i'm trying to retrieve all entires from mongo yet I keep on getting an error that I couldn't find any while having there are some entries.
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017';
const dbName = 'toy_db';
tryMongo();
function tryMongo() {
MongoClient.connect(url, (err, client) => {
if (err) return console.log('Cannot connect to DB');
console.log('Connected successfully to server');
const db = client.db(dbName);
const collection = db.collection('toy');
collection.find().toArray((err, docs) => {
if (err) return console.log('cannot find toys');
console.log('found these:');
console.log(docs);
});
client.close();
});
}
this is the error i'm getting :
Server listening on port 3030!
Connected successfully to server
cannot find toys
I have also added a picture of mongo
appreciating any kind of help!
You are closing mongo connection before you get response from server. Move client.close(); inside toArray callback.
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017';
const dbName = 'toy_db';
tryMongo();
function tryMongo() {
MongoClient.connect(url, (err, client) => {
if (err) return console.log(err);
console.log('Connected successfully to server');
const db = client.db(dbName);
const collection = db.collection('toy');
collection.find().toArray((err, docs) => {
if (err) {
console.log(err);
} else {
console.log('found these:');
console.log(docs);
}
client.close();
});
});
}

How do i update a object in mongoDB via nodeJS?

I'm attempting to make it so that when a player gets a highscore it searches there name, then it adds that highscore to there account. My issue is I don't know how to search for a name and update a tag using mongoose?
Here is my server code:
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
var PORT = 3332;
app.use("/", express.static(__dirname));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect("mongodb://localhost/endg", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
var db = mongoose.connection;
db.once("open", function (cb) {
console.log("connection established");
});
io.on("connection", function (socket) {
console.log("user connected");
socket.on("chooseName", function (newName) {
var data = {
nickname: newName,
highscore: 0,
};
db.collection("dat").findOne({ nickname: data.nickname }, function (
err,
doc
) {
if (err) throw err;
if (doc) {
io.emit("nnTaken", null);
} else {
db.collection("dat").insertOne(data, function (err, coll) {
if (err) throw err;
console.log("rec estab");
io.emit("newNickname", null);
});
}
});
});
socket.on("player", function (player) {
socket.on("highscore", function (hs) {
console.log(player + ": " + hs);
db.collection("dat").updateOne(
{ name: player },
{ $set: { highscore: hs } }
);
//This is where im trying to update but the above code does not work
});
});
});
http.listen(PORT, function () {
console.log("server is up and running using port " + PORT);
});
How would i do this? I try using the update inside the highscore socket, so that when a highscore is achieved it updates that field but nothing is changing.
Or if you prefer async function with es6
socket.on('highscore', async highscore => {
await db.collection('dat').findOneAndUpdate(
{ nickname: player },
{ $set: { highscore: hs } }
)
});
I'm using ES6 Javascript syntax. highscore => {} is the same as function (highscore)
Also I'm using async function. await means the program wait until the function is done
I actually figured it out. I'll post the answer in case anyone has this issue in the future.
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
var PORT = 3332;
app.use("/", express.static(__dirname));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect("mongodb://localhost/endg", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
var db = mongoose.connection;
db.once("open", function (cb) {
console.log("connection established");
});
io.on("connection", function (socket) {
console.log("user connected");
socket.on("chooseName", function (newName) {
var data = {
nickname: newName,
highscore: 0,
};
db.collection("dat").findOne({ nickname: data.nickname }, function (
err,
doc
) {
if (err) throw err;
if (doc) {
io.emit("nnTaken", null);
} else {
db.collection("dat").insertOne(data, function (err, coll) {
if (err) throw err;
console.log("rec estab");
io.emit("newNickname", null);
});
}
});
});
socket.on("player", function (player) {
socket.on("highscore", function (hs) {
console.log(player + ": " + hs);
db.collection("dat").findOne({ nickname: player }, function () {
db.collection("dat").updateOne(
{ nickname: player },
{ $set: { highscore: hs } }
);
});
});
});
});
http.listen(PORT, function () {
console.log("server is up and running using port " + PORT);
});
I went ahead and basically used findOne to find the players name, and then used updateOne with the $set to update the highscore value.
I'm guessing the issue was stemming from the fact that mongo wasn't able to tell which value i was trying to update.

get a callback from a seperate file in node js

I have two file in my node js app server.js and database.js
//server.js
var db = require('./database.js');
var express = require('express');
var app = express();
var server = app.listen(8081, '000.00.00.000',function(){
var host = server.address().address;
var port = server.address().port
console.log('App listening');
})
app.get('/',function(req,res){
res.end("Hello Jamian");
})
app.get('/insertuser',function(req,res){
console.log("insert user called")
var result = new db.insertUser();
console.log("result " + result)
});
and
//database.js
var mysql = require('mysql');
var con = mysql.createConnection({
host:"localhost",
user:"0000",
password:"0000",
database: "aaaa"
});
con.connect(function(err){
if(err) throw err;
console.log("DB Connected");
});
module.exports = {
insertUser: function () {
console.log("module exported");
var SQL_insert_user = "insert into users(username,useremail,usermobile,userpassword,activetoken) values('darren','darren#yahoo.in','980000000','password','ASKDO5615F')";
con.query(SQL_insert_user,function(err,result){
if(err) throw err;
console.log("data inserted");
return result;
});
},
bar: function () {
console.log("bar called")
}
};
I need a callback from the insertUser function in database.js so i can call a res.end("data inserted"). however it seems con.query is going async, hence I am getting a blank value when I try to log result in server.js from get/insertuser in server.js
data inserted
insert user called
module exported
result {}
data inserted
Use promises. Either native or from a library.
Here's how you could do it with a promise:
insertUser: function(){
return new Promise(function(reject, resolve){
var SQL_insert_user = "insert into users(username,useremail,usermobile,userpassword,activetoken) values('darren','darren#yahoo.in','980000000','password','ASKDO5615F')";
con.query(SQL_insert_user,function(err,result){
if(err) reject(err);
else resolve(result);
});
});
},
Then you can use it your other file like this:
insertUser()
.then(function(result){
// do something with the result
})
.catch(function(err){
// Oh no! there was an error!
});
in your server js do
app.get('/insertuser',function(req,res){
console.log("insert user called")
var result = new db.insertUser(function(result) {
console.log("result " + result)
});
});
and in your database do
module.exports = {
insertUser: function (cb) {
console.log("module exported");
var SQL_insert_user = "insert into users(username,useremail,usermobile,userpassword,activetoken) values('darren','darren#yahoo.in','980000000','password','ASKDO5615F')";
con.query(SQL_insert_user,function(err,result){
if(err) throw err;
console.log("data inserted");
cb(result);
});
},
bar: function () {
console.log("bar called")
}
};

Node.js Module class returns undefined

This is my database class which I want to exist only once because I want only one connection for the application and not multiple connections.
var mysql = require('mysql');
var fs = require("fs");
var eventEmitter = require("./events.js");
function Database() {
this.connection;
this.poolCluster;
var host;
var username;
var password;
var db;
var config;
var clusterConfig = {
removeNodeErrorCount: 5,
restoreNodeTimeout: 1000,
defaultSelector: 'ORDER'
};
var poolConfig = {
acquireTimeout: 10000,
waitForConnections: false,
connectionLimit: 10,
queueLimit: 0
};
this.connect = function() {
this.connection = mysql.createConnection({
host: config.mysqlHost,
user: config.mysqlUsername,
password: config.mysqlPassword,
database: config.mysqlDb
});
this.connection.connect(function(err) {
if(err) {
console.error("Connection couldn't established at " + config.mysqlHost + " (user: " + config.mysqlUsername + ")"
+ "\nError: " + err);
return;
}
console.log("Connected to mysql server at " + config.mysqlHost + " (user: " + config.mysqlUsername + ")");
this.poolCluster = mysql.createPoolCluster(clusterConfig);
this.poolCluster.add("APP", poolConfig);
this.poolCluster.add("ACCOUNTS", poolConfig);
this.poolCluster.add("GAME", poolConfig);
console.log("Created Connection Clusters\n- APP\n- ACCOUNTs \n- GAME");
eventEmitter.emit("MysqlConnectionReady");
});
};
this.getMainConnection = function() {
return this.connection;
};
this.getAppConnection = function() {
this.poolCluster.getConnection("APP", 'ORDER', function(err, connection) {
if(err) throw err;
return connection;
});
};
this.getAccountsConnection = function() {
this.poolCluster.getConnection("ACCOUNTS", 'ORDER', function(err, connection) {
if(err) throw err;
return connection;
});
};
this.getGameConnection = function() {
this.poolCluster.getConnection("GAME", 'ORDER', function(err, connection) {
if(err) throw err;
return connection;
});
};
fs.readFile(process.cwd() + "/config.json", 'utf8', function(err, data) {
if(err) throw err;
config = JSON.parse(data);
this.connect();
});
}
module.exports = Database:
In my code I set module.exports = Database;
When I want to use Database in another file its undefined. I want to use this in another file and I want to use only instance of that because I want only one connection for the app Im running.
But if I use require('./Database.js'j; and use the var it returns undefined
To use the pseudo-classical OOP approach, where you define a Class as a JS function (as shown in your snippet), you would instantiate an object with the new keyword.
Instead of module.exports = Database, try creating the instance and exporting that as the module, like this:
const db = new Database();
module.exports = db

What is wrong with my database file?

this is my database.js file:
const MongoClient = require('mongodb').MongoClient;
const db = function(){
return MongoClient.connect('mongodb://localhost:27017/users', (err, database) => {
if (err) return console.log(err);
return database;
});
}
module.exports = db;
I icluded it to my server.js like this:
var db = require('./database');
but when I want to use it like this
db().collection('orders')
I am getting a TypeError (Cannot read property 'collection' of undefined)
Edit: sorry, I made an issue during writing this question of course I used db().collection
The issue is with your export, and misunderstood behavior of node's callbacks.
const MongoClient = require('mongodb').MongoClient;
const db = function(){
return MongoClient.connect('mongodb://localhost:27017/users', (err, database) => {
// this is inside a callback, you cannot use the database object outside this scope
if (err) return console.log(err);
return database; // this database object is what you should be exporting
});
}
module.exports = db; // You are exporting the wrong variable
One way to fix this is (may not be the best) to export the database object that we receive in the callback. Example:
const MongoClient = require('mongodb').MongoClient;
let database = null;
MongoClient.connect('mongodb://localhost:27017/users', (err, db) => {
if (err) return console.log(err);
database = db;
});
module.exports = database;
And now you can use the db, but with a null check.
var db = require('./database');
if (db !== null) {
db.collection('orders').find({}, (err, docs) => {
if (err) return console.log(err);
console.log(docs);
});
}
But this may lead to connection being established again and again when you require the database.js file (I am not sure about this). A better approach would be:
const MongoClient = require('mongodb').MongoClient;
let database = null;
const connect = () => {
if (database !== null) return Promise.resolve(database);
return new Promise((resolve, reject) => {
MongoClient.connect('mongodb://localhost:27017/users', (err, db) => {
if (err) return reject(err);
database = db;
resolve(database);
});
});
};
module.exports = connect;
and then use it like:
var dbConnect = require('./database');
dbConnect().then((db) => {
db.collection('orders').find({}, (err, docs) => {
if (err) return console.log(err);
console.log(docs);
});
}).catch((err) => {
console.error(err);
});

Categories