I'm using sails 0.9.16 with Postgres and my question is: what is the best way to execute transaction using current API with promises? May be there is something better than:
    Model.query('BEGIN TRANSACTION', function (err) {
      if (err) {
        next(err);
      } else {
        Model
          .create(...)
          .(function (value) {
            return [value, RelatedModel.create(...).then(...)];
          })
          .fail(function (err) {
            Model.query('ROLLBACK');
            next(err);
          })
          .spread(function (...) {
            Model.query('COMMIT')
            next(...);
          })
      }
    })
Thanks for help!
I'm currently using this exact workflow. For executing one query with promises do this:
Model
 .query(params)
 .then(function(result){
 //act on result
 })
 .catch(function(error){
 //handle error
 })
 .done(function(){
 //clean up
 });
To execute multiple queries in parallel, do this:
var Promise = require('q');
Promise.all([
    User.findOne(),
    AnotherModel.findOne(),
    AnotherModel2.find()
])
.spread(function(user,anotherModel,anotherModel2){
    //use the results
})
.catch(function(){
    //handle errors
})
.done(function(){
    //clean up
});
If you're trying to avoid nesting in your code:
Model
.query(params)
.then(function(result){//after query #1
    //since you're returning a promise here, you can use .then after this
    return Model.query();
})
.then(function(results){//after query#2
    if(!results){
        throw new Error("No results found in query #2");
    }else{
        return Model.differentQuery(results);
    }
})
.then(function(results){
//do something with the results
})
.catch(function(err){
    console.log(err);
})
.done(function(){
    //cleanup
});
Note: currently, waterline uses Q for promises. There is a pull request to switch waterline from Q to bluebird here: waterline/bluebird
When I answered this question, I'd yet to take the database class in college, so I didn't know what a transaction was. I did some digging, and bluebird allows you to do transactions with promises. The only problem is, this isn't exactly built into sails since it's some what of a special use case. Here's the code bluebird provides for this situation.
var pg = require('pg');
var Promise = require('bluebird');
Promise.promisifyAll(pg);
function getTransaction(connectionString) {
    var close;
    return pg.connectAsync(connectionString).spread(function(client, done) {
        close = done;
        return client.queryAsync('BEGIN').then(function () {
            return client;
        });
    }).disposer(function(client, promise) {
        if (promise.isFulfilled()) {
            return client.queryAsync('COMMIT').then(closeClient);
        } else {
            return client.queryAsync('ROLLBACK').then(closeClient);
        }
        function closeClient() {
            if (close) close(client);
        }
    });
}
exports.getTransaction = getTransaction;
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With