diff --git a/lib/Drivers/DML/postgres.js b/lib/Drivers/DML/postgres.js index 3661ca8f..a59ca9eb 100644 --- a/lib/Drivers/DML/postgres.js +++ b/lib/Drivers/DML/postgres.js @@ -243,28 +243,26 @@ Driver.prototype.valueToProperty = function (value, property) { switch (property.type) { case "object": if (typeof value == "object" && !Buffer.isBuffer(value)) { - return value; + break; } try { - return JSON.parse(value); + value = JSON.parse(value); } catch (e) { - return null; + value = null; } break; case "point": if (typeof value == "string") { var m = value.match(/\((\-?[\d\.]+)[\s,]+(\-?[\d\.]+)\)/); if (m) { - return { x : parseFloat(m[1], 10) , y : parseFloat(m[2], 10) }; + value = { x : parseFloat(m[1], 10) , y : parseFloat(m[2], 10) }; } } break; case "number": if (typeof value != 'number' && value !== null) { v = Number(value); - if (!isNaN(v)) { - return v; - } + if (!isNaN(v)) value = v; } break; } diff --git a/lib/Drivers/DML/sqlite.js b/lib/Drivers/DML/sqlite.js index baf1129c..5a4402be 100644 --- a/lib/Drivers/DML/sqlite.js +++ b/lib/Drivers/DML/sqlite.js @@ -205,9 +205,12 @@ Driver.prototype.clear = function (table, cb) { }; Driver.prototype.valueToProperty = function (value, property) { + var v; + switch (property.type) { case "boolean": - return !!value; + value = !!value; + break; case "object": if (typeof value == "object" && !Buffer.isBuffer(value)) { return value; @@ -218,16 +221,24 @@ Driver.prototype.valueToProperty = function (value, property) { return null; } break; + case "number": + if (typeof value != 'number' && value !== null) { + v = Number(value); + if (!isNaN(v)) { + return v; + } + } + break; case "date": if (typeof value === 'string') { if (value.indexOf('Z', value.length - 1) === -1) { return new Date(value + 'Z'); } } - return new Date(value); - default: - return value; + value = new Date(value); + break; } + return value; }; Driver.prototype.propertyToValue = function (value, property) { diff --git a/test/integration/instance.js b/test/integration/instance.js index 57b6f918..e89acae5 100644 --- a/test/integration/instance.js +++ b/test/integration/instance.js @@ -1,19 +1,24 @@ -var should = require('should'); -var helper = require('../support/spec_helper'); +var should = require('should'); +var helper = require('../support/spec_helper'); +var common = require('../common'); var ORM = require('../../'); describe("Model instance", function() { var db = null; var Person = null; + var protocol = common.protocol(); var setup = function () { return function (done) { db.settings.set('instance.returnAllErrors', true); Person = db.define("person", { - name : String, - age : { type: 'number', rational: false, required: false } + name : String, + age : { type: 'number', rational: false, required: false }, + height : { type: 'number', rational: false, required: false }, + weight : { type: 'number', required: false } }, { + cache: false, validations: { age: ORM.validators.rangeNumber(0, 150) } @@ -122,4 +127,107 @@ describe("Model instance", function() { }); }); }); + + describe("properties", function () { + describe("Number", function () { + it("should be saved for valid numbers", function (done) { + var person1 = new Person({ height: 190 }); + + person1.save(function (err) { + should.not.exist(err); + + Person.create({ height: 170 }, function (err, person2) { + should.not.exist(err); + + Person.get(person1[Person.id], function (err, item) { + should.not.exist(err); + should.equal(item.height, 190); + + Person.get(person2[Person.id], function (err, item) { + should.not.exist(err); + should.equal(item.height, 170); + done(); + }); + }); + }); + }); + }); + + if (protocol == 'postgres') { + // Only postgres raises propper errors. + // Sqlite & Mysql fail silently and insert nulls. + it("should raise an error for NaN integers", function (done) { + var person = new Person({ height: NaN }); + + person.save(function (err) { + should.exist(err); + var msg = { + postgres : 'invalid input syntax for integer: "NaN"' + }[protocol]; + + should.equal(err.message, msg); + + done(); + }); + }); + + it("should raise an error for Infinity integers", function (done) { + var person = new Person({ height: Infinity }); + + person.save(function (err) { + should.exist(err); + var msg = { + postgres : 'invalid input syntax for integer: "Infinity"' + }[protocol]; + + should.equal(err.message, msg); + + done(); + }); + }); + + it("should raise an error for nonsensical integers", function (done) { + var person = new Person({ height: 'bugz' }); + + person.save(function (err) { + should.exist(err); + var msg = { + postgres : 'invalid input syntax for integer: "bugz"' + }[protocol]; + + should.equal(err.message, msg); + + done(); + }); + }); + } + + if (protocol != 'mysql') { + // Mysql doesn't support IEEE floats (NaN, Infinity, -Infinity) + it("should store NaN & Infinite floats", function (done) { + var person = new Person({ weight: NaN }); + + person.save(function (err) { + should.not.exist(err); + + Person.get(person[Person.id], function (err, person) { + should.not.exist(err); + should(isNaN(person.weight)); + + person.save({ weight: Infinity, name: 'black hole' }, function (err) { + should.not.exist(err); + + Person.get(person[Person.id], function (err, person) { + should.not.exist(err); + should.strictEqual(person.weight, Infinity); + + done(); + }); + }); + }); + }); + }); + } + }); + }); });