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: ''
};
Related
So, if I use my DeepStream server as the following
const {Deepstream} = require('#deepstream/server')
const server = new Deepstream({
server.start()
it's working just fine I can connect to it from my frontend app like the following
const {DeepstreamClient} = require('#deepstream/client')
const client = new DeepstreamClient('192.168.88.238:6020')
client.login()
but If I add MongoDB storage instance or RethinkDB
NPM - RethinkDB
const {Deepstream} = require('#deepstream/server')
const server = new Deepstream({
storage: {
name: 'rethinkdb',
options: {
host: 'localhost',
port: 28015
}
}
})
// start the server
server.start()
I get the following error message when trying to reach my ds server.
(I've also tried to connect via WSS:// instead of WS://)
So hi everybody who has the same problem as me...
I figured it out!
So first of all what the npm packages documentation says from the usage of the Mongo DB driver is completely out of data
so what they say how should u use the npm package :
var Deepstream = require( 'deepstream.io' ),
MongoDBStorageConnector = require( 'deepstream.io-storage-mongodb' ),
server = new Deepstream();
server.set( 'storage', new MongoDBStorageConnector( {
connectionString: 'mongodb://test:test#paulo.mongohq.com:10087/munchkin-dev',
splitChar: '/'
}));
server.start();
INSTEAD OF ALL THIS!
You ain't really need the 'deep stream.io-storage-MongoDB' because it's an old module (based on: ), and u don't really need to use this way...
The correct usage of the MongoDB connector :
const {Deepstream} = require('#deepstream/server');
const server = new Deepstream({
storage: {
name: "mongodb",
options: {
connectionString: MONGO_CONNECTION_STRING ,
splitChar: '/'
}
}
});
server.start();
or you can also create a config. yaml file from all this :
storage:
name: mongodb
options:
connectionString: 'MONGO_CONNECTION_STRING'
# optional database name, defaults to `deepstream`
database: 'DATABASE_NAME'
# optional table name for records without a splitChar
# defaults to deepstream_docs
defaultCollection: 'COLLECTION_NAME'
# optional character that's used as part of the
# record names to split it into a table and an id part
splitChar: '/'
and pass it to the deep stream constructor as below:
const {Deepstream} = require('#deepstream/server');
const server = new Deepstream('config.yaml');
server.start();
If I have a connection URI, I can use that normally with Sequelize as such:
const sequelize = new Sequelize('postgres://user:pass#example.com:5432/dbname');
However, if I want to use Read and Write replication (https://sequelize.org/master/manual/read-replication.html), then there doesn't seem an option to use connection URI. Can I pass connection URI strings to read and write in the replication option as in:
const sequelize = new Sequelize(null, null, null, {
dialect: 'postgres',
replication: {
read: [
'postgres://user:pass#reader.example.com:5432/dbname',
'postgres://user:pass#anotherreader.example.com:5432/dbname'
],
write: 'postgres://user:pass#writer.example.com:5432/dbname'
}
})
EDIT:
I have already found a solution to the issue. and that is using an npm library like connection string to parse the connection string as shown below:
const write_uri = new ConnectionString(uri);
const sequelize = new Sequelize(null, null, null, {
dialect: 'postgres',
replication: {
read: [
'postgres://user:pass#reader.example.com:5432/dbname',
'postgres://user:pass#anotherreader.example.com:5432/dbname'
],
write: {
host: write_uri.hosts[0].name,
username: write_uri.user,
password: write_uri.password,
database: write_uri.path[0],
port: write_uri.hosts[0].port
}
}
});
But, that is not what I'm looking for.
As per sequelize source at master, you can't.
According to the sequelize source docs at sequelize.js, The Sequelize Constructor accepts options agrument, like this
constructor(database, username, password, options){
}
Where options.replication should be an object with two properties, read and write. Write should be an object (a single server for handling writes), and read an array of object (several servers to handle reads). Each read/write server can have the following properties: host, port, username, password, database.
you need to pass an array of objects to read:[] with connection values as props instead of passing strings.
You can pass config object to sequelize constructor even if you use uri connection.
Look the example in from the docs:
https://sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor
// with uri
const sequelize = new Sequelize('mysql://localhost:3306/database', {})
Look at the constructor overloading definition:
Sequelize(uri: string, options?: Sequelize.Options): Sequelize.Sequelize
Just pass the options you need.
I have a replica set on MongoDB Atlas and this is my mongo shell connection string which connects perfectly:
$ mongo "mongodb://MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE?replicaSet=MY_REPLICASET-NAME-shard-0" --ssl --username MY_USERNAME --password MY_PASSWORD --authenticationDatabase MY_ADMIN_DATABASE
How Can I convert it to use in mongoose? How Can I build my uri and options variable?
I tried the following without success:
// connection string using mongoose:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE';
var options = {
replset: {
ssl: true,
authSource: 'MY_ADMIN_DATABASE',
rs_name: 'MY_REPLICASET_NAME-shard-0'
}
};
mongoose.connect(uri, options);
var db = mongoose.connection;
I've tried including user: and pass: on options, removing MY_USER:MY_PASSWORD# from uri, change rs_name to replicaSet, every unsuccessful attempt. It seems that mongoose is not considering the authSource option.
Using the mongojs, it works fine with the following code:
// connection string using mongojs:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE';
var options = {
ssl: true,
authSource: 'MY_ADMIN_DATABASE',
replicaSet: 'MY_REPLICASET_NAME-shard-0'
};
var db = mongojs(uri,'', options);
But, I need to use mongoose because the ODM in my project.
How can I build my uri and options variable using mongoose?
ON MONGODB 3.4.x
I resolved this issue putting the 'options' value directly in 'uri' string, according to documentation (http://mongoosejs.com/docs/connections.html) on 'Replica Set Connections' section.
// connection string using mongoose:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE' +
'ssl=true&replicaSet=MY_REPLICASET_NAME-shard-0&authSource=MY_ADMIN_DATABASE';
mongoose.connect(uri);
var db = mongoose.connection;
Now, it is working fine!
NOTICE WITH MONGODB 3.6
On MongoDB Atlas using the version 3.6.x, the connection string changed to use a DNS server making the link shorter.
mongodb+srv://MY_USER:MY_PASSWORD#MY_SERVER.mongodb.net/MY_DATABASE
...if you use this connection string in your application, this will connect with success but it will be able to read and write only with atlas users with higher privilegies access (atlasAdmin, readWriteAnyDatabase...).
To you work with an specific user with privilege only to readWrite your database, you will need to keep the same connection string used in MongoDB 3.4 because the mongoose not recognized the DNS option (mongodb+srv).
P.S. all the new resources from MongoDB 3.6.x will continue working normally!
Add username and password to database connection
mongodb://[username:password#]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
Standard Connection String Format
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.
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');