Recently I have a requirement to be able to implement a MeteorJS application capable of connecting to different databases according to the connected user.
The structure of the database is the same, only the information it contains changes
I tried connecting through DDP to another backend connected to the necessary database and also by using MongoInternals but, although the users log in correctly, the other collections continue to consult the database by default.
In the server code
const connection = DDP.connect(url)
Accounts.connection = Meteor.connection = connection
_.each(
[
"subscribe",
"methods",
"call",
"apply",
"status",
"reconnect",
"disconnect",
],
function (name) {
Meteor[name] = _.bind(Meteor.connection[name], Meteor.connection); // 55
}
);
ConfigApps = new Mongo.Collection("configapps")
Here the ConfigApps collection obtains the correct data from the database but from the Frontend the data from the other database is read
Or:
var database = new MongoInternals.RemoteCollectionDriver(
"mongodb://localhost:27017/spence-local"
);
ConfigApps = new Mongo.Collection("configapps", {
_driver: database,
_suppressSameNameError: true,
});
Meteor.users = new Mongo.Collection("users", {
_driver: database,
_suppressSameNameError: true,
});
With the same results. User can connect but only one database is read for all querys in the application
Some information or clue would be great.
Related
I have an application in nodejs (express) with a permanent connection to a database in mongodb with mongoose. In this database there are the access data of all users with client ID, as well as other common data.
//server.js
mongoose.connect('mongodb+srv://user:pass#host/DB_Common');
When a user singin, I want to open a connection to the corresponding database (DB_Client001) where he will be able to see data, information... Each client will have his own database. When user logout close the connection.
//users.server.js
//Connection for user0001 (idClient: 001), user002 (idClient: 001), user003 (idClient: 001)...
mongoose.connect('mongodb+srv://user:pass#host/DB_Client001');
//Connection for user010 (idClient: 002), user011 (idClient: 002), user012 (idClient: 002)...
mongoose.connect('mongodb+srv://user:pass#host/DB_Client002');
Mongoose doesn't allow two connections at the same time and the access token for the access I don't know how to implement it in this architecture.
mongoose has a createConnection method
try this
const { createConnection } = require('mongoose');
//Add all these async methods in a function that accepts URL and returns the connection
const db_common = await createConnection('mongodb+srv://user:pass#host/DB_Common')
const db_user0001 = await createConnection('mongodb+srv://user:pass#host/DB_User0001');
const db_user0002 = await createConnection('mongodb+srv://user:pass#host/DB_User0002');
and to check the number of connections you have you can use mongoose.connections.length;
This code snippet solves your problem of having multiple DB connections. But, ideally, you shouldn't have one DB and a corresponding connection for every user. You should change the way your application works
I have an application with Auth0 and graphQl.
I use dataloaders to batching requests to DB. https://github.com/graphql/dataloader
For example, fetching data from DB looks like:
// Booking is Mongoose model
new DataLoader(
bookingIds => Booking.find({ _id: { $in: bookingIds } }),
);
And now I need to fetch data about group of users. Of course, I can write
// getUser is ManagementClient.getUser from 'auth0' package
new DataLoader(
userIds => Promise.all(
userIds.map(
id => getUser({ id }),
),
),
)
This solution is slowly. Can I get data of collection of users by one request?
I work with the Auth0 Community team. You can retrieve users with the GET users endpoint from the management console. Give it a look when you get a chance. Thanks!
how are you doing? Does anyone know how to create database connection dynamically using NodeJS, Express, and Sequelize?
My development team is developing an API for our mobile application, and on the login page, we'll have 3 fields:
Enterprise Code
Username
Password
When the user inputs the "Enterprise Code", I need to go to my default database, which stores all our customers and search the client data based on what was inputted in the field. Let's suppose that the enterprise code is 147, then the API goes to the customer's table into the default database and search for the data where customer_id = 147. That will return the customer data, which also contains its database name, for example, 147_enterprisename, which is a database named "147_enterprisename" referring to this customer.
What I need is: Create a Sequelize connection based on which "Enterprise Code" was typed, like this:
const Sequelize = require('sequelize')
const sequelize = new Sequelize(dynamic_database_name, 'root', 'root', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
})
I also need that the API returns the connection to all routes, where is the functions that fetch data from the database and so on.
Let's say I have a service app.js. Whenever a new client connects to the service , we will check if a mongodb connection is already establish for this client or not.
If it is not available then we will fetch the server ip, dbname ,collection name from a configuration file, connect to the db,and reply to the user.
Note: we can add a new client and corresponding info to Client Info at any time. (dynamically)
Client Info ClientId: ServerIp : Database Name :Collection Name I have tried to store mongo object in array so I can reuse them object based on database name from user's session data. But I keep running into circular json error. How do I store multi tenant database connections?
async.eachSeries(conf.clientDbs.clientsList, function(clientDetails,callback){
console.log(clientDetails);
mongodb.MongoClient.connect(conf.clientDbs.connection+clientDetails.dbName, function (err, database) {
if (err) {
console.log(err);
process.exit(1);
}
// Save database object from the callback for reuse.
var tempdbobj = {};
tempdbobj["obj"] = database
allDbs[clientDetails.team_id] = tempdbobj;
console.log("Database connection ready for "+clientDetails.team_id);
allDbs[clientDetails.team_id].obj.collection('collection_name').find({"ref_id":"111"}, function(dberr, testDoc){
if (dberr) {
console.log(dberr);
callback();
}
else {
console.log(testDoc);
callback();
}
});
});
});
I just want to know if this is possible and how it could be done.
Let's say an Android user has a network connection and makes a change that then updates the database. Then the user loses network connection but still makes changes on their device. They can't obviously send data to the database without a connection.
But when they receive a connection again, the changes they made when there wasn't a connection are automatically updated and sent to the database. How would I go about doing such a thing with Ionic 2 framework? Please point me in the right direction.
Thanks!
Yes it's possible.
For that you need SQLite. It is best to make a SQLite service.
In the first phase the most important thing is to save data to offline/local database. In this case this is SQlite.
When there is no network connection and user make some action save data to table created in your SQlite database.
finishFunction(){
if(this._connectivityService.isOnline()){
//Send data directly to external database
this._api.sendData(this.parameters).subscribe(res => {
});
} else {
//Store data in offline SQLite database
this._database.myOfflineTable(this.parameters);
}
}
After that, in app home page check when network connection is available and call function that sends local/offline data through API to external database. When API return success message you can empty offline table.
sendMyOfflineData(){
this._database.getOfflineTable().then((result) => {
this.OfflineTableList = <Array<Object>> result;
if(this.OfflineTable.length != 0){
for(var i = 0; i < this.OfflineTable.length; i++){
this._api.sendData(this.OfflineTable[i]).subscribe(res => {
if(res.status == true){
this._database.deleteOfflineTable();
}
});
}}
}, (error) => {
console.log("ERROR: ", error);
});
}
If you need more details, I'm here.