Skip to content

Commit

Permalink
Fixed decimal type #332
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Sep 17, 2018
1 parent 9ad2a42 commit 02617db
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 41 deletions.
107 changes: 66 additions & 41 deletions lib/client/network/protocol37/deserializer-binary.js
Expand Up @@ -11,29 +11,6 @@ const OSBTreeRidBag = require("../../../client/database/bag").OSBTreeRidBag;
const BigInteger = require("node-biginteger");
const Long = require("../../../long").Long;

function decimalRead(buffer, scale) {
var num;
var bigi;
if ((buffer[0] & 0x80) === 0) {
bigi = BigInteger.fromBuffer(1, buffer);
num = bigi.longValue().toNumber();
} else {
for (var cur = 0; cur < buffer.length; cur++) {
buffer[cur] = buffer[cur] ^ 0xff;
}
bigi = BigInteger.fromBuffer(-1, buffer);
num = bigi.longValue().toNumber();
// the XOR 0xFF moved the value of 1 unit, change it back
num -= 1;
}
var realScale = 1;
while (scale > 0) {
realScale *= 10;
scale -= 1;
}
return num / realScale;
}

function deserialize(type, input, classes) {
if (!input) {
return null;
Expand Down Expand Up @@ -90,7 +67,7 @@ function parseDocument(input, offset) {

function parseFields(record, input, offset, reader) {
let baseOffset = offset;
let fields = parseNumber(input, offset);
let fields = parseVarintNumber(input, offset);
offset += fields.read;
for (let i = 0; i < fields.value; i++) {
let parsed = parseString(input, offset);
Expand Down Expand Up @@ -133,7 +110,7 @@ function parseValue(input, type, offset, fieldName, reader) {
case 1:
case 2:
case 3:
parsed = parseNumber(input, offset);
parsed = parseVarintNumber(input, offset);
break;
case 4:
parsed = parseFloatNumber(input, offset);
Expand Down Expand Up @@ -173,6 +150,9 @@ function parseValue(input, type, offset, fieldName, reader) {
case 19:
parsed = parseDate(input, offset);
break;
case 21:
parsed = parseDecimal(input, offset);
break;
case 22:
parsed = parseRidBag(input, offset);
break;
Expand All @@ -184,13 +164,13 @@ function parseValue(input, type, offset, fieldName, reader) {
}

function parseDateTime(input, offset) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
parsed.value = new Date(parsed.value);
return parsed;
}

function parseDate(input, offset) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
parsed.value = new Date(parsed.value * 86400000);
return parsed;
}
Expand All @@ -213,7 +193,7 @@ function parseByte(input, offset) {
function parseLinkCollection(input, offset) {
let baseOffset = offset;
let collection = [];
let size = parseNumber(input, offset);
let size = parseVarintNumber(input, offset);
offset += size.read;

for (let i = 0; i < size.value; i++) {
Expand All @@ -226,9 +206,9 @@ function parseLinkCollection(input, offset) {

function parseLink(input, offset) {
let baseOffset = offset;
let clusterId = parseNumber(input, offset);
let clusterId = parseVarintNumber(input, offset);
offset += clusterId.read;
let clusterPosition = parseNumber(input, offset);
let clusterPosition = parseVarintNumber(input, offset);
offset += clusterPosition.read;

let rid;
Expand All @@ -243,12 +223,17 @@ function parseLink(input, offset) {
return { read: offset - baseOffset, value: rid };
}

function parseNumber(input, offset) {
function parseVarintNumber(input, offset) {
let value = varint.decode(input, offset);
let read = varint.decode.bytes;
return { read: read, value: value };
}

function parseInteger(input, offset) {
let value = input.readInt32BE(offset);
return { read: 4, value: value };
}

function parseFloatNumber(input, offset) {
let value = input.readFloatBE(offset);
return { read: 4, value: value };
Expand All @@ -258,15 +243,55 @@ function parseDoubleNumber(input, offset) {
return { read: 8, value: value };
}

function decimalRead(buffer, scale) {
var num;
var bigi;
if ((buffer[0] & 0x80) === 0) {
bigi = BigInteger.fromBuffer(1, buffer);
num = bigi.longValue().toNumber();
} else {
for (var cur = 0; cur < buffer.length; cur++) {
buffer[cur] = buffer[cur] ^ 0xff;
}
bigi = BigInteger.fromBuffer(-1, buffer);
num = bigi.longValue().toNumber();
// the XOR 0xFF moved the value of 1 unit, change it back
num -= 1;
}
var realScale = 1;
while (scale > 0) {
realScale *= 10;
scale -= 1;
}
return num / realScale;
}

function parseDecimal(input, offset) {
let scale = parseInteger(input, offset);
offset = offset + scale.read;
let buffer = parseBytes(input, offset);

return {
read: scale.read + buffer.read,
value: decimalRead(buffer.value, scale.value)
};
}

function parseBytes(input, offset) {
let size = parseInteger(input, offset);
offset = offset + size.read;
let buffer = input.slice(offset, offset + size.value);
return { read: size.read + size.value, value: buffer };
}
function parseString(input, offset) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
offset = offset + parsed.read;
let value = input.toString("utf8", offset, offset + parsed.value);
return { read: parsed.read + parsed.value, value: value };
}

function parseEmbeddedCollection(input, offset, fieldName, reader) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
let baseOffset = offset;
offset += parsed.read;
let embedded = new Array(parsed.value);
Expand Down Expand Up @@ -297,7 +322,7 @@ function parseEmbedded(input, offset, reader) {
}

function parseLinkMap(input, offset) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
let baseOffset = offset;
offset += parsed.read;
let map = {};
Expand All @@ -314,7 +339,7 @@ function parseLinkMap(input, offset) {
return { read: offset - baseOffset, value: map };
}
function parseEmbeddedMap(input, offset) {
let parsed = parseNumber(input, offset);
let parsed = parseVarintNumber(input, offset);
let baseOffset = offset;
offset += parsed.read;
let map = {};
Expand Down Expand Up @@ -349,7 +374,7 @@ function parseRidBag(input, offset) {
let bag = null;
if (type.value === 1) {
bag = new ORidBag(new OEmbeddedRidBag());
let size = parseNumber(input, offset);
let size = parseVarintNumber(input, offset);
offset += size.read;
for (let i = 0; i < size.value; i++) {
let link = parseLink(input, offset);
Expand All @@ -358,15 +383,15 @@ function parseRidBag(input, offset) {
}
// Tree
} else {
let fileId = parseNumber(input, offset);
let fileId = parseVarintNumber(input, offset);
offset += fileId.read;
let pageIndex = parseNumber(input, offset);
let pageIndex = parseVarintNumber(input, offset);
offset += pageIndex.read;
let pageOffset = parseNumber(input, offset);
let pageOffset = parseVarintNumber(input, offset);
offset += pageOffset.read;
let size = parseNumber(input, offset);
let size = parseVarintNumber(input, offset);
offset += size.read;
let changes = parseNumber(input, offset);
let changes = parseVarintNumber(input, offset);
offset += changes.read;

bag = new ORidBag(new OSBTreeRidBag({ size: size.value }));
Expand Down
12 changes: 12 additions & 0 deletions test/database/database-complex-records-test.js
Expand Up @@ -167,6 +167,18 @@ describe("ODatabase API - Open / Simple Query", function() {
should(response.linkMap["bar"]).be.null;
});
});

it("should create a simple record with big decimal", function() {
return this.db
.command("create property Foo.decimal DECIMAL")
.all()
.then(response => {
return this.db.command(`insert into Foo set decimal = 0.32`).one();
})
.then(response => {
response.decimal.should.be.eql(0.32);
});
});
});

describe("Database::RidBags", function() {
Expand Down

0 comments on commit 02617db

Please sign in to comment.