From f572f920a4e884ef20596f403bd05df75cdb49ff Mon Sep 17 00:00:00 2001 From: Amir Jafarian Date: Fri, 4 Dec 2015 14:55:13 -0500 Subject: [PATCH] Implement ReplaceOrCreate --- lib/mysql.js | 41 ++++++++++++++++++-------- test/mysql.test.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 12 deletions(-) diff --git a/lib/mysql.js b/lib/mysql.js index fc545ee..0f0b36e 100644 --- a/lib/mysql.js +++ b/lib/mysql.js @@ -200,17 +200,7 @@ MySQL.prototype.executeSQL = function(sql, params, options, callback) { } }; -/** - * Update if the model instance exists with the same id or create a new instance - * - * @param {String} model The model name - * @param {Object} data The model instance data - * @param {Function} [callback] The callback function - */ -MySQL.prototype.updateOrCreate = MySQL.prototype.save = - function(model, data, options, callback) { - var fields = this.buildFields(model, data); - +MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) { var sql = new ParameterizedSQL('INSERT INTO ' + this.tableEscaped(model)); var columnValues = fields.columnValues; var fieldNames = fields.names; @@ -246,9 +236,36 @@ MySQL.prototype.updateOrCreate = MySQL.prototype.save = // 2 for each successful UPDATE. meta.isNewInstance = (info.affectedRows === 1); } - callback(err, data, meta); + cb(err, data, meta); }); }; + +/** + * Replace if the model instance exists with the same id or create a new instance + * + * @param {String} model The model name + * @param {Object} data The model instance data + * @param {Object} options The options + * @param {Function} [cb] The callback function + */ +MySQL.prototype.replaceOrCreate = function(model, data, options, cb) { + var fields = this.buildReplaceFields(model, data); + this._modifyOrCreate(model, data, options, fields, cb); +}; + +/** + * Update if the model instance exists with the same id or create a new instance + * + * @param {String} model The model name + * @param {Object} data The model instance data + * @param {Object} options The options + * @param {Function} [cb] The callback function + */ +MySQL.prototype.save = +MySQL.prototype.updateOrCreate = function(model, data, options, cb) { + var fields = this.buildFields(model, data); + this._modifyOrCreate(model, data, options, fields, cb); +}; function dateToMysql(val) { return val.getUTCFullYear() + '-' + diff --git a/test/mysql.test.js b/test/mysql.test.js index bd52116..70d8bea 100644 --- a/test/mysql.test.js +++ b/test/mysql.test.js @@ -156,6 +156,78 @@ describe('mysql', function () { }); + context('replaceOrCreate', function() { + it('should replace the instance', function(done) { + Post.create({title: 'a', content: 'AAA'}, function(err, post) { + if (err) return done(err); + post = post.toObject(); + delete post.content; + Post.replaceOrCreate(post, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + p.title.should.equal('a'); + should.not.exist(p.content); + should.not.exist(p._id); + Post.findById(post.id, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + p.title.should.equal('a'); + should.not.exist(post.content); + should.not.exist(p._id); + done(); + }); + }); + }); + }); + + it('should replace with new data', function(done) { + Post.create({title: 'a', content: 'AAA', comments: ['Comment1']}, + function(err, post) { + if (err) return done(err); + post = post.toObject(); + delete post.comments; + delete post.content; + post.title = 'b'; + Post.replaceOrCreate(post, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + should.not.exist(p._id); + p.title.should.equal('b'); + should.not.exist(p.content); + should.not.exist(p.comments); + Post.findById(post.id, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + should.not.exist(p._id); + p.title.should.equal('b'); + should.not.exist(p.content); + should.not.exist(p.comments); + done(); + }); + }); + }); + }); + + it('should create a new instance if it does not exist', function(done) { + var post = {id: 123, title: 'a', content: 'AAA'}; + Post.replaceOrCreate(post, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + should.not.exist(p._id); + p.title.should.equal(post.title); + p.content.should.equal(post.content); + Post.findById(p.id, function(err, p) { + if (err) return done(err); + p.id.should.equal(post.id); + should.not.exist(p._id); + p.title.should.equal(post.title); + p.content.should.equal(post.content); + done(); + }); + }); + }); + }); + it('save should update the instance with the same id', function (done) { Post.create({title: 'a', content: 'AAA'}, function (err, post) { post.title = 'b';