3

I am rebuilding a legacy PHP application using nodejs and I choose sailsjs after about a week of exploration. Everything was fine until I realised that in sails you only have access to session variables in your controllers. Thus, I cannot make dynamic connections with the model.

The legacy app uses PHP session global variables to connect to different postgresql databases after authentication and I can't seem to find a work around on the web. I have seen similar questions on sails around the web. Any node/sails/database geeks around?

I am thinking of using sails for authentication since it already works and using expressjs to implement services that my sails app would then call by sending db connection params in some form of microservice architecture.

Currenttly running sails on localhost:1337 and my express on localhost:3000. Is this a good way to go about?

ArrowHead
  • 609
  • 5
  • 16
  • what do you mean? you can set different connections in your`config/connections.js` and set the connection for each model. – Luis González Jul 19 '16 at 08:18
  • @LuisGonzález . I know about that, I have a connection for a database that is used for authentication(default database). After authentication, I need to connect to different databases to pull data based on the current user. In my model, how do I dynamically tell my models to connect to a particular database. Current, when I do console.log of my connections, it is showing the default database. – ArrowHead Jul 19 '16 at 08:25

3 Answers3

1

I think you can't dynamically change the connection property defined in models. However you could try not setting any connection in models which connection will dynamically change, and set the default config connection depending on the user. Some thing like:

User.find(1, function(err, user){

    connection = select_connection_for_phones(user);

    // changing the model connection dinamically
    // You should not define any connection in the model.
    sails.config.models.connection = connection;
    Phone.find({user : user.id }, do_something_else);

});

That way, your select_connection_for_phones will receive the user and return the string connection, you set the global config connection for models, and after that you start the query. If your model Phone has no connection defined, it will use the default.

The inverse way, could be something like:

User.find(1, function(err, user){

    connection = select_connection_for_phones(user);

    // changing properties of the postgresql connection.
    // You must define all your models with this connection.
    sails.config.connections.postgresql.host = host_from_user(user);
    sails.config.connections.postgresql.port = port_from_user(user);
    Phone.find({user : user.id }, do_something_else);

});

In this case you should set the models with the same connections, and you dynamically change the connection's properties.

Luis González
  • 3,199
  • 26
  • 43
  • The problem is not the use of different drivers. I am using one driver (postgresql). I need database connections based on the current user. In sails if you don't specify "connection", in the model, it uses the default database. I want to dynamically be able to change that. based on the current authenticated user. – ArrowHead Jul 19 '16 at 08:29
  • 1
    Thanks for your suggestion, unfortunately, this doesn't resolve the issue. Even when I overwrite the connection properties, it still tries to pull data from the default database specified. I have looked at similar questions on stackover and around the web, it seems to be an open/common problem with sails. Thanks – ArrowHead Jul 19 '16 at 10:08
1

I am answering my own question here, similar questions have been asked here and none of the answers provided seems to work. Instead of using waterline in my models, I have used successfully the pg module,

$ npm install pg --save
var pg = require('pg');

in this way, I can dynamically pass the connection string from my controller to my models and disregard the waterline ORM.

I created a sails service to get and set the database connection string for each session.

Then for each query I pass the connection string stored in session around :

var sessionConnection = ConnectionsService.getSessionConnection(req,res);

  pg.connect(sessionConnection, function(err, client, done) {
     // do connection stuff and queries here

  });

Hope this helps others

ArrowHead
  • 609
  • 5
  • 16
0

I create a sails adapter from sails-postgresql v0.11.4 with extras functions. https://www.npmjs.com/package/sails-postgresql-pp