Skip to content

Commit

Permalink
Infinity & NaN support.
Browse files Browse the repository at this point in the history
Number fixes for sqlite.
Should fix #310
  • Loading branch information
dxg committed Aug 28, 2013
1 parent 9141d43 commit 5f5bc61
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 15 deletions.
12 changes: 5 additions & 7 deletions lib/Drivers/DML/postgres.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
19 changes: 15 additions & 4 deletions lib/Drivers/DML/sqlite.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
116 changes: 112 additions & 4 deletions test/integration/instance.js
Original file line number Diff line number Diff line change
@@ -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)
}
Expand Down Expand Up @@ -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();
});
});
});
});
});
}
});
});
});

0 comments on commit 5f5bc61

Please sign in to comment.