How exactly does eval work with nodejs? - node.js

Let's say I do:
eval(
db_config = {
host: 'localhost',
user: 'root',
database: 'forum',
password: 'test'
}
);
var gamefunctions = require('gamefunctions.js');
I can use db_config anywhere inside gamefunctions.js without having to pass it through a parameter. That's pretty neat. But, is this bad practice?
Reason I ask this is because if I do:
var db_config = {
host: 'localhost',
user: 'root',
database: 'forum',
password: 'test'
}
var gamefunctions = require('gamefunctions.js');
db_config becomes undefined anytime I use it in gamefunctions.js. And I would have to pass it through a parameter on each different function which just seems like evaling it first would save time and code, any downside to this?
Does eval basically just define the variables in a global scope for you, so they can be used in any file in nodejs?

You're doing 2 things wrong and there's much more elegant solution to this.
To explain what you're doing wrong, first is the use of globals. Second is that you're storing sensitive information in your code - your database password! And besides, it won't be very portable. Suppose you want to run it on another machine that has some other database credentials you'll end up changing your code unnecessarily.
You need to store it as environment variables. And if you end up hosting it some environments automatically have those set for you so you could use them in your app. For example openshift would have an $OPENSHIFT_MONGODB_DB_HOST that it tells you to use in your app to connect to its database.
And you need to create a separate file to store your db_config which you can require from other files.
So you might create a db_config.js which would look like this
var config = {};
config.host = process.env.HOST || 'localhost';
config.user = process.env.USER || 'root';
config.password = process.env.password;
module.exports = config;
Then you can safely just pass it the sensitive information like password from console
$ password=pass
$ node index.js
And as for having that information in your gamefunctions.js all you gotta do is require it
var db_config = require('./db_config');

Related

How/where does any-db-sqlite3 save the database to?

I have the follow code in a node.js script:
var anyDB = require('any-db-sqlite3');
var dbURL = 'sqlite3:///tmp/test.db';
// var dbURL = 'sqlite3://test.db'; // this doesn't work either
var conn = anyDB.createConnection(dbURL);
and if I understand correctly is should create and write data to the file '/tmp/test.db' but the file does not seem to get saved. The script runs and writes data to the database. If I use the mysql adapter is works fine. I have tried creating the file first with:
sqlite3 /tmp/test.db
but that does not seem to help.
So it turns out there is a bug in any-db-sqlite3 where the connection string url is not getting parsed and defaults to :memory:. The work around if to pass an object instead of the url string like:
var dbURL = {
adapter: 'sqlite3',
host: '',
port: '',
database: 'test2.db',
user: '',
password: ''
};

my .env variables wont return for database login in node.js

Having a problem with .env variables in node.js, am using dotenv to handle the variables.
straight forward
require('dotenv').load()
and then checked console log to see if I can access then variables like so
console.log("database Name: "+process.env.DB_NAME);
console.log("database Username: "+process.env.DB_USER);
etc and all return fine.
the part of the code that calls the db is the following-
var Sequelize = require('sequelize');
module.exports = new Sequelize('dbname, 'username', 'password', {
host: 'hostname',
dialect: 'mssql',
dialectOptions: {
instanceName: 'namehere'
}
});
I replace the dbname with process.env.DB_NAME and all is fine, nothing falls over but the moment I try and use DB_USER in there then it fails to connect and shows user as ' ' in the log.
module.exports = new Sequelize(process.env.DB_NAME, process.env.USER_DB, 'password', { etc
the .env file itself is very straight forward and nothing out of the ordinary. structured as
NAME="value"
NAME2="value2"
etc. I though maybe once a value has been console logged it wont be available and turned off the console logs, but no luck. I also tried changing the name of the value encase that was reserved. please advise.
nevermind I was being silly. I presumed it only needed to be required once but not the case.

Where do I put database connection information in a Node.js app?

Node.js is my first backend language and I am at the point where I am asking myself "where do I put the database connection information?".
There is a lot of good information regarding this issue. Unfortunately for me all the examples are in PHP. I get the ideas but I am not confident enough to replicate it in Node.js.
In PHP you would put the information in a config file outside the web root, and include it when you need database data.
How would you do this in Node.js? using the Express.js framework.
So far I have this:
var express = require('express'), app = express();
var mysql = require('mysql');
app.get('/', function(req,res) {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'store'
});
var query = connection.query('SELECT * from customers where email = "deelo42#gmail.com"');
query.on('error', function(err) {
throw err;
});
query.on('fields', function(fields) {
console.log('this is fields');
});
query.on('result', function(row) {
var first = row.first_name;
var last = row.last_name;
res.render('index.jade', {
title: "My first name is " + first,
category: "My last name is " + last
});
});
});
app.listen(80, function() {
console.log('we are logged in');
});
As you can see I have a basic express application with 1 GET route. This route sets off the function to go to the database and pull out information based on an email address.
At the top of the GET route is the database connection information. Where do I put that? How do I call it? How do I keep it out of web root, and include it like PHP ? Can you please show me in a working example. Thanks!
I use the Express Middleware concept for same and that gives me nice flexibility to manage files.
I am writing a detailed answer, which includes how i am use the config params in app.js to connect to DB.
So my app structure looks something this:
How i connect to DB? (I am using MongoDB, mongoose is ORM, npm install mongoose)
var config = require('./config/config');
var mongoose = require("mongoose");
var connect = function(){
var options = {
server: {
socketOptions:{
keepAlive : 1
}
}
};
mongoose.connect(config.db,options);
};
connect();
under the config folder i also have 'env' folder, which stores the environment related configurations in separate files such as development.js, test.js, production.js
Now as the name suggests, development.js stores the configuration params related to my development environment and same applies to the case of test and production. Now if you wish you can have some more configuration setting such as 'staging' etc.
project-name/config/config.js
var path = require("path");
var extend = require("util")._extend;
var development = require("./env/development");
var test = require("./env/test");
var production = require("./env/production");
var defaults = {
root: path.normalize(__dirname + '/..')
};
module.exports = {
development: extend(development,defaults),
test: extend(test,defaults),
production: extend(production,defaults)
}[process.env.NODE_ENV || "development"]
project-name/config/env/test.js
module.exports = {
db: 'mongodb://localhost/mongoExpress_test'
};
Now you can make it even more descriptive by breaking the URL's into, username, password, port, database, hostname.
For For more details have a look at my repo, where you can find this implementation, in fact now in all of my projects i use the same configuration.
If you are more interested then have a look at Mean.js and Mean.io, they have some better ways to manage all such things. If you are beginner i would recommend to keep it simple and get things going, once you are comfortable, you can perform magic on your own. Cheers
I recommend the 12-factor app style http://12factor.net which keeps all of this in env vars. You never should have this kind of information hard-coded or in the app source-code / repo, so you can reuse it in different environments or even share it publicly without breaking security.
However, since there are lots of environment vars, I tend to keep them together in a single env.js like the previous responder wrote - although it is not in the source code repo - and then source it with https://www.npmjs.org/package/dotenv
An alternative is to do it manually and keep it in, e.g. ./env/dev.json and just require() the file.
Any of these works, the important point is to keep all configuration information separate from code.
I agree with the commenter, put it in a config file. There is no ultimate way, but nconf is also one of my favourites.
The important best practise is that you keep the config separate if you have a semi-public project, so your config file will not overwrite other developers.
config-sample.json (has to be renamed and is tracked with for example git)
config.json (not tracked / ignored by git)

Node Express Session Count

I have an application where I need to limit the number of active connections, and the most logical way of doing this to me, would be to simply count the number of active sessions.
I have searched for "node express session count" but did not find anything useful.
Is it possible to get the number of open sessions in node express ?
The alternative would be to save the IP address of each connected client, but the problem with this method is that the ip address would need to be manually removed from the datastore.
I guess if I use redis as the data store, I could use expire to achieve something similar.
set ip.192.168.42.1 true
expire ip.192.168.42.1 60
ttl ip.192.168.42.1
etc etc
Or is there a better way ?
EDIT
I have tried the suggestion of using MemoryStore but I can't seem to figure out how to use it ??
var express = require("express");
var MemoryStore = express.session.MemoryStore;
MemoryStore.prototype.length = function(fn) {
fn(null, Object.keys(this.sessions).length);
};
MemoryStore.length(function(len) {
console.log('sessions:'+len);
});
Use the Store.length(fn) method. In the default Connect memory storage, it's written like this:
MemoryStore.prototype.length = function(fn) {
fn(null, Object.keys(this.sessions).length);
};
So you would call it like this:
store.length(function(len) {
// we have len number of sessions
});
I am well aware of how old this post is but I thought I would share my way, as this comes up as the top result as I was trying to figure it out.
This what I did and it seems to be working.
So if you are using MySQLStore & Express Session you can approach it like this,
Add activeUsers to your options(app/index.js):
var options = {
host: process.env.DB_HOST,
port: 3306,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
activeUsers: 0
};
On your login.js add:
req.sessionStore.options.userCount += 1
And on your logout:
req.sessionStore.options.userCount += 1
Now I am not sure if on session timeout if this will return back to 0 or not, but I would assume that it does. And then just create a app.local that refers to the userSession count

Express js Where do the settings go?

In the express docs, there is a section called settings:
http://expressjs.com/api.html#app-settings
But I can't figure out where exactly the should go (to some function? as a dictionary in the use middleware? or somewhere else?)
P.S. How would I go about figure theses things out - do I need to look at source?
There are many ways to manage configuration, but here's a blog post I wrote about it:
http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/
The basic premise is you have a file for each environment (ie config.development.js, config.production.js) and one for everything else called config.global.js the development and production files would simply overwrite whatever you set in the global based on the needs of that environment.
Here’s the basic config/index.js file, this will load the config.test.js file assuming your NODE_ENV=test (we will default to ‘development’ if NODE_ENV is not defined):
var env = process.env.NODE_ENV || 'development'
, cfg = require('./config.'+env);
module.exports = cfg;
Next comes the config.test.js which will include config.global.js and then overwrite it’s json objects as needed:
config.test.js:
var config = require('./config.global');
config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';
module.exports = config;
And the config.global.js which defines all the defaults:
var config = module.exports = {};
config.env = 'development';
config.hostname = 'dev.example.com';
//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';
Now we wrap it all together and use it in our code…for example in a model, you might do something like this in ./models/user.js:
var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
And that’s all there is to it.
You have to use app.set:
app.set('name of setting', 'value');
You usually put them into a specific configuration block:
app.configure(function () {
// ...
});
You can even use named blocks for having different configurations.
Let express create an application for you and have a look at it. For that simply run
$ express --help
at the command prompt and see what it offers.
PS: This answers both of your questions ;-)

Resources