Skip to content

Commit c770436

Browse files
authored
Merge pull request #153 from pontusmelke/1.1-integer-cleanup
Expose new integer methods
2 parents 93807c3 + a414253 commit c770436

File tree

4 files changed

+144
-10
lines changed

4 files changed

+144
-10
lines changed

README.md

+11-8
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ While there is no need to grab admin right if you are running tests against an e
138138
## A note on numbers and the Integer type
139139
The Neo4j type system includes 64-bit integer values.
140140
However, Javascript can only safely represent integers between `-(2`<sup>`53`</sup>` - 1)` and `(2`<sup>`53`</sup>` - 1)`.
141-
In order to support the full Neo4j type system, the driver includes an explicit Integer types.
142-
Any time the driver recieves an Integer value from Neo4j, it will be represented with the Integer type by the driver.
141+
In order to support the full Neo4j type system, the driver will not automatically convert to javascript integers.
142+
Any time the driver receives an integer value from Neo4j, it will be represented with an internal integer type by the driver.
143143

144144
### Write integers
145145
Number written directly e.g. `session.run("CREATE (n:Node {age: {age}})", {age: 22})` will be of type `Float` in Neo4j.
@@ -158,19 +158,22 @@ session.run("CREATE (n {age: {myIntParam}})", {myIntParam: neo4j.int("9223372036
158158
```
159159

160160
### Read integers
161-
Since Integers can be larger than can be represented as JavaScript numbers, it is only safe to convert Integer instances to JavaScript numbers if you know that they will not exceed `(2`<sup>`53`</sup>` - 1)` in size:
161+
Since Integers can be larger than can be represented as JavaScript numbers, it is only safe to convert to JavaScript numbers if you know that they will not exceed `(2`<sup>`53`</sup>` - 1)` in size.
162+
In order to facilitate working with integers the driver include `neo4j.isInt`, `neo4j.integer.inSafeRange`, `neo4j.integer.toNumber`, and `neo4j.integer.toString`.
162163

163164
```javascript
164165
var aSmallInteger = neo4j.int(123);
165-
var aNumber = aSmallInteger.toNumber();
166+
if (neo4j.integer.inSafeRange(aSmallInteger)) {
167+
var aNumber = aSmallInteger.toNumber();
168+
}
166169
```
167170

168-
If you will be handling integers larger than that, you can use the Integer instances directly, or convert them to strings:
171+
If you will be handling integers larger than that, you can should convert them to strings:
169172

170173
```javascript
171174
var aLargerInteger = neo4j.int("9223372036854775807");
172-
var integerAsString = aLargerInteger.toString();
175+
if (!neo4j.integer.inSafeRange(aSmallInteger)) {
176+
var integerAsString = aLargerInteger.toString();
177+
}
173178
```
174179

175-
To help you work with Integers, the Integer class exposes a large set of arithmetic methods.
176-
Refer to the [Integer API docs](http://neo4j.com/docs/api/javascript-driver/current/class/src/v1/integer.js~Integer.html) for details.

src/v1/index.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* limitations under the License.
1818
*/
1919

20-
import {int, isInt} from './integer';
20+
import {int, isInt, inSafeRange, toNumber, toString} from './integer';
2121
import {Node, Relationship, UnboundRelationship, PathSegment, Path} from './graph-types'
2222
import {Neo4jError, SERVICE_UNAVAILABLE, SESSION_EXPIRED} from './error';
2323
import Result from './result';
@@ -138,11 +138,17 @@ const error = {
138138
SERVICE_UNAVAILABLE,
139139
SESSION_EXPIRED
140140
};
141+
const integer = {
142+
toNumber,
143+
toString,
144+
inSafeRange
145+
};
141146

142147
const forExport = {
143148
driver,
144149
int,
145150
isInt,
151+
integer,
146152
Neo4jError,
147153
auth,
148154
types,
@@ -154,6 +160,7 @@ export {
154160
driver,
155161
int,
156162
isInt,
163+
integer,
157164
Neo4jError,
158165
auth,
159166
types,

src/v1/integer.js

+82-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {newError} from "./error";
3232
* @param {number} low The low (signed) 32 bits of the long
3333
* @param {number} high The high (signed) 32 bits of the long
3434
* @constructor
35+
*
36+
* @deprecated This class will be removed or made internal in a future version of the driver.
3537
*/
3638
class Integer {
3739
constructor(low, high) {
@@ -67,6 +69,8 @@ class Integer {
6769
// Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
6870
// methods on which they depend.
6971

72+
73+
inSafeRange() {return this.greaterThanOrEqual(Integer.MIN_SAFE_VALUE) && this.lessThanOrEqual(Integer.MAX_SAFE_VALUE)}
7074
/**
7175
* Converts the Integer to an exact javascript Number, assuming it is a 32 bit integer.
7276
* @returns {number}
@@ -718,6 +722,41 @@ Integer.fromValue = function(val) {
718722
return new Integer(val.low, val.high);
719723
};
720724

725+
/**
726+
* Converts the specified value to a number.
727+
* @access private
728+
* @param {!Integer|number|string|!{low: number, high: number}} val Value
729+
* @returns {number}
730+
* @expose
731+
*/
732+
Integer.toNumber = function(val) {
733+
return Integer.fromValue(val).toNumber();
734+
};
735+
736+
/**
737+
* Converts the specified value to a string.
738+
* @access private
739+
* @param {!Integer|number|string|!{low: number, high: number}} val Value
740+
* @param {number} radix optional radix for string conversion, defaults to 10
741+
* @returns {String}
742+
* @expose
743+
*/
744+
Integer.toString = function(val, radix) {
745+
return Integer.fromValue(val).toString(radix)
746+
};
747+
748+
/**
749+
* Checks if the given value is in the safe range in order to be converted to a native number
750+
* @access private
751+
* @param {!Integer|number|string|!{low: number, high: number}} val Value
752+
* @param {number} radix optional radix for string conversion, defaults to 10
753+
* @returns {boolean}
754+
* @expose
755+
*/
756+
Integer.inSafeRange = function(val) {
757+
return Integer.fromValue(val).inSafeRange();
758+
};
759+
721760
/**
722761
* @type {number}
723762
* @const
@@ -801,6 +840,20 @@ Integer.MAX_VALUE = Integer.fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
801840
*/
802841
Integer.MIN_VALUE = Integer.fromBits(0, 0x80000000|0, false);
803842

843+
/**
844+
* Minimum safe value.
845+
* @type {!Integer}
846+
* @expose
847+
*/
848+
Integer.MIN_SAFE_VALUE = Integer.fromBits(0x1|0, 0xFFFFFFFFFFE00000|0);
849+
850+
/**
851+
* Maximum safe value.
852+
* @type {!Integer}
853+
* @expose
854+
*/
855+
Integer.MAX_SAFE_VALUE = Integer.fromBits(0xFFFFFFFF|0,0x1FFFFF|0);
856+
804857
/**
805858
* Cast value to Integer type.
806859
* @access public
@@ -812,14 +865,42 @@ let int = Integer.fromValue;
812865
/**
813866
* Check if a variable is of Integer type.
814867
* @access public
815-
* @param {Mixed} value - The varaible to check.
868+
* @param {Mixed} value - The variable to check.
816869
* @return {Boolean} - Is it of the Integer type?
817870
*/
818871
let isInt = Integer.isInteger;
819872

873+
/**
874+
* Check if a variable can be safely converted to a number
875+
* @access public
876+
* @param {Mixed} value - The variable to check
877+
* @return {Boolean} - true if it is safe to call toNumber on variable otherwise false
878+
*/
879+
let inSafeRange = Integer.inSafeRange;
880+
881+
/**
882+
* Converts a variable to a number
883+
* @access public
884+
* @param {Mixed} value - The variable to convert
885+
* @return {number} - the variable as a number
886+
*/
887+
let toNumber = Integer.toNumber;
888+
889+
/**
890+
* Converts the integer to a string representation
891+
* @access public
892+
* @param {Mixed} value - The variable to convert
893+
* @param {number} radix - radix to use in string conversion, defaults to 10
894+
* @return {String} - returns a string representation of the integer
895+
*/
896+
let toString = Integer.toString;
897+
820898
export {
821899
int,
822900
isInt,
901+
inSafeRange,
902+
toNumber,
903+
toString
823904
}
824905

825906
export default Integer

test/v1/integer.test.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
var v1 = require('../../lib/v1');
21+
var int = v1.int;
22+
var integer = v1.integer;
23+
24+
describe('Pool', function() {
25+
it('exposes inSafeRange function', function () {
26+
expect(integer.inSafeRange(int("9007199254740991"))).toBeTruthy();
27+
expect(integer.inSafeRange(int("9007199254740992"))).toBeFalsy();
28+
expect(integer.inSafeRange(int("-9007199254740991"))).toBeTruthy();
29+
expect(integer.inSafeRange(int("-9007199254740992"))).toBeFalsy();
30+
});
31+
32+
it('exposes toNumber function', function () {
33+
expect(integer.toNumber(int("9007199254740991"))).toEqual(9007199254740991);
34+
expect(integer.toNumber(int("-9007199254740991"))).toEqual(-9007199254740991);
35+
});
36+
37+
it('exposes toString function', function () {
38+
expect(integer.toString(int("9007199254740991"))).toEqual("9007199254740991");
39+
expect(integer.toString(int("9007199254740992"))).toEqual("9007199254740992");
40+
expect(integer.toString(int("-9007199254740991"))).toEqual("-9007199254740991");
41+
expect(integer.toString(int("-9007199254740992"))).toEqual("-9007199254740992");
42+
});
43+
});

0 commit comments

Comments
 (0)