Allow models backed by MySQL to reference mongodb ObjectID

This commit is contained in:
Raymond Feng 2015-03-04 22:55:33 -08:00
parent dc72bb8696
commit 634a0a94bc
2 changed files with 70 additions and 10 deletions

View File

@ -323,6 +323,9 @@ MySQL.prototype.toDatabase = function (prop, val, forCreate) {
if (!prop) {
return this.client.escape(val);
}
if (prop.type === String) {
return this.client.escape(String(val));
}
if (prop.type === Number) {
if (isNaN(val)) {
val = null;
@ -345,16 +348,25 @@ MySQL.prototype.toDatabase = function (prop, val, forCreate) {
return val ? 'Point(' + val.lat + ',' + val.lng + ')' : 'NULL';
}
if (prop.type === Object) {
return this.client.escape(val);
return this._serializeObject(val);
}
if (typeof prop.type === 'function') {
if (prop.type.modelName) {
// For embedded models
return this.client.escape(JSON.stringify(val));
}
return this.client.escape(prop.type(val));
return this._serializeObject(val);
}
return this.client.escape(val.toString());
return this._serializeObject(val);
};
MySQL.prototype._serializeObject = function(obj) {
var val;
if (obj && typeof obj.toJSON === 'function') {
obj = obj.toJSON();
}
if (typeof obj !== 'string') {
val = JSON.stringify(obj);
} else {
val = obj;
}
return this.client.escape(val);
};
/*!
@ -381,6 +393,12 @@ MySQL.prototype.fromDatabase = function (model, data) {
}
if (props[p]) {
switch (props[p].type.name) {
case 'Number':
val = Number(val);
break;
case 'String':
val = String(val);
break;
case 'Date':
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
break;
@ -394,6 +412,17 @@ MySQL.prototype.fromDatabase = function (model, data) {
lng: val.y
};
break;
case 'List':
case 'Array':
case 'Object':
case 'JSON':
break;
default:
if (!Array.isArray(props[p].type) && !props[p].type.modelName) {
// Do not convert array and model types
val = props[p].type(val);
}
break;
}
}
json[p] = val;

View File

@ -2,6 +2,19 @@ var should = require('./init.js');
var Post, PostWithStringId, PostWithUniqueTitle, db;
// Mock up mongodb ObjectID
function ObjectID(id) {
if (!(this instanceof ObjectID)) {
return new ObjectID(id);
}
this.id1 = id.substring(0, 2);
this.id2 = id.substring(2);
}
ObjectID.prototype.toJSON = function() {
return this.id1 + this.id2;
};
describe('mysql', function () {
before(function (done) {
@ -12,7 +25,8 @@ describe('mysql', function () {
content: { type: String },
comments: [String],
history: Object,
stars: Number
stars: Number,
userId: ObjectID
});
PostWithStringId = db.define('PostWithStringId', {
@ -44,11 +58,11 @@ describe('mysql', function () {
it('should allow array or object', function (done) {
Post.create({title: 'a', content: 'AAA', comments: ['1', '2'],
history: {a: 1, b: 'b'}}, function (err, post) {
history: {a: 1, b: 'b'}}, function(err, post) {
should.not.exist(err);
Post.findById(post.id, function (err, p) {
Post.findById(post.id, function(err, p) {
p.id.should.be.equal(post.id);
p.content.should.be.equal(post.content);
@ -59,7 +73,24 @@ describe('mysql', function () {
done();
});
});
});
it('should allow ObjectID', function(done) {
var uid = new ObjectID('123');
Post.create({title: 'a', content: 'AAA', userId: uid},
function(err, post) {
should.not.exist(err);
Post.findById(post.id, function(err, p) {
p.id.should.be.equal(post.id);
p.content.should.be.equal(post.content);
p.title.should.be.equal('a');
p.userId.should.eql(uid);
done();
});
});
});
it('updateOrCreate should update the instance', function (done) {