5

Some time ago I decided to switch from PHP to node. In my first projects I didn't want to use any ORM since I thought that I didn't need to complicate my life so much learning another thing (at the moment I was learning node and angular) therefor I decided to use mysql package without anything else. It is important to say that I have some complex queries and I didn't want to learn from sctratch how to make them work using one of the 9000 ORM node have, This is what I've been doing so far:

thing.service.js

Thing.list = function (done) {
  db.query("SELECT * FROM thing...",function (err,data) {
    if (err) {
      done(err)
    } else {
      done(null,data);
    }
  });
};
module.exports = Thing;

thing.controler.js

Thing = require('thing.service.js');
Thing.list(function (err,data) {
  if (err) {
    res.status(500).send('Error D:');
  } else {
    res.json(data);
  }
});

how can I promisify this kind of functions using bluebird ? I've already tried but .... here I am asking for help. This is what I tried

var Thing = Promise.promisifyAll(require('./models/thing.service.js'));

Thing.list().then(function(){})
Ced
  • 721
  • 1
  • 11
  • 21

3 Answers3

15

I have done this way and it is working fine.

const connection = mysql.createConnection({.....});
global.db  = Bluebird.promisifyAll(connection);
db.queryAsync("SELECT * FROM users").then(function(rows){   
console.log(rows);});
Tushar Nikam
  • 594
  • 4
  • 13
9

I have never had much luck with promisifyAll and IMO I prefer to handle my internal checks manually. Here is an example of how I would approach this:

//ThingModule
var Promises = require('bluebird');

Things.list = function(params) {
 return new Promises(function(resolve, reject) {
   db.query('SELECT * FROM thing...', function(err, data) {
     return (err ? reject(err) : resolve(data));
   });

 });
}

//usage
var thinger = require('ThingModule');

thinger.list().then(function(data) {
   //do something with data
})
.error(function(err) {
  console.error(err);
})
sctskw
  • 1,588
  • 1
  • 12
  • 14
  • This looks very good! but following this approach I would need to modify all my existing code, that was the the reason for tying with promisifyAll – Ced Feb 12 '15 at 19:41
  • 1
    totally agree. the maintenance level can be a burden. However, promisifyAll makes a lot of assumptions about how your code works, which will require you to make code changes anyway. There are very few scenarios where promisifyAll will do what you want it to do without drawbacks. – sctskw Feb 12 '15 at 19:59
  • 1
    http://stackoverflow.com/questions/26391419/trying-to-understand-how-promisification-works-with-bluebird ... this would be your reference in what code updates you might need to make – sctskw Feb 12 '15 at 20:03
  • hey, I was checking this account and I decided to respond to this, the problem is that once you use "promisiyAll" then you have to call the functions adding "async" at the end of your function name, for instance, in my example I had to do this: Thing.listAsync().then() – Ced May 06 '15 at 20:57
2

You can also create a function that fires SQL like this :-

function sqlGun(query, obj, callback) {
    mySQLconnection.query(query, obj, function(err, rows, fields) {
        if (err) {
            console.log('Error  ==>', err);
            // throw err;
            return (err, null);
        }
        console.log(query)
        if (rows.length) {
            return callback(null, rows);
        } else {
            return callback(null, [])
        }
    });

}

Where mySQLconnection is the connection object you get after mysql.createConnection({}).

After that, you can promisify the function and use the promise like below :-

var promisified = Promise.promisify(sqlGun);
promisified(query, {}).then( function() {} );
Piyush Balapure
  • 1,023
  • 9
  • 14