├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .jshintignore
├── .jshintrc
├── LICENSE
├── Makefile
├── README.md
├── index.d.ts
├── index.js
├── itest
├── asyncreq.js
├── compression.js
├── connect.js
├── deserialization.js
├── emptyChar2null.js
├── flipTables.js
├── issue18.js
├── nanos2date.js
├── readme.js
├── serialization.js
├── subs.js
├── syncreqres.js
├── tls.js
└── unicode.js
├── lib
├── assert.js
├── c.js
├── typed.d.ts
└── typed.js
├── package-lock.json
├── package.json
├── test
├── c.js
├── compress.js
├── connect.js
└── typed.js
└── tsconfig.json
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | runs-on: 'ubuntu-latest'
8 |
9 | steps:
10 |
11 | - uses: 'actions/checkout@v2'
12 |
13 | - uses: 'actions/setup-node@v1'
14 | with:
15 | node-version: '12'
16 |
17 | - name: install dependencies
18 | run: npm ci
19 |
20 | - name: run tests
21 | run: npm test
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | npm-debug.log
3 | coverage/
4 |
5 |
--------------------------------------------------------------------------------
/.jshintignore:
--------------------------------------------------------------------------------
1 | node_modules/**
2 | test/**
3 | lib/c.js
4 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "maxerr" : 500,
3 | "bitwise" : true,
4 | "camelcase" : false,
5 | "curly" : true,
6 | "eqeqeq" : true,
7 | "forin" : true,
8 | "immed" : false,
9 | "indent" : 4,
10 | "latedef" : true,
11 | "newcap" : false,
12 | "noarg" : true,
13 | "noempty" : true,
14 | "nonew" : false,
15 | "plusplus" : false,
16 | "quotmark" : false,
17 | "undef" : true,
18 | "unused" : false,
19 | "strict" : true,
20 | "trailing" : true,
21 | "maxparams" : false,
22 | "maxdepth" : false,
23 | "maxstatements" : false,
24 | "maxcomplexity" : false,
25 | "maxlen" : false,
26 | "asi" : false,
27 | "boss" : false,
28 | "debug" : false,
29 | "eqnull" : false,
30 | "es5" : false,
31 | "esnext" : false,
32 | "moz" : false,
33 | "evil" : false,
34 | "expr" : false,
35 | "funcscope" : false,
36 | "globalstrict" : false,
37 | "iterator" : false,
38 | "lastsemic" : false,
39 | "laxbreak" : false,
40 | "laxcomma" : false,
41 | "loopfunc" : false,
42 | "multistr" : false,
43 | "proto" : false,
44 | "scripturl" : false,
45 | "shadow" : false,
46 | "sub" : false,
47 | "supernew" : false,
48 | "validthis" : false,
49 | "browser" : false,
50 | "couch" : false,
51 | "devel" : false,
52 | "dojo" : false,
53 | "jquery" : false,
54 | "mootools" : false,
55 | "node" : true,
56 | "nonstandard" : false,
57 | "prototypejs" : false,
58 | "rhino" : false,
59 | "worker" : false,
60 | "wsh" : false,
61 | "yui" : false,
62 | "globals" : {},
63 | "predef" : ["describe", "it", "before", "after"]
64 | }
65 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Michael Wittig
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | default: test
2 |
3 | jshint:
4 | @echo "jshint"
5 | @find . -name "*.js" -print0 | xargs -0 ./node_modules/.bin/jshint
6 |
7 | circular:
8 | @echo "circular"
9 | @./node_modules/.bin/madge --circular --format amd --exclude "madge|source-map" .
10 |
11 | mocha:
12 | @echo "mocha (unit test)"
13 | @TZ=UTC ./node_modules/.bin/mocha test/*.js
14 | @echo
15 |
16 | coverage:
17 | @echo "cover"
18 | @./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha test/*
19 | @echo
20 |
21 | mochait:
22 | @echo "mocha (integreation test assumes running kdb+tick process on localhost:5000)"
23 | @TZ=UTC ./node_modules/.bin/mocha -t 5000 itest/*.js
24 | @echo
25 |
26 | test: jshint mocha circular
27 | @echo "test"
28 | @echo
29 |
30 | itest: jshint mocha mochait circular
31 | @echo "test"
32 | @echo
33 |
34 | outdated:
35 | @echo "outdated modules?"
36 | @./node_modules/.bin/npmedge
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-q
2 |
3 | Q interfacing with Node.js. Supports [decompression](http://code.kx.com/wiki/Reference/ipcprotocol#Compression). Can deserialize all q data types (including `guid`) to JavaScript. Can serialize all JavaScript data types to q.
4 |
5 | ## Installation
6 |
7 | ```
8 | npm install node-q
9 | ```
10 |
11 | ## Usage
12 |
13 | ### Create Connection
14 |
15 | ```javascript
16 | var nodeq = require("node-q");
17 | nodeq.connect({host: "localhost", port: 5000}, function(err, con) {
18 | if (err) throw err;
19 | console.log("connected");
20 | // interact with con like demonstrated below
21 | });
22 | ```
23 |
24 | ### Create TLS Connection
25 |
26 | ```javascript
27 | var nodeq = require("node-q");
28 | nodeq.connect({host: "localhost", port: 6000, useTLS: true}, function(err, con) {
29 | if (err) throw err;
30 | console.log("connected");
31 | // interact with con like demonstrated below
32 | });
33 | ```
34 |
35 | ### Create Connection with user and password auth
36 |
37 | ```javascript
38 | var nodeq = require("node-q");
39 | nodeq.connect({host: "localhost", port: 5000, user: "user", password: "password"}, function(err, con) {
40 | if (err) throw err;
41 | console.log("connected");
42 | // interact with con like demonstrated below
43 | });
44 | ```
45 |
46 | ### Create Connection with Unix Domain Socket (Doesn't support abstract namespace sockets: KDB 3.5+ on Linux)
47 |
48 | ```javascript
49 | nodeq.connect({ unixSocket: "/path/to/socket" }, function(err, con) {
50 | if (err) throw err;
51 | console.log("connected");
52 | });
53 | ```
54 |
55 | ### Execute Q code and receive result
56 |
57 | ```javascript
58 | con.k("sum 1 2 3", function(err, res) {
59 | if (err) throw err;
60 | console.log("result", res); // 6
61 | });
62 | ```
63 |
64 | ### Execute function with one parameter and receive result
65 |
66 | ```javascript
67 | con.k("sum", [1, 2, 3], function(err, res) {
68 | if (err) throw err;
69 | console.log("result", res); // 6
70 | });
71 | ```
72 |
73 | ### Execute function with two parameters and receive result
74 |
75 | ```javascript
76 | con.k("cor", [1, 2, 3], [4, 5, 6], function(err, res) {
77 | if (err) throw err;
78 | console.log("result", res); // 1
79 | });
80 | ```
81 |
82 | ### Async execute Q code
83 |
84 | ```javascript
85 | con.ks("show 1 2 3", function(err) {
86 | if (err) throw err;
87 | });
88 | ```
89 |
90 | ### Async execute function with parameters
91 |
92 | ```javascript
93 | con.ks("show", [1, 2, 3], function(err) {
94 | if (err) throw err;
95 | });
96 | ```
97 |
98 | ### Listen to a handle
99 |
100 | ```javascript
101 | con.k(function(err, res) {
102 | if (err) throw err;
103 | console.log("result", res);
104 | });
105 | ```
106 |
107 | ### Subscribe to kdb+tick
108 |
109 | ```javascript
110 | con.on("upd", function(table, data) {
111 | console.log(table, data);
112 | });
113 |
114 | con.ks(".u.sub[`;`]", function(err) { // subscribe to all tables and all symbols
115 | if (err) throw err;
116 | });
117 | ```
118 |
119 | ### Close connection
120 |
121 | ```javascript
122 | con.close(function() {
123 | console.log("con closed");
124 | });
125 | ```
126 |
127 | ## Types
128 |
129 | q has more [data types](http://code.kx.com/wiki/Reference/Datatypes) than JavaScript. Therefore you need to know how types are converted.
130 |
131 | ### From q to JavaScript (deserialization)
132 |
133 | | q type | JavaScript type | Null | +Infinity | -Infinity |
134 | | ------ | --------------- | ---- | --------- | --------- |
135 | | boolean | [Boolean](https://developer.mozilla.org/docs/Glossary/Boolean) | | | |
136 | | guid | [String](https://developer.mozilla.org/docs/Glossary/String) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
137 | | byte | [Number](https://developer.mozilla.org/docs/Glossary/Number) | | | |
138 | | short | [Number](https://developer.mozilla.org/docs/Glossary/Number) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) |
139 | | int | [Number](https://developer.mozilla.org/docs/Glossary/Number) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) |
140 | | long | [Number](https://developer.mozilla.org/docs/Glossary/Number) [5](#types-footnote5) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) |
141 | | real | [Number](https://developer.mozilla.org/docs/Glossary/Number) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) |
142 | | float | [Number](https://developer.mozilla.org/docs/Glossary/Number) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) |
143 | | char | [String](https://developer.mozilla.org/docs/Glossary/String) | [Null](https://developer.mozilla.org/docs/Glossary/Null) [4](#types-footnote4) | | |
144 | | symbol | [String](https://developer.mozilla.org/docs/Glossary/String) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
145 | | timestamp | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [1](#types-footnote1), [2](#types-footnote2) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
146 | | month | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
147 | | date | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
148 | | datetime | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
149 | | timespan | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [1](#types-footnote1), [2](#types-footnote2), [3](#types-footnote3) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
150 | | minute | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2), [3](#types-footnote3) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
151 | | second | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2), [3](#types-footnote3) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
152 | | time | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) [2](#types-footnote2), [3](#types-footnote3) | [Null](https://developer.mozilla.org/docs/Glossary/Null) | | |
153 |
154 | * 1: q comes with nanoseconds precision. JavaScript only with milliseconds. You can disable `nanos2date` deserialization during `connect(params, cb)` to get the nanoseconds timestamp as a plain [Number](https://developer.mozilla.org/docs/Glossary/Number).
155 | * 2: think about running your Node.js process with `TZ=UTC node ...` to run in UTC timezone. q doesn't know timezones.
156 | * 3: date is set to `2000-01-01` in the Date object. Only evaluate the time part.
157 | * 4: You can disable `emptyChar2null` deserialization during `connect(params, cb)` to keep the empty char.
158 | * 5: You can disable `long2number` deserialization during `connect(params, cb)` to represent longs as [long.js](https://www.npmjs.com/package/long).
159 |
160 | #### dict
161 |
162 | ```
163 | q) (`a`b`c)!(1 2 3i)
164 | ```
165 |
166 | becomes [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)
167 |
168 |
169 | ```javascript
170 | {
171 | a: 1,
172 | b: 2,
173 | c: 3
174 | }
175 | ```
176 |
177 | #### list
178 |
179 | ```
180 | q) 1 2 3i
181 | ```
182 |
183 | becomes [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)
184 |
185 | ```javascript
186 | [1, 2, 3]
187 | ```
188 |
189 | #### table
190 |
191 | ```
192 | q) ([] sym:`a`b`c; size:(1 2 3i))
193 | ```
194 |
195 | becomes [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) of [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) per row.
196 |
197 | ```javascript
198 | [
199 | {sym: "a", size: 1},
200 | {sym: "b", size: 2},
201 | {sym: "c", size: 3}
202 | ]
203 | ```
204 |
205 | You can disable `flipTables` during `connect(params, cb)` to get a table as an [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) with an [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) per column.
206 |
207 | ```javascript
208 | {
209 | sym: ["a", "b", "c"],
210 | size: [1, 2, 3]
211 | }
212 | ```
213 |
214 | ### From JavaScript to q (serialization)
215 |
216 | #### Simple (infer type)
217 |
218 | | JavaScript type | q type |
219 | | --------------- | ------ |
220 | | [Boolean](https://developer.mozilla.org/docs/Glossary/Boolean) | boolean |
221 | | [String](https://developer.mozilla.org/docs/Glossary/String) starting with ` | symbol |
222 | | [String](https://developer.mozilla.org/docs/Glossary/String) | list[char] |
223 | | [Number](https://developer.mozilla.org/docs/Glossary/Number) | float |
224 | | [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | datetime |
225 | | [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) | dict |
226 | | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)[*] | list[*] |
227 | | [Null](https://developer.mozilla.org/docs/Glossary/Null) | unary primitive |
228 | | [Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | float |
229 | | -[Infinity](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | float |
230 |
231 | #### Advanced (explicit types)
232 |
233 | If you want to explicitly serialize a JavaScript type as a q type you need to use the typed API.
234 |
235 | Let's start with two examples:
236 |
237 | ```javascript
238 | con.k("type", nodeq.short(1), function(err, res) {
239 | if (err) throw err;
240 | console.log("result", res); // -5
241 | });
242 |
243 | con.k("type", nodeq.shorts([1, 2, 3]), function(err, res) {
244 | if (err) throw err;
245 | console.log("result", res); // 5
246 | });
247 | ```
248 |
249 | For every primitive type in q, this module exports a method to wrap the JavaScript value. You can also wrap a JavaScript array into a q type by appending an s to the primitive wrapper's name.
250 |
251 | | q type | primitive wrapper | array wrapper |
252 | | ------ | ----------------- | ------------- |
253 | | boolean | `boolean(Boolean)` | `booleans(Array[Boolean])` |
254 | | guid | `guid(String)`| `guids(Array[String])` |
255 | | byte | `byte(Number)`| `bytes(Array[Number])` |
256 | | short | `short(Number)` | `shorts(Array[Number])` |
257 | | int | `int(Number)` | `ints(Array[Number])` |
258 | | long | `long(long)` [1](#wrappers-footnote1) | `longs(Array[long])` [1](#wrappers-footnote1) |
259 | | real | `real(Number)` | `reals(Array[Number])` |
260 | | float | `float(Number)` | `floats(Array[Number])` |
261 | | char | `char(String)` | `chars(Array[String])` |
262 | | symbol | `symbol(String)` | `symbols(Array[String])` |
263 | | timestamp | `timestamp(Date)` | `timestamps(Array[Date])` |
264 | | month | `month(Date)` | `months(Array[Date])` |
265 | | date | `date(Date)` | `dates(Array[Date])` |
266 | | datetime | `datetime(Date)` | `datetimes(Array[Date])` |
267 | | timespan | `timespan(Date)` | `timespans(Array[Date])` |
268 | | minute | `minute(Date)` | `minutes(Array[Date])` |
269 | | second | `second(Date)` | `seconds(Array[Date])` |
270 | | time | `time(Date)` | `times(Array[Date])` |
271 |
272 | * 1: JavaScript can not represent 64bit longs. Therefore this module uses the [long.js](https://www.npmjs.com/package/long) module to represent longs.
273 |
274 | ## API
275 |
276 | ### connect(params, cb)
277 |
278 | * `params`: Object
279 | * `host`: String (e. g. "localhost") (optional)
280 | * `port`: Number (e. g. 5000) (optional)
281 | * `unixSocket`: String (e. g. "/path/to/socket") (optional)
282 | * `user`: String (optional)
283 | * `password`: String (optional)
284 | * `useTLS`: Boolean (optional)
285 | * `ca`: Buffer | String (e.g. fs.readFileSync('path\\to\\cert.pem')) (optional)
286 | * `socketNoDelay` : Boolean (optional, see http://nodejs.org/api/net.html#net_socket_setnodelay_nodelay)
287 | * `socketTimeout`: Number (optional, see http://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback)
288 | * `nanos2date`: Boolean (optional, default: true)
289 | * `flipTables`: Boolean (optional, default: true)
290 | * `emptyChar2null`: Boolean (optional, default: true)
291 | * `long2number`: Boolean (optional, default: true)
292 | * `cb`: Function(`err`, `con`)
293 | * `err`: `Error` or `undefined`
294 | * `conn`: `Connection` or `undefined`
295 |
296 | ### @deprecated connect(host, port, [user, password,] cb)
297 |
298 | This is deprecated. Please use the new, mor flexible API above!
299 |
300 | * `host`: String (e. g. "localhost")
301 | * `port`: Number (e. g. 5000)
302 | * `user`: String (optional)
303 | * `password`: String (optional)
304 |
305 | ### Connection
306 |
307 | Is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter).
308 |
309 | #### k(s, [x, [y, [z, [...,] ] ] ] cb)
310 |
311 | Sync request/response.
312 |
313 | * `s`: String
314 | * `x`: Object (optional)
315 | * `y`: Object (optional)
316 | * `z`: Object (optional)
317 | * `...`: Object (optional)
318 | * `cb`: Function(`err`, `res`)
319 | * `err`: `Error` or `undefined`
320 | * `res`: `Object` or `undefined`
321 |
322 | #### ks(s, [x, [y, [z, [...,] ] ] ] cb)
323 |
324 | Async request.
325 |
326 | * `s`: String
327 | * `x`: Object (optional)
328 | * `y`: Object (optional)
329 | * `z`: Object (optional)
330 | * `...`: Object (optional)
331 | * `cb`: Function(`err`)
332 | * `err`: `Error` or `undefined`
333 |
334 | #### close(cb)
335 |
336 | * `cb`: Function(`err`) (optional)
337 | * `err`: `Error` or `undefined`
338 |
339 | #### Events
340 |
341 | ##### upd(table, data)
342 |
343 | If you use kdb+tick and subscribe like `con.ks(".u.sub[`;`]", function(err) { throw err; })` you will receive all Updates via `upd` Event.
344 |
345 | * `table`: String (e.g. trades)
346 | * `data`: Object (table represented in JavaScript as [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) of [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))
347 |
348 | ##### error(err)
349 |
350 | If the socket emit an `error` event.
351 |
352 | * `err`: `Error`
353 |
354 | ##### end()
355 |
356 | If the socket emit an `end` event.
357 |
358 | ##### timeout()
359 |
360 | If the socket emit a `timeout` event.
361 |
362 | ##### close(had_error)
363 |
364 | If the socket emit a `close` event.
365 |
366 | * `had_error`: Boolean (true if the socket had a transmission error)
367 |
368 | ## Contribution
369 |
370 | If you want to create a Pull-Request please make sure that `make test` runs without failures.
371 |
372 | If you have a kdb+tick setup please also run `make mochait`.
373 |
374 | ### Code Style
375 |
376 | make jshint
377 |
378 | ### Unit Tests
379 |
380 | make mocha
381 |
382 | ### Integration Test
383 |
384 | Assumes a running q process on port 5000 with kdb+tick available in QHOME (`QHOME=~/q ~/q/m32/q -p 5000`). For the tls tests you will also need a running q process on port 6000 set up to require tls. Instructions for this can be found [here](https://code.kx.com/q/kb/ssl/). If you are using a self signed certificate you will also need to set the `NODE_TLS_REJECT_UNAUTHORIZED` environment variable to `0`.
385 |
386 | make mochait
387 |
388 | ### Circular depdendencies
389 |
390 | make circular
391 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import * as events from 'events';
4 |
5 | /**
6 | * A standard node.js callback after an asynchronous call with no return value.
7 | * @param error - This parameter will be undefined if the call was successful, or an error if not.
8 | */
9 | export declare type AsyncCallback = (error: Error | undefined) => void;
10 |
11 | /**
12 | * A standard node.js callback after an asynchronous call with a return value.
13 | * @param error - This parameter will be undefined if the call was successful, or an error if not.
14 | * @param value - This parameter will be undefined if the call was not successful, or the return value if it was successful.
15 | */
16 | export declare type AsyncValueCallback = (error: Error | undefined, value: T | undefined) => void;
17 |
18 | /**
19 | * The events that can be raised by the Connection class and the event listener types.
20 | */
21 | export declare interface ConnectionEvents {
22 | /**
23 | * Raised when the connection is closed.
24 | * @param hadError - Whether or not it was closed due to an error.
25 | */
26 | close: (hadError: boolean) => void;
27 | /**
28 | * Raised when the connection is ended.
29 | */
30 | end: () => void;
31 | /**
32 | * Raised when an error is encountered.
33 | * @param error - The error encountered.
34 | */
35 | error: (error: Error) => void;
36 | /**
37 | * Raised when the connection times out.
38 | */
39 | timeout: () => void;
40 | /**
41 | * Raised by KDB as an update. Includes the table name and typically one more piece of data indicating the updates (though optionally more than one).
42 | */
43 | upd: (tableName: string, ...data: any[]) => void;
44 | }
45 |
46 | /**
47 | * Class representing the KDB connection.
48 | */
49 | export declare class Connection extends events.EventEmitter {
50 | /**
51 | * A private constructor is used to prevent inheritance.
52 | */
53 | private constructor();
54 | /**
55 | * Adds an event listener for events of the specified type.
56 | * @param type The event type.
57 | * @param listener The event listener to add.
58 | */
59 | addListener(type: T, listener: ConnectionEvents[T]): this;
60 | /**
61 | * Closes this connection.
62 | * @param callback Optional callback to be invoked when the close operation has finished.
63 | */
64 | close(callback?: () => void): void;
65 | /**
66 | * Listen to a handle.
67 | * @param callback The callback to be invoked when the results are available or an error is to be reported.
68 | */
69 | k(callback: AsyncValueCallback): void;
70 | /**
71 | * Execute a statement synchronously against KDB and return the result when available via the callback.
72 | * @param statement The statement to execute against KDB.
73 | * @param callback The callback to be invoked when the results are available or an error is to be reported.
74 | */
75 | k(statement: string, callback: AsyncValueCallback): void;
76 | /**
77 | * Execute a statement synchronously against KDB that takes a single parameter and return the result when available via the callback.
78 | * @param statement The statement to execute against KDB.
79 | * @param parameter The parameter to pass to KDB.
80 | * @param callback The callback to be invoked when the results are available or an error is to be reported.
81 | */
82 | k(statement: string, parameter: any, callback: AsyncValueCallback): void;
83 | /**
84 | * Execute a statement synchronously against KDB that takes an arbitrary number of parameters. The last element in the rest array must be an AsyncValueCallback.
85 | * @param statement The statement to execute against KDB.
86 | * @param parametersEndingInCallback The parameters to pass to KDB, with the last element being the callback to be invoked when the results are available or an error is to be reported.
87 | */
88 | k(statement: string, ...parametersEndingInCallback: any[]): void;
89 | /**
90 | * Execute a statement asynchronously against KDB with no return value, and return a callback indicating the message was received by KDB successfuly.
91 | * @param statement The statement to execute against KDB.
92 | * @param callback The callback to be invoked when the statement is received by KDB or an error is to be reported.
93 | */
94 | ks(statement: string, callback: AsyncCallback): void;
95 | /**
96 | * Execute a statement asynchronously against KDB with a single parameter and no return value, and return a callback indicating the message was received by KDB successfuly.
97 | * @param statement The statement to execute against KDB.
98 | * @param callback The callback to be invoked when the statement is received by KDB or an error is to be reported.
99 | */
100 | ks(statement: string, parameter: any, callback: AsyncCallback): void;
101 | /**
102 | * Execute a statement asynchronously against KDB that takes an arbitrary number of parameters and has no return value. The last element in the rest array must be an AsyncCallback.
103 | * @param statement The statement to execute against KDB.
104 | * @param parametersEndingInCallback The parameters to pass to KDB, with the last element being the callback to be invoked when the statement is received by KDB or an error is to be reported.
105 | */
106 | ks(statement: string, ...parametersEndingInCallback: any[]): void;
107 | /**
108 | * Gets the number of listeners for the specified event type.
109 | * @param type The event type.
110 | */
111 | listenerCount(type: keyof ConnectionEvents): number;
112 | /**
113 | * Gets the collection of listeners for the specified event type.
114 | * @param type The event type.
115 | */
116 | listeners(type: T): ConnectionEvents[T][];
117 | /**
118 | * Adds an event listener for events of the specified type.
119 | * @param type The event type.
120 | * @param listener The event listener to add.
121 | */
122 | on(type: T, listener: ConnectionEvents[T]): this;
123 | /**
124 | * Adds an event listener for only the next time an event of the specified type is invoked.
125 | * @param type The event type.
126 | * @param listener The event listener to add.
127 | */
128 | once(type: T, listener: ConnectionEvents[T]): this;
129 | /**
130 | * Adds an event listener for events of the specified type, but add it at the beginning of the collection of listeners for the event type.
131 | * @param type The event type.
132 | * @param listener The event listener to add.
133 | */
134 | prependListener(type: T, listener: ConnectionEvents[T]): this;
135 | /**
136 | * Adds an event listener for only the next time events of the specified type are raised, but add it at the beginning of the collection of listeners for the event type.
137 | * @param type The event type.
138 | * @param listener The event listener to add.
139 | */
140 | prependOnceListener(type: T, listener: ConnectionEvents[T]): this;
141 | /**
142 | * Removes all listeners from all events.
143 | */
144 | removeAllListeners(): this;
145 | /**
146 | * Removes all listeners from the specified event type.
147 | * @param type The event type.
148 | */
149 | removeAllListeners(type: keyof ConnectionEvents): this;
150 | /**
151 | * Removes the specified listener from the collection of listeners associated with the type.
152 | * @param type The event type.
153 | * @param listener The listener to remove.
154 | */
155 | removeListener(type: T, listener: ConnectionEvents[T]): this;
156 | }
157 |
158 | /**
159 | * Connection parameters.
160 | */
161 | export declare interface ConnectionParameters {
162 | /**
163 | * The KDB host to connect to.
164 | */
165 | host?: string;
166 | /**
167 | * The port on the KDB host to connect to.
168 | */
169 | port?: number;
170 | /**
171 | * Optional - The user to authenticate as to KDB.
172 | */
173 | user?: string;
174 | /**
175 | * Optional - The password to use to authenticate to KDB.
176 | */
177 | password?: string;
178 | /**
179 | * Set the socket to no-delay. See https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay
180 | */
181 | socketNoDelay?: boolean;
182 | /**
183 | * Sets the socket to timeout after the number of milliseconds of inactivity. See https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback
184 | */
185 | socketTimeout?: number;
186 | /**
187 | * Should this connection convert KDB nanoseconds to JavaScript Date objects (defaults to true).
188 | */
189 | nanos2date?: boolean;
190 | /**
191 | * Should this connection flip tables (defaults to true).
192 | */
193 | flipTables?: boolean;
194 | /**
195 | * Should this connection convert empty char fields to null (defaults to true).
196 | */
197 | emptyChar2null?: boolean;
198 | /**
199 | * Should this connection convert KDB longs to JavaScript Number types (defaults to true).
200 | * Specifying false will cause KDB longs to be returned using long.js.
201 | */
202 | long2number?: boolean;
203 | /**
204 | * Connect with Unix Domain Sockets rather than TCP
205 | */
206 | unixSocket?: string;
207 | /**
208 | * Should this connection use TLS
209 | */
210 | useTLS?: boolean;
211 | }
212 |
213 | /**
214 | * Attempt to connect to KDB using the specified connection parameters, and return the connection when it is established.
215 | * @param parameters The connection parameters.
216 | * @param callback Callback to be invoked when the connection is (or fails to be) established.
217 | */
218 | export declare function connect(parameters: ConnectionParameters, callback: AsyncValueCallback): void;
219 | /**
220 | * Attempt to connect to an unauthenticated KDB instance using the specified host and port, and return the connection when it is established.
221 | * @param host The KDB host to connect to.
222 | * @param port The port on the host to connect to.
223 | * @param callback Callback to be invoked when the connection is (or fails to be) established.
224 | */
225 | export declare function connect(host: string, port: number, callback: AsyncValueCallback): void;
226 | /**
227 | * Attempt to connect to a KDB instance using the specified host, port, username and password, and return the connection when it is established.
228 | * @param host The KDB host to connect to.
229 | * @param port The port on the host to connect to.
230 | * @param user The user to authenticate to KDB with.
231 | * @param password The password to use to authenticate to KDB.
232 | * @param callback Callback to be invoked when the connection is (or fails to be) established.
233 | */
234 | export declare function connect(host: string, port: number, user: string, password: string, callback: AsyncValueCallback): void;
235 | /**
236 | * Attempt to connect to KDB using Unix Domain Sockets, and return the connection when it is established.
237 | * @param unixSocket Path to KDB Unix Domain Socket (Doesn't support abstract namespace sockets: KDB3.5+ on Linux)
238 | * @param callback Callback to be invoked when the connection is (or fails to be) established.
239 | */
240 | export declare function connect(unixSocket: string, callback: AsyncValueCallback): void;
241 | /**
242 | * Brings in the Typed wrapper APIs.
243 | */
244 | export * from './lib/typed';
245 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var libc = require("./lib/c.js");
2 | var net = require("net");
3 | var tls = require("tls");
4 | var events = require("events");
5 | var util = require("util");
6 | var assert = require("./lib/assert.js");
7 | var typed = require("./lib/typed.js");
8 |
9 | function Connection(socket, nanos2date, flipTables, emptyChar2null, long2number) {
10 | "use strict";
11 | events.EventEmitter.call(this);
12 | this.socket = socket;
13 | this.nanos2date = nanos2date;
14 | this.flipTables = flipTables;
15 | this.emptyChar2null = emptyChar2null;
16 | this.long2number = long2number;
17 | this.nextRequestNo = 1;
18 | this.nextResponseNo = 1;
19 | var self = this;
20 | this.socket.on("end", function() {
21 | self.emit("end");
22 | });
23 | this.socket.on("timeout", function() {
24 | self.emit("timeout");
25 | });
26 | this.socket.on("error", function(err) {
27 | self.emit("error", err);
28 | });
29 | this.socket.on("close", function(had_error) {
30 | self.emit("close", had_error);
31 | });
32 | }
33 | util.inherits(Connection, events.EventEmitter);
34 | Connection.prototype.listen = function() {
35 | "use strict";
36 | var self = this;
37 | this.chunk = new Buffer(0);
38 | this.socket.on("data", function(inbuffer) {
39 | var buffer,
40 | length, // current msg length
41 | o, // deserialized object
42 | err, // deserialize error
43 | responseNo;
44 |
45 | if (self.chunk.length !== 0) {
46 | buffer = new Buffer(self.chunk.length + inbuffer.length);
47 | self.chunk.copy(buffer);
48 | inbuffer.copy(buffer, self.chunk.length);
49 | } else {
50 | buffer = inbuffer;
51 | }
52 | while (buffer.length >= 8) {
53 | length = buffer.readUInt32LE(4);
54 | if (buffer.length >= length) {
55 | try {
56 | o = libc.deserialize(buffer, self.nanos2date, self.flipTables, self.emptyChar2null, self.long2number);
57 | err = undefined;
58 | } catch (e) {
59 | o = null;
60 | err = e;
61 | }
62 | if (buffer.readUInt8(1) === 2) { // MsgType: 2 := response
63 | responseNo = self.nextResponseNo;
64 | self.nextResponseNo += 1;
65 | self.emit("response:" + responseNo, err, o);
66 | } else {
67 | if (err === undefined && Array.isArray(o) && o[0] === "upd") {
68 | events.EventEmitter.prototype.emit.apply(self, o);
69 | } else {
70 | responseNo = self.nextResponseNo;
71 | self.nextResponseNo += 1;
72 | self.emit("response:" + responseNo, err, o);
73 | }
74 | }
75 | if (buffer.length > length) {
76 | buffer = buffer.slice(length);
77 | } else {
78 | buffer = new Buffer(0);
79 | }
80 | } else {
81 | break;
82 | }
83 | }
84 |
85 | self.chunk = buffer;
86 | });
87 | };
88 | Connection.prototype.auth = function(auth, cb) {
89 | "use strict";
90 | var n = Buffer.byteLength(auth, "ascii"),
91 | b = new Buffer(n + 2),
92 | self = this;
93 | b.write(auth, 0, n, "ascii"); // auth (username:password)
94 | b.writeUInt8(0x3, n); // capability byte (compression, timestamp, timespan) http://code.kx.com/wiki/Reference/ipcprotocol#Handshake
95 | b.writeUInt8(0x0, n+1); // zero terminated
96 | this.socket.write(b);
97 | this.socket.once("data", function(buffer) {
98 | if (buffer.length === 1) {
99 | if (buffer[0] >= 1) { // capability byte must support at least (compression, timestamp, timespan) http://code.kx.com/wiki/Reference/ipcprotocol#Handshake
100 | self.listen();
101 | cb();
102 | } else {
103 | cb(new Error("Invalid capability byte from server"));
104 | }
105 | } else {
106 | cb(new Error("Invalid auth response from server"));
107 | }
108 | });
109 | };
110 | Connection.prototype.k = function(s, cb) {
111 | "use strict";
112 | cb = arguments[arguments.length - 1];
113 | assert.func(cb, "cb");
114 | var self = this,
115 | payload,
116 | b,
117 | requestNo = this.nextRequestNo;
118 | this.nextRequestNo += 1;
119 | if (arguments.length === 1) {
120 | // Listen for async responses
121 | self.once("response:" + requestNo, function(err, o) {
122 | cb(err, o);
123 | });
124 | } else {
125 | assert.string(s, "s");
126 | if (arguments.length === 2) {
127 | payload = s;
128 | } else {
129 | payload = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
130 | }
131 | b = libc.serialize(payload);
132 | b.writeUInt8(0x1, 1); // MsgType: 1 := sync
133 | this.socket.write(b, function() {
134 | self.once("response:" + requestNo, function(err, o) {
135 | cb(err, o);
136 | });
137 | });
138 | }
139 | };
140 | Connection.prototype.ks = function(s, cb) {
141 | "use strict";
142 | assert.string(s, "s");
143 | cb = arguments[arguments.length - 1];
144 | assert.func(cb, "cb");
145 | var payload,
146 | b;
147 | if (arguments.length === 2) {
148 | payload = s;
149 | } else {
150 | payload = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
151 | }
152 | b = libc.serialize(payload);
153 | this.socket.write(b, function() {
154 | cb();
155 | });
156 | };
157 | Connection.prototype.close = function(cb) {
158 | "use strict";
159 | assert.optionalFunc(cb, "cb");
160 | this.socket.once("close", function() {
161 | if (cb) {
162 | cb();
163 | }
164 | });
165 | this.socket.end();
166 | };
167 |
168 | function connect(params, cb) {
169 | "use strict";
170 | var auth,
171 | errorcb,
172 | closecb,
173 | socket,
174 | error = false,
175 | close = false;
176 | if (typeof params !== "object") {
177 | params = {};
178 | if (arguments.length === 2) {
179 | params.unixSocket = arguments[0];
180 | cb = arguments[1];
181 | } else if (arguments.length === 3) {
182 | params.host = arguments[0];
183 | params.port = arguments[1];
184 | cb = arguments[2];
185 | } else if (arguments.length === 5) {
186 | params.host = arguments[0];
187 | params.port = arguments[1];
188 | params.user = arguments[2];
189 | params.password = arguments[3];
190 | cb = arguments[4];
191 | } else {
192 | throw new Error("only two, three or five arguments allowed");
193 | }
194 | }
195 | assert.object(params, "params");
196 | assert.optionalString(params.host, "params.host");
197 | assert.optionalNumber(params.port, "params.port");
198 | assert.optionalString(params.user, "params.user");
199 | assert.optionalString(params.password, "password");
200 | assert.optionalObject(params.ca, "params.ca");
201 | assert.optionalBool(params.socketNoDelay, "params.socketNoDelay");
202 | assert.optionalNumber(params.socketTimeout, "params.socketTimeout");
203 | assert.optionalBool(params.nanos2date, "params.nanos2date");
204 | assert.optionalBool(params.flipTables, "params.flipTables");
205 | assert.optionalBool(params.emptyChar2null, "params.emptyChar2null");
206 | assert.optionalBool(params.long2number, "params.long2number");
207 | assert.optionalString(params.unixSocket, "params.unixSocket");
208 | assert.optionalBool(params.useTLS, "params.useTLS");
209 | if (params.user !== undefined) {
210 | assert.string(params.password, "password");
211 | auth = params.user + ":" + params.password;
212 | } else {
213 | auth = "anonymous";
214 | }
215 | assert.func(cb, "cb");
216 | errorcb = function(err) {
217 | error = true;
218 | cb(err);
219 | };
220 | closecb = function() {
221 | close = true;
222 | cb(new Error("Connection closes (wrong auth?)"));
223 | };
224 |
225 | var socketArgs;
226 | if (params.useTLS) {
227 | socketArgs = {};
228 | if (params.unixSocket) {
229 | socketArgs.path = params.unixSocket;
230 | } else {
231 | socketArgs.port = params.port;
232 | socketArgs.host = params.host;
233 | socketArgs.ca = params.ca;
234 | }
235 | } else {
236 | socketArgs = [];
237 | if (params.unixSocket) {
238 | socketArgs.push(params.unixSocket);
239 | }
240 | else {
241 | socketArgs.push(params.port, params.host);
242 | }
243 | }
244 | var connectionCBfunc = function() {
245 | socket.removeListener("error", errorcb);
246 | if (error === false) {
247 | socket.once("close", closecb);
248 | var con = new Connection(socket, params.nanos2date, params.flipTables, params.emptyChar2null, params.long2number);
249 | con.once("error", function(err) {
250 | socket.removeListener("close", closecb);
251 | cb(err);
252 | });
253 | con.auth(auth, function() {
254 | socket.removeListener("close", closecb);
255 | if (close === false) {
256 | cb(undefined, con);
257 | }
258 | });
259 | }
260 | };
261 |
262 | if (params.useTLS) {
263 | socket = tls.connect(socketArgs, connectionCBfunc);
264 | } else {
265 | socketArgs.push(connectionCBfunc);
266 | socket = net.connect.apply(null, socketArgs);
267 | }
268 |
269 | if (params.socketTimeout !== undefined) {
270 | socket.setTimeout(params.socketTimeout);
271 | }
272 | if (params.socketNoDelay !== undefined) {
273 | socket.setNoDelay(params.socketNoDelay);
274 | }
275 | socket.once("error", errorcb);
276 | }
277 | exports.connect = connect;
278 |
279 | // export typed API
280 | Object.keys(typed).forEach(function(k) {
281 | "use strict";
282 | if (/^[a-z]*$/.test(k[0])) {
283 | exports[k] = typed[k];
284 | }
285 | });
286 |
--------------------------------------------------------------------------------
/itest/asyncreq.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js");
2 |
3 | describe("asyncreq", function() {
4 | "use strict";
5 | var con;
6 | before(function(done) {
7 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
8 | if (err) { throw err; }
9 | con = c;
10 | done();
11 | });
12 | });
13 | after(function(done) {
14 | con.close(function() {
15 | con = undefined;
16 | done();
17 | });
18 | });
19 | it("execute q", function(done) {
20 | con.ks("show 1 2 3", function(err) {
21 | if (err) { throw err; }
22 | done();
23 | });
24 | });
25 | it("execute function with one parameter", function(done) {
26 | con.k("show", [1, 2, 3], function(err) {
27 | if (err) { throw err; }
28 | done();
29 | });
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/itest/compression.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert"),
3 | os = require("os");
4 |
5 | describe("compression", function() {
6 | "use strict";
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: os.hostname(), port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | it("uncompress result", function(done) {
22 | con.k("til 1000000", function(err, res) {
23 | if (err) { throw err; }
24 | assert.equal(res.length, 1000000, "res.length");
25 | done();
26 | });
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/itest/connect.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js");
2 |
3 | describe("connect", function() {
4 | "use strict";
5 | describe("old API", function() {
6 | it("should work if enpoint is available", function(done) {
7 | nodeq.connect("localhost", 5000, function(err) {
8 | if (err) { throw err; }
9 | done();
10 | });
11 | });
12 | });
13 | describe("new API", function() {
14 | it("should work if enpoint is available", function(done) {
15 | nodeq.connect({host: "localhost", port: 5000}, function(err) {
16 | if (err) { throw err; }
17 | done();
18 | });
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/itest/deserialization.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("deserialization", function() {
5 | "use strict";
6 | var con;
7 | before(function(done) {
8 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
9 | if (err) { throw err; }
10 | con = c;
11 | done();
12 | });
13 | });
14 | after(function(done) {
15 | con.close(function() {
16 | con = undefined;
17 | done();
18 | });
19 | });
20 | describe("boolean", function() {
21 | it("true", function(done) {
22 | con.k("1b", function(err, res) {
23 | if (err) { throw err; }
24 | assert.equal(res, true, "res");
25 | done();
26 | });
27 | });
28 | it("false", function(done) {
29 | con.k("0b", function(err, res) {
30 | if (err) { throw err; }
31 | assert.equal(res, false, "res");
32 | done();
33 | });
34 | });
35 | });
36 | describe("guid", function() {
37 | it("null", function(done) {
38 | con.k("0Ng", function(err, res) {
39 | if (err) { throw err; }
40 | assert.equal(res, null, "res");
41 | done();
42 | });
43 | });
44 | it("random", function(done) {
45 | con.k("rand 0Ng", function(err, res) {
46 | if (err) { throw err; }
47 | assert.equal(typeof res, "string", "res");
48 | done();
49 | });
50 | });
51 | });
52 | describe("byte", function() {
53 | it("255", function(done) {
54 | con.k("0xff", function(err, res) {
55 | if (err) { throw err; }
56 | assert.equal(res, 255, "res");
57 | done();
58 | });
59 | });
60 | it("1", function(done) {
61 | con.k("0x01", function(err, res) {
62 | if (err) { throw err; }
63 | assert.equal(res, 1, "res");
64 | done();
65 | });
66 | });
67 | it("0", function(done) {
68 | con.k("0x00", function(err, res) {
69 | if (err) { throw err; }
70 | assert.equal(res, 0, "res");
71 | done();
72 | });
73 | });
74 | });
75 | describe("short", function() {
76 | it("null", function(done) {
77 | con.k("0Nh", function(err, res) {
78 | if (err) { throw err; }
79 | assert.equal(res, null, "res");
80 | done();
81 | });
82 | });
83 | it("+infinity", function(done) {
84 | con.k("0Wh", function(err, res) {
85 | if (err) { throw err; }
86 | assert.equal(res, Infinity, "res");
87 | done();
88 | });
89 | });
90 | it("-infinity", function(done) {
91 | con.k("-0Wh", function(err, res) {
92 | if (err) { throw err; }
93 | assert.equal(res, -Infinity, "res");
94 | done();
95 | });
96 | });
97 | it("1", function(done) {
98 | con.k("1h", function(err, res) {
99 | if (err) { throw err; }
100 | assert.equal(res, 1, "res");
101 | done();
102 | });
103 | });
104 | it("0", function(done) {
105 | con.k("0h", function(err, res) {
106 | if (err) { throw err; }
107 | assert.equal(res, 0, "res");
108 | done();
109 | });
110 | });
111 | it("-1", function(done) {
112 | con.k("-1h", function(err, res) {
113 | if (err) { throw err; }
114 | assert.equal(res, -1, "res");
115 | done();
116 | });
117 | });
118 | });
119 | describe("int", function() {
120 | it("null", function(done) {
121 | con.k("0Ni", function(err, res) {
122 | if (err) { throw err; }
123 | assert.equal(res, null, "res");
124 | done();
125 | });
126 | });
127 | it("+infinity", function(done) {
128 | con.k("0Wi", function(err, res) {
129 | if (err) { throw err; }
130 | assert.equal(res, Infinity, "res");
131 | done();
132 | });
133 | });
134 | it("-infinity", function(done) {
135 | con.k("-0Wi", function(err, res) {
136 | if (err) { throw err; }
137 | assert.equal(res, -Infinity, "res");
138 | done();
139 | });
140 | });
141 | it("1", function(done) {
142 | con.k("1i", function(err, res) {
143 | if (err) { throw err; }
144 | assert.equal(res, 1, "res");
145 | done();
146 | });
147 | });
148 | it("0", function(done) {
149 | con.k("0i", function(err, res) {
150 | if (err) { throw err; }
151 | assert.equal(res, 0, "res");
152 | done();
153 | });
154 | });
155 | it("-1", function(done) {
156 | con.k("-1i", function(err, res) {
157 | if (err) { throw err; }
158 | assert.equal(res, -1, "res");
159 | done();
160 | });
161 | });
162 | });
163 | describe("long", function() {
164 | it("null", function(done) {
165 | con.k("0Nj", function(err, res) {
166 | if (err) { throw err; }
167 | assert.equal(res, null, "res");
168 | done();
169 | });
170 | });
171 | it("+infinity", function(done) {
172 | con.k("0Wj", function(err, res) {
173 | if (err) { throw err; }
174 | assert.equal(res, Infinity, "res");
175 | done();
176 | });
177 | });
178 | it("-infinity", function(done) {
179 | con.k("-0Wj", function(err, res) {
180 | if (err) { throw err; }
181 | assert.equal(res, -Infinity, "res");
182 | done();
183 | });
184 | });
185 | it("1", function(done) {
186 | con.k("1j", function(err, res) {
187 | if (err) { throw err; }
188 | assert.equal(res, 1, "res");
189 | done();
190 | });
191 | });
192 | it("0", function(done) {
193 | con.k("0j", function(err, res) {
194 | if (err) { throw err; }
195 | assert.equal(res, 0, "res");
196 | done();
197 | });
198 | });
199 | it("-1", function(done) {
200 | con.k("-1j", function(err, res) {
201 | if (err) { throw err; }
202 | assert.equal(res, -1, "res");
203 | done();
204 | });
205 | });
206 | });
207 | describe("real", function() {
208 | it("null", function(done) {
209 | con.k("0Ne", function(err, res) {
210 | if (err) { throw err; }
211 | assert.equal(res, null, "res");
212 | done();
213 | });
214 | });
215 | it("+infinity", function(done) {
216 | con.k("0We", function(err, res) {
217 | if (err) { throw err; }
218 | assert.equal(res, Infinity, "res");
219 | done();
220 | });
221 | });
222 | it("-infinity", function(done) {
223 | con.k("-0We", function(err, res) {
224 | if (err) { throw err; }
225 | assert.equal(res, -Infinity, "res");
226 | done();
227 | });
228 | });
229 | it("1", function(done) {
230 | con.k("1.0e", function(err, res) {
231 | if (err) { throw err; }
232 | assert.equal(res, 1, "res");
233 | done();
234 | });
235 | });
236 | it("0", function(done) {
237 | con.k("0e", function(err, res) {
238 | if (err) { throw err; }
239 | assert.equal(res, 0, "res");
240 | done();
241 | });
242 | });
243 | it("-1", function(done) {
244 | con.k("-1e", function(err, res) {
245 | if (err) { throw err; }
246 | assert.equal(res, -1, "res");
247 | done();
248 | });
249 | });
250 | });
251 | describe("float", function() {
252 | it("null", function(done) {
253 | con.k("0Nf", function(err, res) {
254 | if (err) { throw err; }
255 | assert.equal(res, null, "res");
256 | done();
257 | });
258 | });
259 | it("+infinity", function(done) {
260 | con.k("0Wf", function(err, res) {
261 | if (err) { throw err; }
262 | assert.equal(res, Infinity, "res");
263 | done();
264 | });
265 | });
266 | it("-infinity", function(done) {
267 | con.k("-0Wf", function(err, res) {
268 | if (err) { throw err; }
269 | assert.equal(res, -Infinity, "res");
270 | done();
271 | });
272 | });
273 | it("1", function(done) {
274 | con.k("1f", function(err, res) {
275 | if (err) { throw err; }
276 | assert.equal(res, 1, "res");
277 | done();
278 | });
279 | });
280 | it("0", function(done) {
281 | con.k("0f", function(err, res) {
282 | if (err) { throw err; }
283 | assert.equal(res, 0, "res");
284 | done();
285 | });
286 | });
287 | it("-1", function(done) {
288 | con.k("-1f", function(err, res) {
289 | if (err) { throw err; }
290 | assert.equal(res, -1, "res");
291 | done();
292 | });
293 | });
294 | });
295 | describe("char", function() {
296 | it("null", function(done) {
297 | con.k('" "', function(err, res) {
298 | if (err) { throw err; }
299 | assert.equal(res, null, "res");
300 | done();
301 | });
302 | });
303 | it("a", function(done) {
304 | con.k('"a"', function(err, res) {
305 | if (err) { throw err; }
306 | assert.equal(res, "a", "res");
307 | done();
308 | });
309 | });
310 | });
311 | describe("symbol", function() {
312 | it("null", function(done) {
313 | con.k("s: `; s", function(err, res) {
314 | if (err) { throw err; }
315 | assert.equal(res, null, "res");
316 | done();
317 | });
318 | });
319 | it("`a", function(done) {
320 | con.k("s: `a; s", function(err, res) {
321 | if (err) { throw err; }
322 | assert.equal(res, "a", "res");
323 | done();
324 | });
325 | });
326 | it("`abc", function(done) {
327 | con.k("s: `abc; s", function(err, res) {
328 | if (err) { throw err; }
329 | assert.equal(res, "abc", "res");
330 | done();
331 | });
332 | });
333 | });
334 | describe("timestamp", function() {
335 | it("null", function(done) {
336 | con.k("0Np", function(err, res) {
337 | if (err) { throw err; }
338 | assert.equal(res, null, "res");
339 | done();
340 | });
341 | });
342 | it("2015.01.01D00:00:00.000000000", function(done) {
343 | con.k("2015.01.01D00:00:00.000000000", function(err, res) {
344 | if (err) { throw err; }
345 | assert.equal(res.getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res");
346 | done();
347 | });
348 | });
349 | it("1995.01.01D00:00:00.000000000", function(done) {
350 | con.k("1995.01.01D00:00:00.000000000", function(err, res) {
351 | if (err) { throw err; }
352 | assert.equal(res.getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res");
353 | done();
354 | });
355 | });
356 | });
357 | describe("month", function() {
358 | it("null", function(done) {
359 | con.k("0Nm", function(err, res) {
360 | if (err) { throw err; }
361 | assert.equal(res, null, "res");
362 | done();
363 | });
364 | });
365 | it("2015.01", function(done) {
366 | con.k("2015.01m", function(err, res) {
367 | if (err) { throw err; }
368 | assert.equal(res.getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res");
369 | done();
370 | });
371 | });
372 | it("1995.01", function(done) {
373 | con.k("1995.01m", function(err, res) {
374 | if (err) { throw err; }
375 | assert.equal(res.getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res");
376 | done();
377 | });
378 | });
379 | });
380 | describe("date", function() {
381 | it("null", function(done) {
382 | con.k("0Nd", function(err, res) {
383 | if (err) { throw err; }
384 | assert.equal(res, null, "res");
385 | done();
386 | });
387 | });
388 | it("2015.01.01", function(done) {
389 | con.k("2015.01.01", function(err, res) {
390 | if (err) { throw err; }
391 | assert.equal(res.getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res");
392 | done();
393 | });
394 | });
395 | it("1995.01.01", function(done) {
396 | con.k("1995.01.01", function(err, res) {
397 | if (err) { throw err; }
398 | assert.equal(res.getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res");
399 | done();
400 | });
401 | });
402 | });
403 | describe("datetime", function() {
404 | it("null", function(done) {
405 | con.k("0Nz", function(err, res) {
406 | if (err) { throw err; }
407 | assert.equal(res, null, "res");
408 | done();
409 | });
410 | });
411 | it("2015.01.01T00:00:00.000", function(done) {
412 | con.k("2015.01.01T00:00:00.000", function(err, res) {
413 | if (err) { throw err; }
414 | assert.equal(res.getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res");
415 | done();
416 | });
417 | });
418 | it("1995.01.01T00:00:00.000", function(done) {
419 | con.k("1995.01.01T00:00:00.000", function(err, res) {
420 | if (err) { throw err; }
421 | assert.equal(res.getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res");
422 | done();
423 | });
424 | });
425 | });
426 | describe("timespan", function() {
427 | it("null", function(done) {
428 | con.k("0Nn", function(err, res) {
429 | if (err) { throw err; }
430 | assert.equal(res, null, "res");
431 | done();
432 | });
433 | });
434 | it("0D00:00:00.000000000", function(done) {
435 | con.k("0D00:00:00.000000000", function(err, res) {
436 | if (err) { throw err; }
437 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
438 | done();
439 | });
440 | });
441 | it("0D00:00:00.000000000", function(done) {
442 | con.k("0D00:00:00.000000000", function(err, res) {
443 | if (err) { throw err; }
444 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
445 | done();
446 | });
447 | });
448 | });
449 | describe("minute", function() {
450 | it("null", function(done) {
451 | con.k("0Nu", function(err, res) {
452 | if (err) { throw err; }
453 | assert.equal(res, null, "res");
454 | done();
455 | });
456 | });
457 | it("00:00", function(done) {
458 | con.k("00:00", function(err, res) {
459 | if (err) { throw err; }
460 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
461 | done();
462 | });
463 | });
464 | it("00:01", function(done) {
465 | con.k("00:01", function(err, res) {
466 | if (err) { throw err; }
467 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 1, 0, 0).getTime(), "res");
468 | done();
469 | });
470 | });
471 | });
472 | describe("second", function() {
473 | it("null", function(done) {
474 | con.k("0Nv", function(err, res) {
475 | if (err) { throw err; }
476 | assert.equal(res, null, "res");
477 | done();
478 | });
479 | });
480 | it("00:00:00", function(done) {
481 | con.k("00:00:00", function(err, res) {
482 | if (err) { throw err; }
483 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
484 | done();
485 | });
486 | });
487 | it("00:00:01", function(done) {
488 | con.k("00:00:01", function(err, res) {
489 | if (err) { throw err; }
490 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 1, 0).getTime(), "res");
491 | done();
492 | });
493 | });
494 | });
495 | describe("time", function() {
496 | it("null", function(done) {
497 | con.k("0Nt", function(err, res) {
498 | if (err) { throw err; }
499 | assert.equal(res, null, "res");
500 | done();
501 | });
502 | });
503 | it("00:00:00.000", function(done) {
504 | con.k("00:00:00.000", function(err, res) {
505 | if (err) { throw err; }
506 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
507 | done();
508 | });
509 | });
510 | it("00:00:01", function(done) {
511 | con.k("00:00:00.001", function(err, res) {
512 | if (err) { throw err; }
513 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 1).getTime(), "res");
514 | done();
515 | });
516 | });
517 | });
518 | describe("dict", function() {
519 | it("empty", function(done) {
520 | con.k("()!()", function(err, res) {
521 | if (err) { throw err; }
522 | assert.deepEqual(res, {}, "res");
523 | done();
524 | });
525 | });
526 | it("single", function(done) {
527 | con.k("(enlist `a)!(enlist 1i)", function(err, res) {
528 | if (err) { throw err; }
529 | assert.deepEqual(res, {a: 1}, "res");
530 | done();
531 | });
532 | });
533 | it("multi", function(done) {
534 | con.k("(`a`b`c)!(1 2 3i)", function(err, res) {
535 | if (err) { throw err; }
536 | assert.deepEqual(res, {a: 1, b: 2, c: 3}, "res");
537 | done();
538 | });
539 | });
540 | });
541 | describe("list", function() {
542 | it("empty", function(done) {
543 | con.k("()", function(err, res) {
544 | if (err) { throw err; }
545 | assert.deepEqual(res, [], "res");
546 | done();
547 | });
548 | });
549 | it("single", function(done) {
550 | con.k("enlist 1i", function(err, res) {
551 | if (err) { throw err; }
552 | assert.deepEqual(res, [1], "res");
553 | done();
554 | });
555 | });
556 | it("multi", function(done) {
557 | con.k("1 2 3i", function(err, res) {
558 | if (err) { throw err; }
559 | assert.deepEqual(res, [1, 2, 3], "res");
560 | done();
561 | });
562 | });
563 | });
564 | describe("table", function() {
565 | it("empty", function(done) {
566 | con.k("([] sym:`int$(); size:`$())", function(err, res) {
567 | if (err) { throw err; }
568 | assert.deepEqual(res, [], "res");
569 | done();
570 | });
571 | });
572 | it("single", function(done) {
573 | con.k("([] sym:enlist `a; size:enlist 1i)", function(err, res) {
574 | if (err) { throw err; }
575 | assert.deepEqual(res, [{sym: "a", size: 1}], "res");
576 | done();
577 | });
578 | });
579 | it("multi", function(done) {
580 | con.k("([] sym:`a`b`c; size:(1 2 3i))", function(err, res) {
581 | if (err) { throw err; }
582 | assert.deepEqual(res, [{sym: "a", size: 1}, {sym: "b", size: 2}, {sym: "c", size: 3}], "res");
583 | done();
584 | });
585 | });
586 | });
587 | });
588 |
--------------------------------------------------------------------------------
/itest/emptyChar2null.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("emptyChar2null", function() {
5 | "use strict";
6 | describe("default", function() {
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | it("null", function(done) {
22 | con.k('" "', function(err, res) {
23 | if (err) { throw err; }
24 | assert.equal(res, null, "res");
25 | done();
26 | });
27 | });
28 | });
29 | describe("true", function() {
30 | var con;
31 | before(function(done) {
32 | nodeq.connect({host: "localhost", port: 5000, emptyChar2null: true}, function(err, c) {
33 | if (err) { throw err; }
34 | con = c;
35 | done();
36 | });
37 | });
38 | after(function(done) {
39 | con.close(function() {
40 | con = undefined;
41 | done();
42 | });
43 | });
44 | it("null", function(done) {
45 | con.k('" "', function(err, res) {
46 | if (err) { throw err; }
47 | assert.equal(res, null, "res");
48 | done();
49 | });
50 | });
51 | });
52 | describe("false", function() {
53 | var con;
54 | before(function(done) {
55 | nodeq.connect({host: "localhost", port: 5000, emptyChar2null: false}, function(err, c) {
56 | if (err) { throw err; }
57 | con = c;
58 | done();
59 | });
60 | });
61 | after(function(done) {
62 | con.close(function() {
63 | con = undefined;
64 | done();
65 | });
66 | });
67 | it("null", function(done) {
68 | con.k('" "', function(err, res) {
69 | if (err) { throw err; }
70 | assert.equal(res, " ", "res");
71 | done();
72 | });
73 | });
74 | });
75 | });
76 |
--------------------------------------------------------------------------------
/itest/flipTables.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("flipTables", function() {
5 | "use strict";
6 | describe("default", function() {
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | it("empty", function(done) {
22 | con.k("([] sym:`int$(); size:`$())", function(err, res) {
23 | if (err) { throw err; }
24 | assert.deepEqual(res, [], "res");
25 | done();
26 | });
27 | });
28 | it("single", function(done) {
29 | con.k("([] sym:enlist `a; size:enlist 1i)", function(err, res) {
30 | if (err) { throw err; }
31 | assert.deepEqual(res, [{sym: "a", size: 1}], "res");
32 | done();
33 | });
34 | });
35 | it("multi", function(done) {
36 | con.k("([] sym:`a`b`c; size:(1 2 3i))", function(err, res) {
37 | if (err) { throw err; }
38 | assert.deepEqual(res, [{sym: "a", size: 1}, {sym: "b", size: 2}, {sym: "c", size: 3}], "res");
39 | done();
40 | });
41 | });
42 | });
43 | describe("true", function() {
44 | var con;
45 | before(function(done) {
46 | nodeq.connect({host: "localhost", port: 5000, flipTables: true}, function(err, c) {
47 | if (err) { throw err; }
48 | con = c;
49 | done();
50 | });
51 | });
52 | after(function(done) {
53 | con.close(function() {
54 | con = undefined;
55 | done();
56 | });
57 | });
58 | it("empty", function(done) {
59 | con.k("([] sym:`int$(); size:`$())", function(err, res) {
60 | if (err) { throw err; }
61 | assert.deepEqual(res, [], "res");
62 | done();
63 | });
64 | });
65 | it("single", function(done) {
66 | con.k("([] sym:enlist `a; size:enlist 1i)", function(err, res) {
67 | if (err) { throw err; }
68 | assert.deepEqual(res, [{sym: "a", size: 1}], "res");
69 | done();
70 | });
71 | });
72 | it("multi", function(done) {
73 | con.k("([] sym:`a`b`c; size:(1 2 3i))", function(err, res) {
74 | if (err) { throw err; }
75 | assert.deepEqual(res, [{sym: "a", size: 1}, {sym: "b", size: 2}, {sym: "c", size: 3}], "res");
76 | done();
77 | });
78 | });
79 | });
80 | describe("false", function() {
81 | var con;
82 | before(function(done) {
83 | nodeq.connect({host: "localhost", port: 5000, flipTables: false}, function(err, c) {
84 | if (err) { throw err; }
85 | con = c;
86 | done();
87 | });
88 | });
89 | after(function(done) {
90 | con.close(function() {
91 | con = undefined;
92 | done();
93 | });
94 | });
95 | it("empty", function(done) {
96 | con.k("([] sym:`int$(); size:`$())", function(err, res) {
97 | if (err) { throw err; }
98 | assert.deepEqual(res, {sym: [], size: []}, "res");
99 | done();
100 | });
101 | });
102 | it("single", function(done) {
103 | con.k("([] sym:enlist `a; size:enlist 1i)", function(err, res) {
104 | if (err) { throw err; }
105 | assert.deepEqual(res, {sym: ["a"], size: [1]}, "res");
106 | done();
107 | });
108 | });
109 | it("multi", function(done) {
110 | con.k("([] sym:`a`b`c; size:(1 2 3i))", function(err, res) {
111 | if (err) { throw err; }
112 | assert.deepEqual(res, {sym: ["a", "b", "c"], size: [1, 2, 3]}, "res");
113 | done();
114 | });
115 | });
116 | });
117 | });
118 |
--------------------------------------------------------------------------------
/itest/issue18.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | async = require("async"),
3 | assert = require("assert");
4 |
5 | describe("issue 18", function() {
6 | "use strict";
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | async.each([
12 | "numtests:100; timerange:10D; freq:0D00:05",
13 | "testid:(til numtests)!000000999999+numtests?20",
14 | "fcn:numtests*fc:`long$timerange%freq",
15 | "tests:([]time:(-0D00:00:10 + fcn?0D00:00:20)+fcn#(.z.p - timerange)+freq*til fc; test:raze fc#'key testid; testin:fcn?16741128383987; testout:fcn?16741128383987)"
16 | ], function(q, cb) {
17 | c.k(q, cb);
18 | }, function(err) {
19 | if (err) { throw err; }
20 | con = c;
21 | done();
22 | });
23 | });
24 | });
25 | after(function(done) {
26 | con.close(function() {
27 | con = undefined;
28 | done();
29 | });
30 | });
31 | it("keyed table", function(done) {
32 | con.k("select min testin by test from tests", function(err, res) {
33 | if (err) { throw err; }
34 | assert.equal(res[0].length, 100, "res[0].length");
35 | assert.equal(res[1].length, 100, "res[1].length");
36 | done();
37 | });
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/itest/nanos2date.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("nanos2date", function() {
5 | "use strict";
6 | describe("default", function() {
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | it("timestamp", function(done) {
22 | con.k("2011.10.10D14:48:00.000000000", function(err, res) {
23 | if (err) { throw err; }
24 | assert.equal(res.getTime(), 1318258080000, "res");
25 | done();
26 | });
27 | });
28 | });
29 | describe("true", function() {
30 | var con;
31 | before(function(done) {
32 | nodeq.connect({host: "localhost", port: 5000, nanos2date: true}, function(err, c) {
33 | if (err) { throw err; }
34 | con = c;
35 | done();
36 | });
37 | });
38 | after(function(done) {
39 | con.close(function() {
40 | con = undefined;
41 | done();
42 | });
43 | });
44 | it("timestamp", function(done) {
45 | con.k("2011.10.10D14:48:00.000000000", function(err, res) {
46 | if (err) { throw err; }
47 | assert.equal(res.getTime(), 1318258080000, "res");
48 | done();
49 | });
50 | });
51 | });
52 | describe("false", function() {
53 | var con;
54 | before(function(done) {
55 | nodeq.connect({host: "localhost", port: 5000, nanos2date: false}, function(err, c) {
56 | if (err) { throw err; }
57 | con = c;
58 | done();
59 | });
60 | });
61 | after(function(done) {
62 | con.close(function() {
63 | con = undefined;
64 | done();
65 | });
66 | });
67 | it("timestamp", function(done) {
68 | con.k("2011.10.10D14:48:00.000000000", function(err, res) {
69 | if (err) { throw err; }
70 | assert.equal(res, 1318258080000000000, "res");
71 | done();
72 | });
73 | });
74 | it("timespan 1 nano", function(done) {
75 | con.k("0D00:00:00.000000001", function(err, res) {
76 | if (err) { throw err; }
77 | assert.equal(res, 1, "res");
78 | done();
79 | });
80 | });
81 | it("timespan 1 day", function(done) {
82 | con.k("1D00:00:00.000000000", function(err, res) {
83 | if (err) { throw err; }
84 | assert.equal(res, 24 * 60 * 60 * 1000 * 1000 * 1000, "res");
85 | done();
86 | });
87 | });
88 | });
89 | });
90 |
--------------------------------------------------------------------------------
/itest/readme.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | async = require("async"),
3 | assert = require("assert");
4 |
5 | describe("readme", function() {
6 | "use strict";
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) {
11 | done(err);
12 | } else {
13 | async.each([
14 | 'system "l tick/u.q"',
15 | "trade: ([] sym:`$(); time:`timestamp$())",
16 | ".u.init[]",
17 | ".z.ts: {[] trade::0#trade; trade,::(`a;.z.p); .u.pub[`trade;trade]}",
18 | 'system "t 500"'
19 | ], function(q, cb) {
20 | c.k(q, cb);
21 | }, function(err) {
22 | if (err) { throw err; }
23 | con = c;
24 | done();
25 | });
26 | }
27 | });
28 | });
29 | after(function(done) {
30 | con.close(done);
31 | });
32 | it("Execute Q code and receive result", function(done) {
33 | con.k("sum 1 2 3", function(err, res) {
34 | if (err) {
35 | done(err);
36 | } else {
37 | assert.equal(res, 6);
38 | done();
39 | }
40 | });
41 | });
42 | it("Execute function with one parameter and receive result", function(done) {
43 | con.k("sum", [1, 2, 3], function(err, res) {
44 | if (err) {
45 | done(err);
46 | } else {
47 | assert.equal(res, 6);
48 | done();
49 | }
50 | });
51 | });
52 | it("Execute function with two parameters and receive result", function(done) {
53 | con.k("cor", [1, 2, 3], [4, 5, 6], function(err, res) {
54 | if (err) {
55 | done(err);
56 | } else {
57 | assert.equal(res, 1);
58 | done();
59 | }
60 | });
61 | });
62 | it("Async execute Q code", function(done) {
63 | con.ks("show 1 2 3", done);
64 | });
65 | it("Async execute function with parameters", function(done) {
66 | con.ks("show", [1, 2, 3], done);
67 | });
68 | it("Async execute and get async response", function(done) {
69 | con.ks("show 1;neg[.z.w][33]", function(err) {
70 | if (err) {
71 | throw err;
72 | }
73 | });
74 | con.k(function(err, res) {
75 | if (err) {
76 | done(err);
77 | } else {
78 | assert.equal(res, 33);
79 | done();
80 | }
81 | });
82 | });
83 | it("Subscribe to kdb+tick", function(done) {
84 | con.once("upd", function(table, data) {
85 | assert.equal(table, "trade");
86 | assert.equal(data[0].sym, "a");
87 | done();
88 | });
89 | con.ks(".u.sub[`;`]", function(err) {
90 | if (err) {
91 | done(err);
92 | }
93 | });
94 | });
95 | describe("typed", function() {
96 | it("short", function(done) {
97 | con.k("type", nodeq.short(1), function(err, res) {
98 | if (err) {
99 | done(err);
100 | } else {
101 | assert.equal(res, -5);
102 | done();
103 | }
104 | });
105 | });
106 | it("shorts", function(done) {
107 | con.k("type", nodeq.shorts([1, 2, 3]), function(err, res) {
108 | if (err) {
109 | done(err);
110 | } else {
111 | assert.equal(res, 5);
112 | done();
113 | }
114 | });
115 | });
116 | });
117 | });
118 |
--------------------------------------------------------------------------------
/itest/serialization.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("deserialization", function() {
5 | "use strict";
6 | var con;
7 | before(function(done) {
8 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
9 | if (err) { throw err; }
10 | con = c;
11 | c.k("testType: {type x};", function(err, res) {
12 | if (err) { throw err; }
13 | c.k("testValue: {x};", function(err, res) {
14 | if (err) { throw err; }
15 | done();
16 | });
17 | });
18 | });
19 | });
20 | after(function(done) {
21 | con.close(function() {
22 | con = undefined;
23 | done();
24 | });
25 | });
26 | describe("Null", function() {
27 | it("type", function(done) {
28 | con.k("testType", null, function(err, res) {
29 | if (err) { throw err; }
30 | assert.equal(res, 101, "res");
31 | done();
32 | });
33 | });
34 | it("value", function(done) {
35 | con.k("testValue", null, function(err, res) {
36 | if (err) { throw err; }
37 | assert.equal(res, null, "res");
38 | done();
39 | });
40 | });
41 | });
42 | describe("Infinity", function() {
43 | describe("+", function() {
44 | it("type", function(done) {
45 | con.k("testType", Infinity, function(err, res) {
46 | if (err) { throw err; }
47 | assert.equal(res, -9, "res");
48 | done();
49 | });
50 | });
51 | it("value", function(done) {
52 | con.k("testValue", Infinity, function(err, res) {
53 | if (err) { throw err; }
54 | assert.equal(res, Infinity, "res");
55 | done();
56 | });
57 | });
58 | });
59 | describe("-", function() {
60 | it("type", function(done) {
61 | con.k("testType", -Infinity, function(err, res) {
62 | if (err) { throw err; }
63 | assert.equal(res, -9, "res");
64 | done();
65 | });
66 | });
67 | it("value", function(done) {
68 | con.k("testValue", -Infinity, function(err, res) {
69 | if (err) { throw err; }
70 | assert.equal(res, -Infinity, "res");
71 | done();
72 | });
73 | });
74 | });
75 | });
76 | describe("Boolean", function() {
77 | it("type", function(done) {
78 | con.k("testType", true, function(err, res) {
79 | if (err) { throw err; }
80 | assert.equal(res, -1, "res");
81 | done();
82 | });
83 | });
84 | it("value", function(done) {
85 | con.k("testValue", true, function(err, res) {
86 | if (err) { throw err; }
87 | assert.equal(res, true, "res");
88 | done();
89 | });
90 | });
91 | });
92 | describe("String", function() {
93 | describe("starting with `", function() {
94 | it("type", function(done) {
95 | con.k("testType", "`a", function(err, res) {
96 | if (err) { throw err; }
97 | assert.equal(res, -11, "res");
98 | done();
99 | });
100 | });
101 | it("value", function(done) {
102 | con.k("testValue", "`a", function(err, res) {
103 | if (err) { throw err; }
104 | assert.equal(res, "a", "res");
105 | done();
106 | });
107 | });
108 | });
109 | describe("single char", function() {
110 | it("type", function(done) {
111 | con.k("testType", "a", function(err, res) {
112 | if (err) { throw err; }
113 | assert.equal(res, 10, "res");
114 | done();
115 | });
116 | });
117 | it("value", function(done) {
118 | con.k("testValue", "a", function(err, res) {
119 | if (err) { throw err; }
120 | assert.equal(res, "a", "res");
121 | done();
122 | });
123 | });
124 | });
125 | describe("string", function() {
126 | it("type", function(done) {
127 | con.k("testType", "abc", function(err, res) {
128 | if (err) { throw err; }
129 | assert.equal(res, 10, "res");
130 | done();
131 | });
132 | });
133 | it("value", function(done) {
134 | con.k("testValue", "abc", function(err, res) {
135 | if (err) { throw err; }
136 | assert.equal(res, "abc", "res");
137 | done();
138 | });
139 | });
140 | });
141 | });
142 | describe("Number", function() {
143 | it("type", function(done) {
144 | con.k("testType", 1, function(err, res) {
145 | if (err) { throw err; }
146 | assert.equal(res, -9, "res");
147 | done();
148 | });
149 | });
150 | it("value", function(done) {
151 | con.k("testValue", 1, function(err, res) {
152 | if (err) { throw err; }
153 | assert.equal(res, 1, "res");
154 | done();
155 | });
156 | });
157 | });
158 | describe("Date", function() {
159 | describe("year 2015", function() {
160 | it("type", function(done) {
161 | con.k("testType", new Date(2015, 0, 1, 0, 0, 0, 0), function(err, res) {
162 | if (err) { throw err; }
163 | assert.equal(res, -15, "res");
164 | done();
165 | });
166 | });
167 | it("value", function(done) {
168 | con.k("testValue", new Date(2015, 0, 1, 0, 0, 0, 0), function(err, res) {
169 | if (err) { throw err; }
170 | assert.equal(res.getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res");
171 | done();
172 | });
173 | });
174 | });
175 | describe("year 2000", function() {
176 | it("type", function(done) {
177 | con.k("testType", new Date(2000, 0, 1, 0, 0, 0, 0), function(err, res) {
178 | if (err) { throw err; }
179 | assert.equal(res, -15, "res");
180 | done();
181 | });
182 | });
183 | it("value", function(done) {
184 | con.k("testValue", new Date(2000, 0, 1, 0, 0, 0, 0), function(err, res) {
185 | if (err) { throw err; }
186 | assert.equal(res.getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res");
187 | done();
188 | });
189 | });
190 | });
191 | describe("year 1995", function() {
192 | it("type", function(done) {
193 | con.k("testType", new Date(1995, 0, 1, 0, 0, 0, 0), function(err, res) {
194 | if (err) { throw err; }
195 | assert.equal(res, -15, "res");
196 | done();
197 | });
198 | });
199 | it("value", function(done) {
200 | con.k("testValue", new Date(1995, 0, 1, 0, 0, 0, 0), function(err, res) {
201 | if (err) { throw err; }
202 | assert.equal(res.getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res");
203 | done();
204 | });
205 | });
206 | });
207 | });
208 | describe("Object", function() {
209 | it("type", function(done) {
210 | con.k("testType", {a: 1, b: 2, c: 3}, function(err, res) {
211 | if (err) { throw err; }
212 | assert.equal(res, 99, "res");
213 | done();
214 | });
215 | });
216 | it("value", function(done) {
217 | con.k("testValue", {a: 1, b: 2, c: 3}, function(err, res) {
218 | if (err) { throw err; }
219 | assert.deepEqual(res, {a: 1, b: 2, c: 3}, "res");
220 | done();
221 | });
222 | });
223 | });
224 | describe("Array", function() {
225 | describe("Boolean", function() {
226 | it("type", function(done) {
227 | con.k("testType", [true, false, true], function(err, res) {
228 | if (err) { throw err; }
229 | assert.equal(res, 1, "res");
230 | done();
231 | });
232 | });
233 | it("value", function(done) {
234 | con.k("testValue", [true, false, true], function(err, res) {
235 | if (err) { throw err; }
236 | assert.deepEqual(res, [true, false, true], "res");
237 | done();
238 | });
239 | });
240 | });
241 | describe("String", function() {
242 | describe("starting with `", function() {
243 | it("type", function(done) {
244 | con.k("testType", ["`a", "`b", "`c"], function(err, res) {
245 | if (err) { throw err; }
246 | assert.equal(res, 11, "res");
247 | done();
248 | });
249 | });
250 | it("value", function(done) {
251 | con.k("testValue", ["`a", "`b", "`c"], function(err, res) {
252 | if (err) { throw err; }
253 | assert.deepEqual(res, ["a", "b", "c"], "res");
254 | done();
255 | });
256 | });
257 | });
258 | describe("single char", function() {
259 | it("type", function(done) {
260 | con.k("testType", ["a", "b", "c"], function(err, res) {
261 | if (err) { throw err; }
262 | assert.equal(res, 0, "res");
263 | done();
264 | });
265 | });
266 | it("value", function(done) {
267 | con.k("testValue", ["a", "b", "c"], function(err, res) {
268 | if (err) { throw err; }
269 | assert.deepEqual(res, ["a", "b", "c"], "res");
270 | done();
271 | });
272 | });
273 | });
274 | describe("string", function() {
275 | it("type", function(done) {
276 | con.k("testType", ["abc", "bcd", "cde"], function(err, res) {
277 | if (err) { throw err; }
278 | assert.equal(res, 0, "res");
279 | done();
280 | });
281 | });
282 | it("value", function(done) {
283 | con.k("testValue", ["abc", "bcd", "cde"], function(err, res) {
284 | if (err) { throw err; }
285 | assert.deepEqual(res, ["abc", "bcd", "cde"], "res");
286 | done();
287 | });
288 | });
289 | });
290 | });
291 | describe("Number", function() {
292 | it("type", function(done) {
293 | con.k("testType", [1, 2, 3], function(err, res) {
294 | if (err) { throw err; }
295 | assert.equal(res, 9, "res");
296 | done();
297 | });
298 | });
299 | it("value", function(done) {
300 | con.k("testValue", [1, 2, 3], function(err, res) {
301 | if (err) { throw err; }
302 | assert.deepEqual(res, [1, 2, 3], "res");
303 | done();
304 | });
305 | });
306 | });
307 | describe("Date", function() {
308 | it("type", function(done) {
309 | con.k("testType", [new Date(2015, 0, 1, 0, 0, 0, 0), new Date(2000, 0, 1, 0, 0, 0, 0), new Date(1995, 0, 1, 0, 0, 0, 0)], function(err, res) {
310 | if (err) { throw err; }
311 | assert.equal(res, 15, "res");
312 | done();
313 | });
314 | });
315 | it("value", function(done) {
316 | con.k("testValue", [new Date(2015, 0, 1, 0, 0, 0, 0), new Date(2000, 0, 1, 0, 0, 0, 0), new Date(1995, 0, 1, 0, 0, 0, 0)], function(err, res) {
317 | if (err) { throw err; }
318 | assert.deepEqual(res[0].getTime(), new Date(2015, 0, 1, 0, 0, 0, 0).getTime(), "res[0]");
319 | assert.deepEqual(res[1].getTime(), new Date(2000, 0, 1, 0, 0, 0, 0).getTime(), "res[1]");
320 | assert.deepEqual(res[2].getTime(), new Date(1995, 0, 1, 0, 0, 0, 0).getTime(), "res[2]");
321 | done();
322 | });
323 | });
324 | });
325 | });
326 | });
327 |
--------------------------------------------------------------------------------
/itest/subs.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | async = require("async"),
3 | assert = require("assert");
4 |
5 | describe("subs", function() {
6 | "use strict";
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | async.each([
12 | 'system "l tick/u.q"',
13 | "trade: ([] sym:`$(); time:`timestamp$())",
14 | ".u.init[]",
15 | ".z.ts: {[] trade::0#trade; trade,::(`a;.z.p); .u.pub[`trade;trade]}",
16 | 'system "t 500"'
17 | ], function(q, cb) {
18 | c.k(q, cb);
19 | }, function(err) {
20 | if (err) { throw err; }
21 | con = c;
22 | done();
23 | });
24 | });
25 | });
26 | after(function(done) {
27 | con.close(function() {
28 | con = undefined;
29 | done();
30 | });
31 | });
32 | it("subscribe all", function(done) {
33 | con.once("upd", function(table, data) {
34 | assert.equal(typeof table, "string", "table");
35 | assert.equal(Array.isArray(data), true, "data");
36 | done();
37 | });
38 | con.ks(".u.sub[`;`]", function(err) {
39 | if (err) { throw err; }
40 | });
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/itest/syncreqres.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert"),
3 | async = require("async");
4 |
5 | describe("syncreqres", function() {
6 | "use strict";
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | it("evaluate q", function(done) {
22 | con.k("sum 1 2 3", function(err, res) {
23 | if (err) { throw err; }
24 | assert.equal(res, 6, "res");
25 | done();
26 | });
27 | });
28 | it("evaluate malformed q", function(done) {
29 | con.k("sxm 1 2 3", function(err) {
30 | if (err) {
31 | assert.equal(err.message, "sxm", "err");
32 | done();
33 | } else {
34 | assert.fail("no err");
35 | }
36 | });
37 | });
38 | it("evaluate function with one parameter", function(done) {
39 | con.k("sum", [1, 2, 3], function(err, res) {
40 | if (err) { throw err; }
41 | assert.equal(res, 6, "res");
42 | done();
43 | });
44 | });
45 | it("evaluate function with two parameters", function(done) {
46 | con.k("cor", [1, 2, 3], [4, 5, 6], function(err, res) {
47 | if (err) { throw err; }
48 | assert.equal(res, 1, "res");
49 | done();
50 | });
51 | });
52 | it("mass requests", function(done) {
53 | async.map([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], function(i, cb) {
54 | con.k("sum", [i, i], cb);
55 | }, function(err, res) {
56 | if (err) { throw err; }
57 | assert.deepEqual(res, [0, 2, 4, 6, 8, 10, 12, 14, 16, 18], "res");
58 | done();
59 | });
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/itest/tls.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("tls", function() {
5 | "use strict";
6 | it("should fail if endpoint expects tls and we don't set useTLS to true", function(done) {
7 | nodeq.connect({host: "localhost", port: 6000}, function(err) {
8 | assert.ok(err);
9 | done();
10 | });
11 | });
12 |
13 | it("should connect successfully if useTLS is true", function(done) {
14 | nodeq.connect({host: "localhost", port: 6000, useTLS: true}, function(err) {
15 | if (err) {
16 | throw err;
17 | }
18 | done();
19 | });
20 | });
21 |
22 | it("should fail if useTLS is true and endpoint doesn't expect it", function(done) {
23 | nodeq.connect({host: "localhost", port: 5000, useTLS: true}, function(err) {
24 | assert.ok(err);
25 | done();
26 | });
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/itest/unicode.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("unicode", function() {
5 | "use strict";
6 |
7 | var con;
8 | before(function(done) {
9 | nodeq.connect({host: "localhost", port: 5000}, function(err, c) {
10 | if (err) { throw err; }
11 | con = c;
12 | done();
13 | });
14 | });
15 | after(function(done) {
16 | con.close(function() {
17 | con = undefined;
18 | done();
19 | });
20 | });
21 | describe("string", function() {
22 | it("count", function(done) {
23 | con.k("count", "你好", function(err, res) {
24 | if (err) { throw err; }
25 | assert.equal(res, 6, "res");
26 | done();
27 | });
28 | });
29 | it("value", function(done) {
30 | con.k('s: "你好"; s', function(err, res) {
31 | if (err) { throw err; }
32 | assert.equal(res, "你好", "res");
33 | done();
34 | });
35 | });
36 | });
37 | describe("symbol", function() {
38 | it("count", function(done) {
39 | con.k("count", "`你好", function(err, res) {
40 | if (err) { throw err; }
41 | assert.equal(res, 1, "res");
42 | done();
43 | });
44 | });
45 | it("value", function(done) {
46 | con.k('s: `$"你好"; s', function(err, res) {
47 | if (err) { throw err; }
48 | assert.equal(res, "你好", "res");
49 | done();
50 | });
51 | });
52 | });
53 | describe("symbols", function() {
54 | it("count", function(done) {
55 | con.k("count", ["`你好", "`你好", "`你好"], function(err, res) {
56 | if (err) { throw err; }
57 | assert.equal(res, 3, "res");
58 | done();
59 | });
60 | });
61 | it("values", function(done) {
62 | con.k('s: (`$"你好";`$"你好";`$"你好"); s', function(err, res) {
63 | if (err) { throw err; }
64 | assert.deepEqual(res, ["你好", "你好", "你好"], "res");
65 | done();
66 | });
67 | });
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/lib/assert.js:
--------------------------------------------------------------------------------
1 | var Long = require("long");
2 |
3 | function optional(fun) {
4 | "use strict";
5 | return function(val, message) {
6 | if (val === null || val === undefined) {
7 | return;
8 | }
9 | return fun(val, message);
10 | };
11 | }
12 |
13 | function string(val, message) {
14 | "use strict";
15 | if (typeof val !== "string") {
16 | throw new Error(message);
17 | }
18 | }
19 | exports.string = string;
20 | exports.optionalString = optional(string);
21 |
22 | function func(val, message) {
23 | "use strict";
24 | if (typeof val !== "function") {
25 | throw new Error(message);
26 | }
27 | }
28 | exports.func = func;
29 | exports.optionalFunc = optional(func);
30 |
31 | function bool(val, message) {
32 | "use strict";
33 | if (typeof val !== "boolean") {
34 | throw new Error(message);
35 | }
36 | }
37 | exports.bool = bool;
38 | exports.optionalBool = optional(bool);
39 |
40 | function object(val, message) {
41 | "use strict";
42 | if (typeof val !== "object") {
43 | throw new Error(message);
44 | }
45 | }
46 | exports.object = object;
47 | exports.optionalObject = optional(object);
48 |
49 | function number(val, message) {
50 | "use strict";
51 | if (typeof val !== "number") {
52 | throw new Error(message);
53 | }
54 | }
55 | exports.number = number;
56 | exports.optionalNumber = optional(number);
57 |
58 | function date(val, message) {
59 | "use strict";
60 | if (!(val instanceof Date)) {
61 | throw new Error(message);
62 | }
63 | }
64 | exports.date = date;
65 | exports.optionalDate = optional(date);
66 |
67 | function array(val, message) {
68 | "use strict";
69 | if (!Array.isArray(val)) {
70 | throw new Error(message);
71 | }
72 | }
73 | exports.array = array;
74 | exports.optionalArray = optional(array);
75 |
76 | function long(val, message) {
77 | "use strict";
78 | if (!Long.isLong(val)) {
79 | throw new Error(message);
80 | }
81 | }
82 | exports.long = long;
83 | exports.optionalLong = optional(long);
84 |
--------------------------------------------------------------------------------
/lib/c.js:
--------------------------------------------------------------------------------
1 | var Long = require("long");
2 | var uuid = require("node-uuid");
3 | require("buffer-indexof-polyfill");
4 |
5 | var typed = require("./typed.js");
6 |
7 | var J2P32 = Math.pow(2, 32);
8 |
9 | var UUID_NULL = "00000000-0000-0000-0000-000000000000";
10 | var SHORT_NULL = -32768;
11 | var SHORT_INFINITY = 32767;
12 | var SHORT_NEG_INFINITY = 0 - SHORT_INFINITY;
13 | var INT_NULL = -2147483648;
14 | var INT_INFINITY = 2147483647;
15 | var INT_NEG_INFINITY = 0 - INT_INFINITY;
16 | var LONG_NULL = Long.fromString("9223372036854775808", false, 10);
17 | var LONG_INFINITY = Long.fromString("9223372036854775807", false, 10);
18 | var LONG_NEG_INFINITY = Long.fromString("9223372036854775809", false, 10);
19 | var ZERO_BYTE = new Buffer(1);
20 | ZERO_BYTE.writeUInt8(0, 0);
21 |
22 | var QTYPES2NUM = {
23 | "null": 101,
24 | "boolean": 1,
25 | "guid": 2,
26 | "byte": 4,
27 | "short": 5,
28 | "int": 6,
29 | "long": 7,
30 | "real": 8,
31 | "float": 9,
32 | "char": 10,
33 | "symbol": 11,
34 | "timestamp": 12,
35 | "month": 13,
36 | "date": 14,
37 | "datetime": 15,
38 | "timespan": 16,
39 | "minute": 17,
40 | "second": 18,
41 | "time": 19
42 | };
43 | var QTYPES2SIZE = {
44 | "null": 1,
45 | "boolean": 1,
46 | "guid": 16,
47 | "byte": 1,
48 | "short": 2,
49 | "int": 4,
50 | "long": 8,
51 | "real": 4,
52 | "float": 8,
53 | "char": 1,
54 | // "symbol": , // variable length
55 | "timestamp": 8,
56 | "month": 4,
57 | "date": 4,
58 | "datetime": 8,
59 | "timespan": 8,
60 | "minute": 4,
61 | "second": 4,
62 | "time": 4
63 | };
64 | var symbolStringRegex = /^`\S+$/;
65 |
66 | function type2num(t) {
67 | var num = QTYPES2NUM[t];
68 | if (num === undefined) {
69 | throw new Error("bad type " + t);
70 | }
71 | return num;
72 | }
73 |
74 | function type2size(t) {
75 | var size = QTYPES2SIZE[t];
76 | if (size === undefined) {
77 | throw new Error("bad type " + t);
78 | }
79 | return size;
80 | }
81 |
82 | // added support for decompression [GMelika]
83 | function decompress(compressedSize, b) {
84 | "use strict";
85 | var n = 0,
86 | r = 0,
87 | f = 0,
88 | s = 8,
89 | p = s,
90 | i = 0;
91 | var dst = new Buffer(compressedSize);
92 | var d = 12;
93 | var aa = new Int32Array(256);
94 | while (s < dst.length) {
95 | if (!i) {
96 | f = b[d++];
97 | i = 1;
98 | }
99 | if (f & i) {
100 | r = aa[b[d++]];
101 | dst[s++] = dst[r++];
102 | dst[s++] = dst[r++];
103 | n = 0xff & b[d++];
104 | for (var m = 0; m < n; m++) {
105 | dst[s + m] = dst[r + m];
106 | }
107 | } else {
108 | dst[s++] = b[d++];
109 | }
110 | while (p < (s - 1)) {
111 | aa[dst[p] ^ dst[p + 1]] = p++;
112 | }
113 | if (f & i) {
114 | p = (s += n);
115 | }
116 | i *= 2;
117 | if (i === 256) {
118 | i = 0;
119 | }
120 | }
121 | return dst;
122 | }
123 |
124 | function deserialize(b, nanos2date, flipTables, emptyChar2null, long2number) {
125 | "use strict";
126 | var pos = 8, isCompressed = (b[2] === 1);
127 | function rBool() {
128 | return rInt8() === 1;
129 | }
130 | function rChar() {
131 | var val = rUInt8();
132 | if (val === 32 && emptyChar2null !== false) {
133 | return null;
134 | } else {
135 | return String.fromCharCode(val);
136 | }
137 | }
138 | function rString(n) {
139 | var val = b.slice(pos, pos+n).toString('utf8');
140 | pos += n;
141 | return val;
142 | }
143 | function rInt8() {
144 | var val = b.readInt8(pos);
145 | pos += 1;
146 | return val;
147 | }
148 | function rInt(n) {
149 | var val;
150 | if (n === 1) {
151 | val = b.readInt8(pos);
152 | } else if (n === 2) {
153 | val = b.readInt16LE(pos);
154 | } else if (n === 4) {
155 | val = b.readInt32LE(pos);
156 | } else {
157 | throw new Error("only n = 1, 2 or 4 is supported");
158 | }
159 | pos += n;
160 | return val;
161 | }
162 | function rUInt8() {
163 | var val = b.readUInt8(pos);
164 | pos += 1;
165 | return val;
166 | }
167 | function rGuid() {
168 | var x = "0123456789abcdef", s = "";
169 | for (var i = 0; i < 16; i++) {
170 | var c = rUInt8();
171 | s += i === 4 || i === 6 || i === 8 || i === 10 ? "-" : "";
172 | s += x[c >> 4];
173 | s += x[c & 15];
174 | }
175 | if (s === UUID_NULL) {
176 | return null;
177 | } else {
178 | return s;
179 | }
180 | }
181 | function rInt16() {
182 | var h = rInt(2);
183 | if (h === SHORT_NULL) {
184 | return null;
185 | } else if (h === SHORT_INFINITY) {
186 | return Infinity;
187 | } else if (h === SHORT_NEG_INFINITY) {
188 | return -Infinity;
189 | } else {
190 | return h;
191 | }
192 | }
193 | function rInt32() {
194 | var i = rInt(4);
195 | if (i === INT_NULL) {
196 | return null;
197 | } else if (i === INT_INFINITY) {
198 | return Infinity;
199 | } else if (i === INT_NEG_INFINITY) {
200 | return -Infinity;
201 | } else {
202 | return i;
203 | }
204 | }
205 | function rInt64() { // long or closest number
206 | if (long2number === false) {
207 | var low = rInt(4);
208 | var high = rInt(4);
209 | var val = new Long(low, high, false);
210 | if (low === 0 && high === INT_NULL) {
211 | return null;
212 | }
213 | if (low === -1 && high === INT_INFINITY) {
214 | return Infinity;
215 | }
216 | if (low === 1 && high === INT_NULL) {
217 | return -Infinity;
218 | }
219 | return val;
220 | } else {
221 | var y = rInt(4);
222 | var x = rInt(4);
223 | if (x === INT_NULL && y === 0) {
224 | return null;
225 | } else if (x === 2147483647 && y === -1) {
226 | return Infinity;
227 | } else if (x === -2147483648 && y === 1) {
228 | return -Infinity;
229 | } else {
230 | return x * J2P32 + (y >= 0 ? y : J2P32 + y);
231 | }
232 | }
233 | }
234 | function rFloat32() {
235 | var val = b.readFloatLE(pos);
236 | pos += 4;
237 | if (Number.isNaN(val)) {
238 | return null;
239 | } else {
240 | return val;
241 | }
242 | }
243 | function rFloat64() {
244 | var val = b.readDoubleLE(pos);
245 | pos += 8;
246 | if (Number.isNaN(val)) {
247 | return null;
248 | } else {
249 | return val;
250 | }
251 | }
252 | function rSymbol() {
253 | var e = b.indexOf(ZERO_BYTE, pos);
254 | var s = rString(e-pos);
255 | pos += 1; // zero byte
256 | if (s === "") {
257 | return null;
258 | } else {
259 | return s;
260 | }
261 | }
262 | function rTimestamp() {
263 | var val = rInt64();
264 | if (val === null) {
265 | return null;
266 | }
267 | if (nanos2date === false) {
268 | return 86400000000000 * (10957 + (val / 86400000000000));
269 | } else {
270 | return date(val / 86400000000000);
271 | }
272 | }
273 | function rMonth() {
274 | var y = rInt32();
275 | if (y === null) {
276 | return null;
277 | }
278 | var m = y % 12;
279 | y = 2000 + y / 12;
280 | return new Date(Date.UTC(y, m, 1));
281 | }
282 | function date(n) {
283 | return new Date(86400000 * (10957 + n));
284 | }
285 | function rDate() {
286 | var val = rInt32();
287 | return (val === null) ? null : date(val);
288 | }
289 | function rDateTime() {
290 | var val = rFloat64();
291 | return (val === null) ? null : date(val);
292 | }
293 | function rTimespan() {
294 | var val = rInt64();
295 | if (val === null) {
296 | return null;
297 | }
298 | if (nanos2date === false) {
299 | return val;
300 | }
301 | return date(val / 86400000000000);
302 | }
303 | function rSecond() {
304 | var val = rInt32();
305 | if (val === null) {
306 | return null;
307 | }
308 | return date(val / 86400);
309 | }
310 | function rMinute() {
311 | var val = rInt32();
312 | if (val === null) {
313 | return null;
314 | }
315 | return date(val / 1440);
316 | }
317 | function rTime() {
318 | var val = rInt32();
319 | if (val === null) {
320 | return null;
321 | }
322 | return date(val / 86400000);
323 | }
324 | function r() {
325 | var fns = [r, rBool, rGuid, null, rUInt8, rInt16, rInt32, rInt64, rFloat32, rFloat64, rChar, rSymbol, rTimestamp, rMonth, rDate, rDateTime, rTimespan, rMinute, rSecond, rTime];
326 | var i = 0, n, t = rInt8();
327 | if (t === -128) {
328 | throw new Error(rSymbol());
329 | }
330 | if (t < 0 && t > -20) {
331 | return fns[-t]();
332 | }
333 | if (t > 99) {
334 | if (t === 100) {
335 | rSymbol();
336 | return r();
337 | }
338 | if (t < 104) {
339 | return rInt8() === 0 && t === 101 ? null : "func";
340 | }
341 | if (t > 105) {
342 | r();
343 | } else {
344 | for (n = rInt32(); i < n; i++) {
345 | r();
346 | }
347 | }
348 | return "func";
349 | }
350 | if (99 === t) {
351 | var flip = 98 === rUInt8();
352 | pos -= 1;
353 | var x = r(),
354 | y = r(),
355 | o;
356 | if (!flip) {
357 | o = {};
358 | for (i = 0; i < x.length; i++) {
359 | o[x[i]] = y[i];
360 | }
361 | } else {
362 | o = new Array(2);
363 | o[0]=x;
364 | o[1]=y;
365 | }
366 | return o;
367 | }
368 | pos++;
369 | if (98 === t) {
370 | if (flipTables === false) {
371 | return r();
372 | } else {
373 | rInt8();
374 | var x = r();
375 | var y = r();
376 | var A = new Array(y[0].length);
377 | for (var j = 0; j < y[0].length; j++) {
378 | var o = {};
379 | for (var i = 0; i < x.length; i++) {
380 | o[x[i]] = y[i][j];
381 | }
382 | A[j] = o;
383 | }
384 | return A;
385 | }
386 | }
387 | n = rInt32();
388 | if (10 === t) {
389 | return rString(n);
390 | }
391 | var A = new Array(n);
392 | var f = fns[t];
393 | for (i = 0; i < n; i++) {
394 | A[i] = f();
395 | }
396 | return A;
397 | }
398 | if (isCompressed) {
399 | var compressedSize = rInt32();
400 | b = decompress(compressedSize, b);
401 | pos = 8;
402 | }
403 | return r();
404 | }
405 |
406 | function inferType(x) {
407 | if (typed.isTyped(x)) {
408 | return x.type();
409 | }
410 | if (x === null) {
411 | return "null";
412 | }
413 | if (typeof x === "number") {
414 | return "float";
415 | }
416 | if (x instanceof Date) {
417 | return "datetime";
418 | }
419 | if (typeof x === "boolean") {
420 | return "boolean";
421 | }
422 | if (Array.isArray(x)) {
423 | return "list";
424 | }
425 | if (typeof x === "string") {
426 | return "string";
427 | }
428 | if (typeof x === "object") {
429 | return "dict";
430 | }
431 | }
432 |
433 | function isListOfSamePrimitiveType(elements, valuetype) {
434 | if (valuetype === "list" || valuetype === "typedlist" || valuetype === "mixedlist" || valuetype === "string" || valuetype === "dict" || valuetype === "null") {
435 | return false;
436 | }
437 | return elements.every(function(x) {
438 | return inferType(x) === valuetype;
439 | });
440 | }
441 |
442 | function calcN(x, dt) {
443 | var t, vt;
444 | if (dt) {
445 | t = dt;
446 | } else {
447 | if (typed.isTyped(x)) {
448 | t = x.type();
449 | if (t === "typedlist") {
450 | vt = x.valuetype();
451 | }
452 | x = x.value();
453 | } else {
454 | t = inferType(x);
455 | }
456 | }
457 | switch (t) {
458 | case "null": // JavaScript only type
459 | return 2;
460 | case "symbol":
461 | {
462 | if (x === null) {
463 | return 2;
464 | }
465 | return 2 + Buffer.byteLength(x, 'utf8');
466 | }
467 | case "dict":
468 | {
469 | var n = 1 + 6;
470 | var k = Object.keys(x);
471 | for (var i = 0; i < k.length; i++) {
472 | n += 1 + k[i].length;
473 | }
474 | return n + calcN(getVals(x));
475 | }
476 | case "list":
477 | {
478 | if (x.length > 0 && (dt === null || dt === undefined)) {
479 | var valuetype = inferType(x[0]);
480 | if (isListOfSamePrimitiveType(x, valuetype)) {
481 | return calcN(new typed.Typed("typedlist", x.map(function(x1) {
482 | if (typed.isTyped(x1)) {
483 | return x1.value();
484 | } else {
485 | return x1;
486 | }
487 | }), valuetype));
488 | }
489 | }
490 | return calcN(x, "mixedlist");
491 | }
492 | case "mixedlist":
493 | {
494 | var n = 6;
495 | for (var i = 0; i < x.length; i++) {
496 | n += calcN(x[i], null);
497 | }
498 | return n;
499 | }
500 | case "typedlist":
501 | {
502 | var n = 6;
503 | if (vt === "symbol") {
504 | for (var i = 0; i < x.length; i++) {
505 | n += 1 + Buffer.byteLength(x[i], 'utf8');
506 | }
507 | } else {
508 | n += type2size(vt) * x.length;
509 | }
510 | return n;
511 | }
512 | case "string": // JavaScript only type => list of char
513 | {
514 | var n=Buffer.byteLength(x, 'utf8') + (symbolStringRegex.test(x) ? 1 : 6);
515 | return n;
516 | }
517 | // TODO implement calcN for table type
518 | }
519 | return 1 + type2size(t);
520 | }
521 |
522 | function getVals(x) { // can be replaces with Object.values someday
523 | var v = [], o;
524 | for (o in x) {
525 | if (x.hasOwnProperty(o)) {
526 | v.push(x[o]);
527 | }
528 | }
529 | return v;
530 | }
531 |
532 | function serialize(x) {
533 | "use strict";
534 | var pos = 0, b;
535 | function wb(i) {
536 | b.writeInt8(i, pos);
537 | pos += 1;
538 | }
539 | function wub(i) {
540 | b.writeUInt8(i, pos);
541 | pos += 1;
542 | }
543 | function wr(i) {
544 | b.writeFloatLE(i, pos);
545 | pos += 4;
546 | }
547 | function wf(i) {
548 | b.writeDoubleLE(i, pos);
549 | pos += 8;
550 | }
551 | function wn(n, i) {
552 | if (n === 1) {
553 | b.writeInt8(i, pos);
554 | } else if (n === 2) {
555 | b.writeInt16LE(i, pos);
556 | } else if (n === 4) {
557 | b.writeInt32LE(i, pos);
558 | } else {
559 | throw new Error("only n = 1, 2 or 4 is supported");
560 | }
561 | pos += n;
562 | }
563 | function wlongjs(x) {
564 | wn(4, x.low);
565 | wn(4, x.high);
566 | }
567 | function wboolean(x) {
568 | wb(x ? 1 : 0);
569 | }
570 | function wguid(x) {
571 | if (x === null) {
572 | uuid.parse(UUID_NULL, b, pos);
573 | } else {
574 | uuid.parse(x, b, pos);
575 | }
576 | pos+=16;
577 | }
578 | function wbyte(x) {
579 | wb(x);
580 | }
581 | function wshort(x) {
582 | if (x === null) {
583 | wn(2, SHORT_NULL);
584 | } else if (x === Infinity) {
585 | wn(2, SHORT_INFINITY);
586 | } else if (x === -Infinity) {
587 | wn(2, SHORT_NEG_INFINITY);
588 | } else {
589 | wn(2, x);
590 | }
591 | }
592 | function wint(x) {
593 | if (x === null) {
594 | wn(4, INT_NULL);
595 | } else if (x === Infinity) {
596 | wn(4, INT_INFINITY);
597 | } else if (x === -Infinity) {
598 | wn(4, INT_NEG_INFINITY);
599 | } else {
600 | wn(4, x);
601 | }
602 | }
603 | function wlong(x) {
604 | if (x === null) {
605 | wub(0);
606 | wub(0);
607 | wub(0);
608 | wub(0);
609 | wub(0);
610 | wub(0);
611 | wub(0);
612 | wub(128);
613 | } else if (x === Infinity) {
614 | wub(255);
615 | wub(255);
616 | wub(255);
617 | wub(255);
618 | wub(255);
619 | wub(255);
620 | wub(255);
621 | wub(127);
622 | } else if (x === -Infinity) {
623 | wub(1);
624 | wub(0);
625 | wub(0);
626 | wub(0);
627 | wub(0);
628 | wub(0);
629 | wub(0);
630 | wub(128);
631 | } else {
632 | wlongjs(x);
633 | }
634 | }
635 | function wreal(x) {
636 | if (x === null) {
637 | wub(0);
638 | wub(0);
639 | wub(192);
640 | wub(255);
641 | } else if (x === Infinity) {
642 | wub(0);
643 | wub(0);
644 | wub(128);
645 | wub(127);
646 | } else if (x === -Infinity) {
647 | wub(0);
648 | wub(0);
649 | wub(128);
650 | wub(255);
651 | } else {
652 | wr(x);
653 | }
654 | }
655 | function wfloat(x) {
656 | if (x === null) {
657 | wub(0);
658 | wub(0);
659 | wub(0);
660 | wub(0);
661 | wub(0);
662 | wub(0);
663 | wub(248);
664 | wub(255);
665 | } else if (x === Infinity) {
666 | wub(0);
667 | wub(0);
668 | wub(0);
669 | wub(0);
670 | wub(0);
671 | wub(0);
672 | wub(240);
673 | wub(127);
674 | } else if (x === -Infinity) {
675 | wub(0);
676 | wub(0);
677 | wub(0);
678 | wub(0);
679 | wub(0);
680 | wub(0);
681 | wub(240);
682 | wub(255);
683 | } else {
684 | wf(x);
685 | }
686 | }
687 | function wchar(x) {
688 | if (x === null) {
689 | wub(32);
690 | } else {
691 | wub(x.charCodeAt());
692 | }
693 | }
694 | function wstring(x) {
695 | pos += b.write(x, pos, 'utf8');
696 | }
697 | function wsymbol(x) {
698 | if (x !== null) {
699 | wstring(x);
700 | }
701 | wb(0);
702 | }
703 | function wtimestamp(x) {
704 | if (x === null) {
705 | wlong(null);
706 | } else {
707 | // 86400000000000 * (x.getTime() / 86400000 - 10957)
708 | wlong(Long.fromNumber(Long.fromString("1000000", false, 10).multiply(Long.fromNumber(x.getTime())).subtract(Long.fromString("946684800000000000", false, 10))));
709 | }
710 | }
711 | function wmonth(x) {
712 | if (x == null) {
713 | wn(4, INT_NULL);
714 | } else {
715 | wn(4, (x.getUTCFullYear() - 2000) * 12 + x.getUTCMonth());
716 | }
717 | }
718 | function wdate(x) {
719 | if (x == null) {
720 | wn(4, INT_NULL);
721 | } else {
722 | wn(4, x.getTime() / 86400000 - 10957);
723 | }
724 | }
725 | function wdatetime(x) {
726 | if (x === null) {
727 | wub(0);
728 | wub(0);
729 | wub(0);
730 | wub(0);
731 | wub(0);
732 | wub(0);
733 | wub(248);
734 | wub(255);
735 | } else {
736 | wf(x.getTime() / 86400000 - 10957);
737 | }
738 | }
739 | function wtimespan(x) {
740 | if (x === null) {
741 | wlong(null);
742 | } else {
743 | var nanos = (((x.getUTCHours() * 60 + x.getUTCMinutes()) * 60 + x.getUTCSeconds()) * 1000 + x.getUTCMilliseconds()) * 1000 * 1000;
744 | wlong(Long.fromNumber(nanos));
745 | }
746 | }
747 | function wminute(x) {
748 | if (x == null) {
749 | wn(4, INT_NULL);
750 | } else {
751 | wn(4, x.getUTCHours() * 60 + x.getUTCMinutes());
752 | }
753 | }
754 | function wsecond(x) {
755 | if (x == null) {
756 | wn(4, INT_NULL);
757 | } else {
758 | wn(4, (x.getUTCHours() * 60 + x.getUTCMinutes()) * 60 + x.getUTCSeconds());
759 | }
760 | }
761 | function wtime(x) {
762 | if (x == null) {
763 | wn(4, INT_NULL);
764 | } else {
765 | wn(4, ((x.getUTCHours() * 60 + x.getUTCMinutes()) * 60 + x.getUTCSeconds()) * 1000 + x.getUTCMilliseconds());
766 | }
767 | }
768 | function wnull() {
769 | wb(0);
770 | }
771 |
772 | var qtype2wfn = {
773 | "null": wnull,
774 | "boolean": wboolean,
775 | "guid": wguid,
776 | "byte": wbyte,
777 | "short": wshort,
778 | "int": wint,
779 | "long": wlong,
780 | "real": wreal,
781 | "float": wfloat,
782 | "char": wchar,
783 | "symbol": wsymbol,
784 | "timestamp": wtimestamp,
785 | "month": wmonth,
786 | "date": wdate,
787 | "datetime": wdatetime,
788 | "timespan": wtimespan,
789 | "minute": wminute,
790 | "second": wsecond,
791 | "time": wtime
792 | };
793 |
794 | function type2wfn(t) {
795 | var wfn = qtype2wfn[t];
796 | if (wfn === undefined) {
797 | throw new Error("bad type " + t);
798 | }
799 | return wfn;
800 | }
801 |
802 | function w(x, dt) {
803 | var t, vt;
804 | if (dt) {
805 | t = dt;
806 | } else {
807 | if (typed.isTyped(x)) {
808 | t = x.type();
809 | if (t === "typedlist") {
810 | vt = x.valuetype();
811 | }
812 | x = x.value();
813 | } else {
814 | t = inferType(x);
815 | }
816 | }
817 | switch (t) {
818 | case "null": // JavaScript only type
819 | {
820 | wb(101);
821 | wb(0);
822 | }
823 | return;
824 | case "dict":
825 | {
826 | var k = Object.keys(x);
827 | wb(99);
828 | wb(11);
829 | wb(0);
830 | wn(4, k.length);
831 | for (var i = 0; i < k.length; i++) {
832 | wsymbol(k[i]);
833 | }
834 | w(getVals(x));
835 | }
836 | return;
837 | case "list":
838 | {
839 | if (x.length > 0 && (dt === null || dt === undefined)) {
840 | var valuetype = inferType(x[0]);
841 | if (isListOfSamePrimitiveType(x, valuetype)) {
842 | return w(new typed.Typed("typedlist", x.map(function(x1) {
843 | if (typed.isTyped(x1)) {
844 | return x1.value();
845 | } else {
846 | return x1;
847 | }
848 | }), valuetype));
849 | }
850 | }
851 | return w(x, "mixedlist");
852 | }
853 | case "mixedlist":
854 | {
855 | wb(0);
856 | wb(0);
857 | wn(4, x.length);
858 | for (var i = 0; i < x.length; i++) {
859 | w(x[i], null);
860 | }
861 | return;
862 | }
863 | case "typedlist":
864 | {
865 | wb(type2num(vt));
866 | wb(0);
867 | wn(4, x.length);
868 | var wfn = type2wfn(vt);
869 | x.forEach(wfn);
870 | }
871 | return;
872 | case "string": // JavaScript only type => list of char
873 | {
874 | if (symbolStringRegex.test(x)) {
875 | w(x.substr(1), "symbol");
876 | } else {
877 | wb(10);
878 | wb(0);
879 | wn(4, Buffer.byteLength(x, 'utf8'));
880 | wstring(x);
881 | }
882 | return;
883 | }
884 | // TODO implement write to buffer for table type
885 | }
886 | var num = type2num(t);
887 | var wfn = type2wfn(t);
888 | wb(0-num);
889 | wfn(x);
890 |
891 | }
892 | var n = calcN(x, null);
893 | b = new Buffer(8 + n);
894 | wb(1);
895 | wb(0);
896 | wb(0);
897 | wb(0);
898 | wn(4, b.length);
899 | w(x, null);
900 | return b;
901 | }
902 |
903 | exports.deserialize = deserialize;
904 | exports.serialize = serialize;
905 |
--------------------------------------------------------------------------------
/lib/typed.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /**
4 | * Explicit serialization to KDB is possible using the Typed API.
5 | */
6 | export declare class Typed {
7 | /**
8 | * A private constructor is used to prevent inheritance.
9 | */
10 | private constructor();
11 | /**
12 | * Name of the type to serialize as.
13 | */
14 | readonly type: string;
15 | /**
16 | * The JavaScript value of the Typed object.
17 | */
18 | readonly value: any;
19 | /**
20 | * When the type is a list, this property returns the type of values within the list.
21 | */
22 | readonly valueType: string | undefined;
23 | }
24 |
25 | /* Primitive wrapper methods */
26 |
27 | /**
28 | * Explicitly wrap the specified value as a boolean.
29 | * @param value The value to wrap.
30 | */
31 | export declare function boolean(value: boolean): Typed;
32 | /**
33 | * Explicitly wrap the specified value as a guid.
34 | * @param value The value to wrap.
35 | */
36 | export declare function guid(value: string): Typed;
37 | /**
38 | * Explicitly wrap the specified value as a byte.
39 | * @param value The value to wrap.
40 | */
41 | export declare function byte(value: number): Typed;
42 | /**
43 | * Explicitly wrap the specified value as a short.
44 | * @param value The value to wrap.
45 | */
46 | export declare function short(value: number): Typed;
47 | /**
48 | * Explicitly wrap the specified value as a int.
49 | * @param value The value to wrap.
50 | */
51 | export declare function int(value: number): Typed;
52 | /**
53 | * Explicitly wrap the specified value as a long.
54 | * @param value The value to wrap.
55 | */
56 | export declare function long(value: Long): Typed;
57 | /**
58 | * Explicitly wrap the specified value as a real.
59 | * @param value The value to wrap.
60 | */
61 | export declare function real(value: number): Typed;
62 | /**
63 | * Explicitly wrap the specified value as a float.
64 | * @param value The value to wrap.
65 | */
66 | export declare function float(value: number): Typed;
67 | /**
68 | * Explicitly wrap the specified value as a char.
69 | * @param value The value to wrap.
70 | */
71 | export declare function char(value: string): Typed;
72 | /**
73 | * Explicitly wrap the specified value as a symbol.
74 | * @param value The value to wrap.
75 | */
76 | export declare function symbol(value: string): Typed;
77 | /**
78 | * Explicitly wrap the specified value as a timestamp.
79 | * @param value The value to wrap.
80 | */
81 | export declare function timestamp(value: Date): Typed;
82 | /**
83 | * Explicitly wrap the specified value as a month.
84 | * @param value The value to wrap.
85 | */
86 | export declare function month(value: Date): Typed;
87 | /**
88 | * Explicitly wrap the specified value as a date.
89 | * @param value The value to wrap.
90 | */
91 | export declare function date(value: Date): Typed;
92 | /**
93 | * Explicitly wrap the specified value as a datetime.
94 | * @param value The value to wrap.
95 | */
96 | export declare function datetime(value: Date): Typed;
97 | /**
98 | * Explicitly wrap the specified value as a timespan.
99 | * @param value The value to wrap.
100 | */
101 | export declare function timespan(value: Date): Typed;
102 | /**
103 | * Explicitly wrap the specified value as a minute.
104 | * @param value The value to wrap.
105 | */
106 | export declare function minute(value: Date): Typed;
107 | /**
108 | * Explicitly wrap the specified value as a second.
109 | * @param value The value to wrap.
110 | */
111 | export declare function second(value: Date): Typed;
112 | /**
113 | * Explicitly wrap the specified value as a time.
114 | * @param value The value to wrap.
115 | */
116 | export declare function time(value: Date): Typed;
117 |
118 | /* Array wrapper methods */
119 |
120 | /**
121 | * Explicitly wrap the specified array as a typed list of booleans.
122 | * @param value The array to wrap.
123 | */
124 | export declare function booleans(value: boolean[] | ReadonlyArray): Typed;
125 | /**
126 | * Explicitly wrap the specified array as a typed list of guids.
127 | * @param value The array to wrap.
128 | */
129 | export declare function guids(value: string[] | ReadonlyArray): Typed;
130 | /**
131 | * Explicitly wrap the specified array as a typed list of bytes.
132 | * @param value The array to wrap.
133 | */
134 | export declare function bytes(value: number[] | ReadonlyArray): Typed;
135 | /**
136 | * Explicitly wrap the specified array as a typed list of shorts.
137 | * @param value The array to wrap.
138 | */
139 | export declare function shorts(value: number[] | ReadonlyArray): Typed;
140 | /**
141 | * Explicitly wrap the specified array as a typed list of ints.
142 | * @param value The array to wrap.
143 | */
144 | export declare function ints(value: number[] | ReadonlyArray): Typed;
145 | /**
146 | * Explicitly wrap the specified array as a typed list of longs.
147 | * @param value The array to wrap.
148 | */
149 | export declare function longs(value: Long[] | ReadonlyArray): Typed;
150 | /**
151 | * Explicitly wrap the specified array as a typed list of reals.
152 | * @param value The array to wrap.
153 | */
154 | export declare function reals(value: number[] | ReadonlyArray): Typed;
155 | /**
156 | * Explicitly wrap the specified array as a typed list of floats.
157 | * @param value The array to wrap.
158 | */
159 | export declare function floats(value: number[] | ReadonlyArray): Typed;
160 | /**
161 | * Explicitly wrap the specified array as a typed list of chars.
162 | * @param value The array to wrap.
163 | */
164 | export declare function chars(value: string[] | ReadonlyArray): Typed;
165 | /**
166 | * Explicitly wrap the specified array as a typed list of symbols.
167 | * @param value The array to wrap.
168 | */
169 | export declare function symbols(value: string[] | ReadonlyArray): Typed;
170 | /**
171 | * Explicitly wrap the specified array as a typed list of timestamps.
172 | * @param value The array to wrap.
173 | */
174 | export declare function timestamps(value: Date[] | ReadonlyArray): Typed;
175 | /**
176 | * Explicitly wrap the specified array as a typed list of months.
177 | * @param value The array to wrap.
178 | */
179 | export declare function months(value: Date[] | ReadonlyArray): Typed;
180 | /**
181 | * Explicitly wrap the specified array as a typed list of dates.
182 | * @param value The array to wrap.
183 | */
184 | export declare function dates(value: Date[] | ReadonlyArray): Typed;
185 | /**
186 | * Explicitly wrap the specified array as a typed list of datetimes.
187 | * @param value The array to wrap.
188 | */
189 | export declare function datetimes(value: Date[] | ReadonlyArray): Typed;
190 | /**
191 | * Explicitly wrap the specified array as a typed list of timespans.
192 | * @param value The array to wrap.
193 | */
194 | export declare function timespans(value: Date[] | ReadonlyArray): Typed;
195 | /**
196 | * Explicitly wrap the specified array as a typed list of mibutes.
197 | * @param value The array to wrap.
198 | */
199 | export declare function minutes(value: Date[] | ReadonlyArray): Typed;
200 | /**
201 | * Explicitly wrap the specified array as a typed list of seconds.
202 | * @param value The array to wrap.
203 | */
204 | export declare function seconds(value: Date[] | ReadonlyArray): Typed;
205 | /**
206 | * Explicitly wrap the specified array as a typed list of times.
207 | * @param value The array to wrap.
208 | */
209 | export declare function times(value: Date[] | ReadonlyArray): Typed;
210 | /**
211 | * Gets a value indicating if the specified value is a Typed wrapper.
212 | * @param value The value to test for being a Typed wrapper.
213 | */
214 | export declare function isTyped(value: any): value is Typed;
215 |
--------------------------------------------------------------------------------
/lib/typed.js:
--------------------------------------------------------------------------------
1 | var assert = require("./assert.js");
2 |
3 | function Typed(type, value, valuetype) {
4 | "use strict";
5 | this._type = type;
6 | this._value = value;
7 | this._valuetype = valuetype;
8 | }
9 | Typed.prototype.type = function() {
10 | "use strict";
11 | return this._type;
12 | };
13 | Typed.prototype.value = function() {
14 | "use strict";
15 | return this._value;
16 | };
17 | Typed.prototype.valuetype = function() {
18 | "use strict";
19 | if (this._type !== "typedlist") {
20 | throw new Error("only available for type typedlist");
21 | }
22 | return this._valuetype;
23 | };
24 | Typed.prototype.toString = function() {
25 | "use strict";
26 | if (this._type === "typedlist") {
27 | return "list[" + this._valuetype + "](" + this._value + ")";
28 | }
29 | return this._type + "(" + this._value + ")";
30 | };
31 |
32 | function listOf(assertfn, values, valuetype) {
33 | "use strict";
34 | assert.array(values, "array");
35 | values.forEach(function(v) {
36 | assertfn(v, assertfn.name);
37 | });
38 | return new Typed("typedlist", values, valuetype);
39 | }
40 |
41 | exports.boolean = function(boolean) {
42 | "use strict";
43 | assert.bool(boolean, "boolean");
44 | return new Typed("boolean", boolean);
45 | };
46 | exports.booleans = function(booleans) {
47 | "use strict";
48 | return listOf(assert.bool, booleans, "boolean");
49 | };
50 |
51 | exports.guid = function(string) {
52 | "use strict";
53 | if (string !== null) {
54 | assert.string(string, "string");
55 | }
56 | return new Typed("guid", string);
57 | };
58 | exports.guids = function(strings) {
59 | "use strict";
60 | return listOf(assert.string, strings, "guid");
61 | };
62 |
63 | exports.byte = function(number) {
64 | "use strict";
65 | assert.number(number, "number");
66 | return new Typed("byte", number);
67 | };
68 | exports.bytes = function(numbers) {
69 | "use strict";
70 | return listOf(assert.number, numbers, "byte");
71 | };
72 |
73 | exports.short = function(number) {
74 | "use strict";
75 | if (number !== null) {
76 | assert.number(number, "number");
77 | }
78 | return new Typed("short", number);
79 | };
80 | exports.shorts = function(numbers) {
81 | "use strict";
82 | return listOf(assert.number, numbers, "short");
83 | };
84 |
85 | exports.int = function(number) {
86 | "use strict";
87 | if (number !== null) {
88 | assert.number(number, "number");
89 | }
90 | return new Typed("int", number);
91 | };
92 | exports.ints = function(numbers) {
93 | "use strict";
94 | return listOf(assert.number, numbers, "int");
95 | };
96 |
97 | exports.long = function(long) {
98 | "use strict";
99 | if (long !== null && long !== Infinity && long !== -Infinity) {
100 | assert.long(long, "long");
101 | }
102 | return new Typed("long", long);
103 | };
104 | exports.longs = function(longs) {
105 | "use strict";
106 | return listOf(assert.long, longs, "long");
107 | };
108 |
109 | exports.real = function(number) {
110 | "use strict";
111 | if (number !== null) {
112 | assert.number(number, "number");
113 | }
114 | return new Typed("real", number);
115 | };
116 | exports.reals = function(numbers) {
117 | "use strict";
118 | return listOf(assert.number, numbers, "real");
119 | };
120 |
121 | exports.float = function(number) {
122 | "use strict";
123 | if (number !== null) {
124 | assert.number(number, "number");
125 | }
126 | return new Typed("float", number);
127 | };
128 | exports.floats = function(numbers) {
129 | "use strict";
130 | return listOf(assert.number, numbers, "float");
131 | };
132 |
133 | exports.char = function(string) {
134 | "use strict";
135 | if (string !== null) {
136 | assert.string(string, "string");
137 | }
138 | return new Typed("char", string);
139 | };
140 | exports.chars = function(strings) {
141 | "use strict";
142 | return listOf(assert.string, strings, "char");
143 | };
144 |
145 | exports.symbol = function(string) {
146 | "use strict";
147 | if (string !== null) {
148 | assert.string(string, "string");
149 | string = string.replace(/\u0000/g, "");
150 | }
151 | return new Typed("symbol", string);
152 | };
153 | exports.symbols = function(strings) {
154 | "use strict";
155 | return listOf(assert.string, strings, "symbol");
156 | };
157 |
158 | exports.timestamp = function(date) {
159 | "use strict";
160 | if (date !== null) {
161 | assert.date(date, "date");
162 | }
163 | return new Typed("timestamp", date);
164 | };
165 | exports.timestamps = function(dates) {
166 | "use strict";
167 | return listOf(assert.date, dates, "timestamp");
168 | };
169 |
170 | exports.month = function(date) {
171 | "use strict";
172 | if (date !== null) {
173 | assert.date(date, "date");
174 | }
175 | return new Typed("month", date);
176 | };
177 | exports.months = function(dates) {
178 | "use strict";
179 | return listOf(assert.date, dates, "month");
180 | };
181 |
182 | exports.date = function(date) {
183 | "use strict";
184 | if (date !== null) {
185 | assert.date(date, "date");
186 | }
187 | return new Typed("date", date);
188 | };
189 | exports.dates = function(dates) {
190 | "use strict";
191 | return listOf(assert.date, dates, "date");
192 | };
193 |
194 | exports.datetime = function(date) {
195 | "use strict";
196 | if (date !== null) {
197 | assert.date(date, "date");
198 | }
199 | return new Typed("datetime", date);
200 | };
201 | exports.datetimes = function(dates) {
202 | "use strict";
203 | return listOf(assert.date, dates, "datetime");
204 | };
205 |
206 | exports.timespan = function(date) {
207 | "use strict";
208 | if (date !== null) {
209 | assert.date(date, "date");
210 | }
211 | return new Typed("timespan", date);
212 | };
213 | exports.timespans = function(dates) {
214 | "use strict";
215 | return listOf(assert.date, dates, "timespan");
216 | };
217 |
218 | exports.minute = function(date) {
219 | "use strict";
220 | if (date !== null) {
221 | assert.date(date, "date");
222 | }
223 | return new Typed("minute", date);
224 | };
225 | exports.minutes = function(dates) {
226 | "use strict";
227 | return listOf(assert.date, dates, "minute");
228 | };
229 |
230 | exports.second = function(date) {
231 | "use strict";
232 | if (date !== null) {
233 | assert.date(date, "date");
234 | }
235 | return new Typed("second", date);
236 | };
237 | exports.seconds = function(dates) {
238 | "use strict";
239 | return listOf(assert.date, dates, "second");
240 | };
241 |
242 | exports.time = function(date) {
243 | "use strict";
244 | if (date !== null) {
245 | assert.date(date, "date");
246 | }
247 | return new Typed("time", date);
248 | };
249 | exports.times = function(dates) {
250 | "use strict";
251 | return listOf(assert.date, dates, "time");
252 | };
253 |
254 | exports.mixedlist = function(values) {
255 | "use strict";
256 | assert.array(values, "array");
257 | return new Typed("mixedlist", values);
258 | };
259 |
260 | exports.dict = function(object) {
261 | "use strict";
262 | assert.object(object, "object");
263 | return new Typed("dict", object);
264 | };
265 |
266 | // TODO expose typed table as soon as implemented
267 | /*exports.table = function(array) {
268 | "use strict";
269 | assert.array(array, "array");
270 | return new Typed("table", array);
271 | };*/
272 |
273 | exports.Typed = Typed;
274 | exports.isTyped = function(val) {
275 | "use strict";
276 | return (val instanceof Typed);
277 | };
278 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-q",
3 | "version": "2.7.0",
4 | "description": "Q interfacing with Node.js",
5 | "keywords": [
6 | "q",
7 | "kx",
8 | "kdb+",
9 | "kdb+tick",
10 | "interfacing"
11 | ],
12 | "main": "index.js",
13 | "types": "index.d.ts",
14 | "scripts": {
15 | "test": "make test",
16 | "itest": "make itest",
17 | "prepublish": "tsc"
18 | },
19 | "author": "Michael Wittig ",
20 | "license": "MIT",
21 | "dependencies": {
22 | "buffer-indexof-polyfill": "1.0.1",
23 | "long": "3.0.3",
24 | "node-uuid": "1.4.7"
25 | },
26 | "devDependencies": {
27 | "@types/long": "^3.0.31",
28 | "@types/node": "^8.0.8",
29 | "async": "1.5.2",
30 | "istanbul": "0.4.2",
31 | "jshint": "2.9.1",
32 | "madge": "0.5.3",
33 | "mocha": "2.4.5",
34 | "moment": "2.22.2",
35 | "npmedge": "0.2.2",
36 | "typescript": "^2.4.1"
37 | },
38 | "repository": {
39 | "type": "git",
40 | "url": "https://github.com/michaelwittig/node-q.git"
41 | },
42 | "engines": {
43 | "node": ">=0.10"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/test/c.js:
--------------------------------------------------------------------------------
1 | var c = require("../lib/c.js"),
2 | typed = require("../lib/typed.js"),
3 | moment = require("moment"),
4 | assert = require("assert"),
5 | Long = require("long");
6 |
7 | function hexstr_to_bin(str) {
8 | "use strict";
9 | return new Buffer(str, "hex");
10 | }
11 |
12 | function bin_to_hexstr(b) {
13 | "use strict";
14 | return b.toString("hex");
15 | }
16 |
17 | // use -8! in q to get the byte representation
18 |
19 | describe("c", function() {
20 | "use strict";
21 | describe("deserialize", function() {
22 | describe("little", function() {
23 | describe("primitives", function() {
24 | it("boolean", function() { // 1b
25 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000ff01")), true);
26 | });
27 | describe("guid", function() {
28 | it("guid", function() { // 0a369037-75d3-b24d-6721-5a1d44d4bed5
29 | assert.equal(c.deserialize(hexstr_to_bin("0100000019000000fe0a36903775d3b24d67215a1d44d4bed5")), "0a369037-75d3-b24d-6721-5a1d44d4bed5");
30 | });
31 | it("null", function() { // 0Ng
32 | assert.equal(c.deserialize(hexstr_to_bin("0100000019000000fe00000000000000000000000000000000")), null);
33 | });
34 | });
35 | it("byte", function() { // 0x01
36 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000fc01")), "1");
37 | });
38 | describe("short", function() {
39 | it("1", function() { // 1h
40 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000fb0100")), 1);
41 | });
42 | it("-1", function() { // -1h
43 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000fbffff")), -1);
44 | });
45 | it("null", function() { // 0Nh
46 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000fb0080")), null);
47 | });
48 | it("Infinity", function() { // 0wh
49 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000fbff7f")), Infinity);
50 | });
51 | it("-Infinity", function() { // -0wh
52 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000fb0180")), -Infinity);
53 | });
54 | });
55 | describe("integer", function() {
56 | it("1", function() { // 1i
57 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000fa01000000")), 1);
58 | });
59 | it("-1", function() { // -1i
60 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000faffffffff")), -1);
61 | });
62 | it("null", function() { // 0Ni
63 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000fa00000080")), null);
64 | });
65 | it("Infinity", function() { // 0wi
66 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000faffffff7f")), Infinity);
67 | });
68 | it("-Infinity", function() { // -0wi
69 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000fa01000080")), -Infinity);
70 | });
71 | });
72 | describe("long", function() {
73 | describe("long2number", function() {
74 | describe("default", function() {
75 | it("1", function() { // 1j
76 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000000")), 1);
77 | });
78 | it("-1", function() { // -1j
79 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffffff")), -1);
80 | });
81 | it("2147483647", function() { // 2147483647j
82 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffff7f00000000")), 2147483647);
83 | });
84 | it("2147483648", function() { // 2147483648j
85 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000008000000000")), 2147483648);
86 | });
87 | it("2147483649", function() { // 2147483649j
88 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100008000000000")), 2147483649);
89 | });
90 | it("4294967295", function() { // 4294967295j
91 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffff00000000")), 4294967295);
92 | });
93 | it("4294967296", function() { // 4294967296j
94 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000001000000")), 4294967296);
95 | });
96 | it("4294967297", function() { // 4294967297j
97 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000001000000")), 4294967297);
98 | });
99 | it("null", function() { // 0Nj
100 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000000000080")), null);
101 | });
102 | it("Infinity", function() { // 0wj
103 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffff7f")), Infinity);
104 | });
105 | it("-Infinity", function() { // -0wj
106 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000080")), -Infinity);
107 | });
108 | });
109 | describe("false", function() {
110 | it("1", function() { // 1j
111 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000000"), undefined, undefined, undefined, false).toNumber(), 1);
112 | });
113 | it("-1", function() { // -1j
114 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffffff"), undefined, undefined, undefined, false).toNumber(), -1);
115 | });
116 | it("2147483647", function() { // 2147483647j
117 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffff7f00000000"), undefined, undefined, undefined, false).toNumber(), 2147483647);
118 | });
119 | it("2147483648", function() { // 2147483648j
120 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000008000000000"), undefined, undefined, undefined, false).toNumber(), 2147483648);
121 | });
122 | it("2147483649", function() { // 2147483649j
123 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100008000000000"), undefined, undefined, undefined, false).toNumber(), 2147483649);
124 | });
125 | it("4294967295", function() { // 4294967295j
126 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffff00000000"), undefined, undefined, undefined, false).toNumber(), 4294967295);
127 | });
128 | it("4294967296", function() { // 4294967296j
129 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000001000000"), undefined, undefined, undefined, false).toNumber(), 4294967296);
130 | });
131 | it("4294967297", function() { // 4294967297j
132 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000001000000"), undefined, undefined, undefined, false).toNumber(), 4294967297);
133 | });
134 | it("null", function() { // 0Nj
135 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000000000080"), undefined, undefined, undefined, false), null);
136 | });
137 | it("Infinity", function() { // 0wj
138 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffff7f"), undefined, undefined, undefined, false), Infinity);
139 | });
140 | it("-Infinity", function() { // -0wj
141 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000080"), undefined, undefined, undefined, false), -Infinity);
142 | });
143 | });
144 | describe("true", function() {
145 | it("1", function() { // 1j
146 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000000"), undefined, undefined, undefined, true), 1);
147 | });
148 | it("-1", function() { // -1j
149 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffffff"), undefined, undefined, undefined, true), -1);
150 | });
151 | it("2147483647", function() { // 2147483647j
152 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffff7f00000000"), undefined, undefined, undefined, true), 2147483647);
153 | });
154 | it("2147483648", function() { // 2147483648j
155 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000008000000000"), undefined, undefined, undefined, true), 2147483648);
156 | });
157 | it("2147483649", function() { // 2147483649j
158 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100008000000000"), undefined, undefined, undefined, true), 2147483649);
159 | });
160 | it("4294967295", function() { // 4294967295j
161 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffff00000000"), undefined, undefined, undefined, true), 4294967295);
162 | });
163 | it("4294967296", function() { // 4294967296j
164 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000001000000"), undefined, undefined, undefined, true), 4294967296);
165 | });
166 | it("4294967297", function() { // 4294967297j
167 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000001000000"), undefined, undefined, undefined, true), 4294967297);
168 | });
169 | it("null", function() { // 0Nj
170 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90000000000000080"), undefined, undefined, undefined, true), null);
171 | });
172 | it("Infinity", function() { // 0wj
173 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f9ffffffffffffff7f"), undefined, undefined, undefined, true), Infinity);
174 | });
175 | it("-Infinity", function() { // -0wj
176 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f90100000000000080"), undefined, undefined, undefined, true), -Infinity);
177 | });
178 | });
179 | });
180 | });
181 | describe("real", function() {
182 | it("1", function() { // 1e
183 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f80000803f")), 1.0);
184 | });
185 | it("-1", function() { // -1e
186 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f8000080bf")), -1.0);
187 | });
188 | it("null", function() { // 0Ne
189 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f80000c0ff")), null);
190 | });
191 | it("Infinity", function() { // 0we
192 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f80000807f")), Infinity);
193 | });
194 | it("-Infinity", function() { // -0we
195 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f8000080ff")), -Infinity);
196 | });
197 | });
198 | describe("float", function() {
199 | it("1", function() { // 1f
200 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f7000000000000f03f")), 1.0);
201 | });
202 | it("-1", function() { // -1f
203 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f7000000000000f0bf")), -1.0);
204 | });
205 | it("null", function() { // 0Nf
206 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f7000000000000f8ff")), null);
207 | });
208 | it("Infinity", function() { // 0wf
209 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f7000000000000f07f")), Infinity);
210 | });
211 | it("-Infinity", function() { // -0wf
212 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f7000000000000f0ff")), -Infinity);
213 | });
214 | });
215 | describe("char", function() {
216 | describe("emptyChar2null", function() {
217 | describe("default", function() {
218 | it("a", function() { // "a"
219 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f661")), "a");
220 | });
221 | it("null", function() { // " "
222 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f620")), null);
223 | });
224 | });
225 | describe("true", function() {
226 | it("a", function() { // "a"
227 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f661"), undefined, undefined, true), "a");
228 | });
229 | it("null", function() { // " "
230 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f620"), undefined, undefined, true), null);
231 | });
232 | });
233 | describe("false", function() {
234 | it("a", function() { // "a"
235 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f661"), undefined, undefined, false), "a");
236 | });
237 | it("null", function() { // " "
238 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f620"), undefined, undefined, false), " ");
239 | });
240 | });
241 | });
242 | });
243 | describe("symbol", function() {
244 | it("length 1", function() { // `a
245 | assert.equal(c.deserialize(hexstr_to_bin("010000000b000000f56100")), "a");
246 | });
247 | it("null", function() { // `
248 | assert.equal(c.deserialize(hexstr_to_bin("010000000a000000f500")), null);
249 | });
250 | it("length 2", function() { // `ab
251 | assert.equal(c.deserialize(hexstr_to_bin("010000000c000000f5616200")), "ab");
252 | });
253 | it("length 3", function() { // `abc
254 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f561626300")), "abc");
255 | });
256 | it("length 4", function() { // `abcd
257 | assert.equal(c.deserialize(hexstr_to_bin("010000000e000000f56162636400")), "abcd");
258 | });
259 | it("lenth 5", function() { // `abcde
260 | assert.equal(c.deserialize(hexstr_to_bin("010000000f000000f5616263646500")), "abcde");
261 | });
262 | it("unicode length 1", function() { // `$"你"
263 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f5e4bda000")), "你");
264 | });
265 | it("unicode length 2", function() { // `$"你好"
266 | assert.equal(c.deserialize(hexstr_to_bin("0100000010000000f5e4bda0e5a5bd00")), "你好");
267 | });
268 | });
269 | describe("nanos2date", function() {
270 | describe("default", function() {
271 | it("deserialize_timestamp_little_test", function() { // 2014.06.23D11:34:39.412547000
272 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f4b84d1d352d045706")).getTime(), moment.utc("2014.06.23 11:34:39.412547000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
273 | });
274 | it("deserialize_timestamp_null_little_test", function() { // 0Np
275 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f40000000000000080")), null);
276 | });
277 | it("deserialize_timespan_little_test", function() { // 00:01:00.000000000
278 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f0005847f80d000000")).getTime(), moment.utc("2000.01.01 00:01:00.000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
279 | });
280 | it("deserialize_timespan_null_little_test", function() { // 0Nn
281 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f00000000000000080")), null);
282 | });
283 | });
284 | describe("true", function() {
285 | it("deserialize_timestamp_little_test", function() { // 2014.06.23D11:34:39.412547000
286 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f4b84d1d352d045706"), true).getTime(), moment.utc("2014.06.23 11:34:39.412547000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
287 | });
288 | it("deserialize_timestamp_null_little_test", function() { // 0Np
289 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f40000000000000080"), true), null);
290 | });
291 | it("deserialize_timespan_little_test", function() { // 00:01:00.000000000
292 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f0005847f80d000000"), true).getTime(), moment.utc("2000.01.01 00:01:00.000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
293 | });
294 | it("deserialize_timespan_null_little_test", function() { // 0Nn
295 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f00000000000000080"), true), null);
296 | });
297 | });
298 | describe("false", function() {
299 | it("deserialize_timestamp_little_test", function() { // 2014.06.23D11:34:39.412547000
300 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f4b84d1d352d045706"), false), 1403523279412547000);
301 | });
302 | it("deserialize_timestamp_null_little_test", function() { // 0Np
303 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f40000000000000080"), false), null);
304 | });
305 | it("deserialize_timespan_little_test", function() { // 00:01:00.000000000
306 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f0005847f80d000000"), false), 60000000000);
307 | });
308 | it("deserialize_timespan_null_little_test", function() { // 0Nn
309 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f00000000000000080"), false), null);
310 | });
311 | });
312 | });
313 | describe("month", function() {
314 | it("201401", function() { // 2014.01m
315 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f3a8000000")).getTime(), moment.utc("2014.01", "YYYY.MM").toDate().getTime());
316 | });
317 | it("null", function() { // 0Nm
318 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f300000080")), null);
319 | });
320 | it("199501", function() { // 1995.01m
321 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f3c4ffffff")).getTime(), moment.utc("1995.01", "YYYY.MM").toDate().getTime());
322 | });
323 | });
324 | describe("date", function() {
325 | it("20140101", function() { // 2014.01.01
326 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f2fa130000")).getTime(), moment.utc("2014.01.91", "YYYY.MM").toDate().getTime());
327 | });
328 | it("null", function() { // 0Nd
329 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f200000080")), null);
330 | });
331 | it("19950101", function() { // 1995.01.01
332 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000f2def8ffff")).getTime(), moment.utc("1995.01.01", "YYYY.MM").toDate().getTime());
333 | });
334 | });
335 | describe("datetime", function() {
336 | it("datetime", function() { // 2014.06.23T11:49:31.533
337 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f1facf4b237ea7b440")).getTime(), moment.utc("2014.06.23 11:49:31.533", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
338 | });
339 | it("null", function() { // 0Nz
340 | assert.equal(c.deserialize(hexstr_to_bin("0100000011000000f1000000000000f8ff")), null);
341 | });
342 | });
343 | describe("minute", function() {
344 | it("00:01", function() { // 00:01
345 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ef01000000")).getTime(), moment.utc("2000.01.01 00:01:00.000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
346 | });
347 | it("null", function() { // 0Nu
348 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ef00000080")), null);
349 | });
350 | });
351 | describe("second", function() {
352 | it("00:00:01", function() { // 00:00:01
353 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ee01000000")).getTime(), moment.utc("2000.01.01 00:00:01.000", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
354 | });
355 | it("null", function() { // 0Nv
356 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ee00000080")), null);
357 | });
358 | });
359 | describe("time", function() {
360 | it("00:00:00.001", function() { // 00:00:00.001
361 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ed01000000")).getTime(), moment.utc("2000.01.01 00:00:00.001", "YYYY.MM.DD HH:mm:ss.SSS").toDate().getTime());
362 | });
363 | it("null", function() { // 0Nt
364 | assert.equal(c.deserialize(hexstr_to_bin("010000000d000000ed00000080")), null);
365 | });
366 | });
367 | });
368 | describe("list", function() {
369 | it("empty", function() {
370 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000000e000000000000000000")), []);
371 | });
372 | it("generic", function() { // (1j;1b;3h)
373 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001c000000000003000000f90100000000000000ff01fb0300")), [1, true, 3]);
374 | });
375 | it("null", function() { // (::;::;::)
376 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000014000000000003000000650065006500")), [null, null, null]);
377 | });
378 | describe("list of list", function() {
379 | it("same types", function() { // enlist (1f;2f;3f)
380 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000002c000000000001000000090003000000000000000000f03f00000000000000400000000000000840")), [[1, 2, 3]]);
381 | });
382 | it("different types", function() { // enlist (1f;1b;3h)
383 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000022000000000001000000000003000000f7000000000000f03fff01fb0300")), [[1, true, 3]]);
384 | });
385 | });
386 | describe("boolean", function() {
387 | it("single", function() {
388 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000000f00000001000100000001")), [true]);
389 | });
390 | it("multi", function() {
391 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000011000000010003000000010001")), [true, false, true]);
392 | });
393 | });
394 | describe("guid", function() {
395 | it("single", function() {
396 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001e000000020001000000daedb4cc85f44ba0e3083c62191c0865")), ["daedb4cc-85f4-4ba0-e308-3c62191c0865"]);
397 | });
398 | it("multi", function() {
399 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000003e000000020003000000ca3b0039fc23f2892c3769d4a24fe17cc73d1b400fce85c1a78fb653c8c6d022f4f58976d8cad4c10db7d102c6f91025")), ["ca3b0039-fc23-f289-2c37-69d4a24fe17c", "c73d1b40-0fce-85c1-a78f-b653c8c6d022", "f4f58976-d8ca-d4c1-0db7-d102c6f91025"]);
400 | });
401 | });
402 | describe("byte", function() {
403 | it("single", function() {
404 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000000f00000004000100000001")), [1]);
405 | });
406 | it("multi", function() {
407 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000011000000040003000000010203")), [1, 2, 3]);
408 | });
409 | });
410 | describe("short", function() {
411 | it("single", function() {
412 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000100000000500010000000100")), [1]);
413 | });
414 | it("multi", function() {
415 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000014000000050003000000010002000300")), [1, 2, 3]);
416 | });
417 | });
418 | describe("int", function() {
419 | it("single", function() {
420 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001200000006000100000001000000")), [1]);
421 | });
422 | it("multi", function() {
423 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a000000060003000000010000000200000003000000")), [1, 2, 3]);
424 | });
425 | });
426 | describe("long", function() {
427 | it("single", function() {
428 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000160000000700010000000100000000000000")), [1]);
429 | });
430 | it("multi", function() {
431 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000026000000070003000000010000000000000002000000000000000300000000000000")), [1, 2, 3]);
432 | });
433 | });
434 | describe("real", function() {
435 | it("single", function() {
436 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000120000000800010000000000803f")), [1]);
437 | });
438 | it("multi", function() {
439 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a0000000800030000000000803f0000004000004040")), [1, 2, 3]);
440 | });
441 | });
442 | describe("float", function() {
443 | it("single", function() {
444 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000016000000090001000000000000000000f03f")), [1]);
445 | });
446 | it("multi", function() {
447 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000026000000090003000000000000000000f03f00000000000000400000000000000840")), [1, 2, 3]);
448 | });
449 | });
450 | describe("char", function() {
451 | it("single", function() {
452 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000000f0000000a000100000061")), "a");
453 | });
454 | it("multi", function() {
455 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000100000000a00020000006162")), "ab");
456 | });
457 | it("unicode", function() { // "你好"
458 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000140000000a0006000000e4bda0e5a5bd")), "你好");
459 | });
460 | });
461 | describe("symbol", function() {
462 | it("single", function() {
463 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000100000000b00010000006100")), ["a"]);
464 | });
465 | it("multi", function() {
466 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000170000000b0003000000610061620061626300")), ["a", "ab", "abc"]);
467 | });
468 | });
469 | describe("timestamp", function() {
470 | describe("nanos2date", function() {
471 | describe("default", function() {
472 | it("single", function() { // 2014.06.23D11:34:39.412547000
473 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000160000000c0001000000b84d1d352d045706")), [new Date("2014-06-23T11:34:39.412")]);
474 | });
475 | it("multi", function() { // 2014.06.23D11:34:39.412547000
476 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000260000000c0003000000b84d1d352d045706b84d5f3c96396006b84df0d493bd6906")), [new Date("2014-06-23T11:34:39.412"), new Date("2014-07-23T11:34:39.412"), new Date("2014-08-23T11:34:39.412")]);
477 | });
478 | });
479 | describe("true", function() {
480 | it("single", function() { // 2014.06.23D11:34:39.412547000
481 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000160000000c0001000000b84d1d352d045706"), true), [new Date("2014-06-23T11:34:39.412")]);
482 | });
483 | it("multi", function() { // 2014.06.23D11:34:39.412547000
484 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000260000000c0003000000b84d1d352d045706b84d5f3c96396006b84df0d493bd6906"), true), [new Date("2014-06-23T11:34:39.412"), new Date("2014-07-23T11:34:39.412"), new Date("2014-08-23T11:34:39.412")]);
485 | });
486 | });
487 | describe("false", function() {
488 | it("single", function() { // 2014.06.23D11:34:39.412547000
489 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000160000000c0001000000b84d1d352d045706"), false), [1403523279412547000]);
490 | });
491 | it("multi", function() { // 2014.06.23D11:34:39.412547000
492 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000260000000c0003000000b84d1d352d045706b84d5f3c96396006b84df0d493bd6906"), false), [1403523279412547000, 1406115279412547000, 1408793679412547000]);
493 | });
494 | });
495 | });
496 | });
497 | describe("month", function() {
498 | it("single", function() { // 1997.01m
499 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000120000000d0001000000dcffffff")), [new Date("1997-01-01T00:00:00.000")]);
500 | });
501 | it("multi", function() {
502 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a0000000d0003000000dcffffffe8fffffff4ffffff")), [new Date("1997-01-01T00:00:00.000"), new Date("1998-01-01T00:00:00.000"), new Date("1999-01-01T00:00:00.000")]);
503 | });
504 | });
505 | describe("date", function() {
506 | it("single", function() { // 1997.01.01
507 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000120000000e0001000000b9fbffff")), [new Date("1997-01-01T00:00:00.000")]);
508 | });
509 | it("multi", function() {
510 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a0000000e0003000000b9fbffff26fdffff93feffff")), [new Date("1997-01-01T00:00:00.000"), new Date("1998-01-01T00:00:00.000"), new Date("1999-01-01T00:00:00.000")]);
511 | });
512 | });
513 | describe("datetime", function() {
514 | it("single", function() { // 2001.01.01T00:00:00.000
515 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000160000000f00010000000000000000e07640")), [new Date("2001-01-01T00:00:00.000")]);
516 | });
517 | it("multi", function() {
518 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000260000000f00030000000000000000e076400000000000d078400000000000907a40")), [new Date("2001-01-01T00:00:00.000"), new Date("2001-02-01T00:00:00.000"), new Date("2001-03-01T00:00:00.000")]);
519 | });
520 | });
521 | describe("timespan", function() {
522 | describe("nanos2date", function() {
523 | describe("default", function() {
524 | it("single", function() { // 00:01:00.000000000
525 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000016000000100001000000005847f80d000000")), [new Date("2000-01-01T00:01:00.000")]);
526 | });
527 | it("multi", function() { // 00:01:00.000000000
528 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000026000000100003000000005847f80d00000000b08ef01b0000000008d6e829000000")), [new Date("2000-01-01T00:01:00.000"), new Date("2000-01-01T00:02:00.000"), new Date("2000-01-01T00:03:00.000")]);
529 | });
530 | });
531 | describe("true", function() {
532 | it("single", function() { // 00:01:00.000000000
533 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000016000000100001000000005847f80d000000"), true), [new Date("2000-01-01T00:01:00.000")]);
534 | });
535 | it("multi", function() { // 00:01:00.000000000
536 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000026000000100003000000005847f80d00000000b08ef01b0000000008d6e829000000"), true), [new Date("2000-01-01T00:01:00.000"), new Date("2000-01-01T00:02:00.000"), new Date("2000-01-01T00:03:00.000")]);
537 | });
538 | });
539 | describe("false", function() {
540 | it("single", function() { // 00:01:00.000000000
541 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000016000000100001000000005847f80d000000"), false), [60000000000]);
542 | });
543 | it("multi", function() { // 00:01:00.000000000
544 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000026000000100003000000005847f80d00000000b08ef01b0000000008d6e829000000"), false), [60000000000, 120000000000, 180000000000]);
545 | });
546 | });
547 | });
548 | });
549 | describe("minute", function() {
550 | it("single", function() { // 00:01
551 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001200000011000100000001000000")), [new Date("2000-01-01T00:01:00.000")]);
552 | });
553 | it("multi", function() {
554 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a000000110003000000010000000200000003000000")), [new Date("2000-01-01T00:01:00.000"), new Date("2000-01-01T00:02:00.000"), new Date("2000-01-01T00:03:00.000")]);
555 | });
556 | });
557 | describe("second", function() {
558 | it("single", function() { // 00:00:01
559 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001200000012000100000001000000")), [new Date("2000-01-01T00:00:01.000")]);
560 | });
561 | it("multi", function() {
562 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a000000120003000000010000000200000003000000")), [new Date("2000-01-01T00:00:01.000"), new Date("2000-01-01T00:00:02.000"), new Date("2000-01-01T00:00:03.000")]);
563 | });
564 | });
565 | describe("time", function() {
566 | it("single", function() { // 00:00:00.001
567 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001200000013000100000001000000")), [new Date("2000-01-01T00:00:00.001")]);
568 | });
569 | it("multi", function() {
570 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001a000000130003000000010000000200000003000000")), [new Date("2000-01-01T00:00:00.001"), new Date("2000-01-01T00:00:00.002"), new Date("2000-01-01T00:00:00.003")]);
571 | });
572 | });
573 | });
574 | describe("dict", function() {
575 | it("empty", function() {
576 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001500000063000000000000000000000000")), {});
577 | });
578 | it("single entry", function() {
579 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000001f000000630b000100000061000700010000000100000000000000")), {a: 1});
580 | });
581 | it("multiple entries same type", function() {
582 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000033000000630b0003000000610062006300070003000000010000000000000002000000000000000300000000000000")), {a: 1, b: 2, c: 3});
583 | });
584 | it("multiple entries different types", function() {
585 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000002f000000630b0003000000610062006300000003000000f90100000000000000ff01f70000000000000840")), {a: 1, b: true, c: 3});
586 | });
587 | it("multiple entries, null values", function() {
588 | assert.deepEqual(c.deserialize(hexstr_to_bin("0100000021000000630b0003000000610062006300000003000000650065006500")), {a: null, b: null, c: null});
589 | });
590 | });
591 | describe("table", function() {
592 | describe("flipTables", function() {
593 | describe("default", function() {
594 | it("multiple rows", function() {
595 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000620000006200630b0003000000610062006300000003000000070003000000010000000000000002000000000000000300000000000000010003000000010001090003000000000000000000f03f00000000000000400000000000000840")), [{a: 1, b: true, c: 1}, {a: 2, b: false, c: 2}, {a: 3, b: true, c: 3}]);
596 | });
597 | it("no rows", function() {
598 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000002f0000006200630b0003000000610062006300000003000000070000000000010000000000090000000000")), []);
599 | });
600 | });
601 | describe("true", function() {
602 | it("multiple rows", function() {
603 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000620000006200630b0003000000610062006300000003000000070003000000010000000000000002000000000000000300000000000000010003000000010001090003000000000000000000f03f00000000000000400000000000000840"), undefined, true), [{a: 1, b: true, c: 1}, {a: 2, b: false, c: 2}, {a: 3, b: true, c: 3}]);
604 | });
605 | it("no rows", function() {
606 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000002f0000006200630b0003000000610062006300000003000000070000000000010000000000090000000000"), undefined, true), []);
607 | });
608 | });
609 | describe("false", function() {
610 | it("multiple rows", function() {
611 | assert.deepEqual(c.deserialize(hexstr_to_bin("01000000620000006200630b0003000000610062006300000003000000070003000000010000000000000002000000000000000300000000000000010003000000010001090003000000000000000000f03f00000000000000400000000000000840"), undefined, false), {a: [1, 2, 3], b: [true, false, true], c: [1, 2, 3]});
612 | });
613 | it("no rows", function() {
614 | assert.deepEqual(c.deserialize(hexstr_to_bin("010000002f0000006200630b0003000000610062006300000003000000070000000000010000000000090000000000"), undefined, false), {a: [], b: [], c: []});
615 | });
616 | });
617 | });
618 | });
619 | });
620 | });
621 | describe("serialize", function() {
622 | describe("infer type", function() {
623 | describe("little", function() {
624 | it("Boolean", function() {
625 | assert.equal(bin_to_hexstr(c.serialize(true)), "010000000a000000ff01");
626 | });
627 | it("symbol length 1", function() {
628 | assert.equal(bin_to_hexstr(c.serialize("`a")), "010000000b000000f56100");
629 | });
630 | it("symbol unicode length 1", function() {
631 | assert.equal(bin_to_hexstr(c.serialize("`你")), "010000000d000000f5e4bda000");
632 | });
633 | it("symbol unicode length 2", function() {
634 | assert.equal(bin_to_hexstr(c.serialize("`你好")), "0100000010000000f5e4bda0e5a5bd00");
635 | });
636 | it("symbol length 2", function() { // `ab
637 | assert.equal(bin_to_hexstr(c.serialize("`ab")), "010000000c000000f5616200");
638 | });
639 | it("symbol length 3", function() { // `abc
640 | assert.equal(bin_to_hexstr(c.serialize("`abc")), "010000000d000000f561626300");
641 | });
642 | it("symbol length 4", function() { // `abcd
643 | assert.equal(bin_to_hexstr(c.serialize("`abcd")), "010000000e000000f56162636400");
644 | });
645 | it("symbol length 5", function() { // `abcde
646 | assert.equal(bin_to_hexstr(c.serialize("`abcde")), "010000000f000000f5616263646500");
647 | });
648 | it("String", function() {
649 | assert.equal(bin_to_hexstr(c.serialize("abc")), "01000000110000000a0003000000616263");
650 | });
651 | it("Number", function() {
652 | assert.equal(bin_to_hexstr(c.serialize(1.0)), "0100000011000000f7000000000000f03f");
653 | });
654 | it("Date", function() {
655 | assert.equal(bin_to_hexstr(c.serialize(new Date("2014-06-23T11:49:31.533"))), "0100000011000000f1facf4b237ea7b440");
656 | });
657 | describe("Object", function() {
658 | it("one key", function() {
659 | assert.equal(bin_to_hexstr(c.serialize({a: 1})), "010000001f000000630b00010000006100090001000000000000000000f03f");
660 | });
661 | it("one key, null value", function() {
662 | assert.equal(bin_to_hexstr(c.serialize({a: null})), "0100000019000000630b000100000061000000010000006500");
663 | });
664 | it("multiple keys, same value type", function() {
665 | assert.equal(bin_to_hexstr(c.serialize({a: 1, b: 2, c: 3})), "0100000033000000630b0003000000610062006300090003000000000000000000f03f00000000000000400000000000000840");
666 | });
667 | it("multiple keys, different value types", function() {
668 | assert.equal(bin_to_hexstr(c.serialize({a: 1, b: true, c: 3})), "010000002f000000630b0003000000610062006300000003000000f7000000000000f03fff01f70000000000000840");
669 | });
670 | it("multiple keys, null value", function() {
671 | assert.equal(bin_to_hexstr(c.serialize({a: null, b: null, c: null})), "0100000021000000630b0003000000610062006300000003000000650065006500");
672 | });
673 | });
674 | describe("Array", function() {
675 | it("empty", function() {
676 | assert.equal(bin_to_hexstr(c.serialize([])), "010000000e000000000000000000");
677 | });
678 | it("one element", function() {
679 | assert.equal(bin_to_hexstr(c.serialize([1])), "0100000016000000090001000000000000000000f03f");
680 | });
681 | it("multiple elements, same types", function() {
682 | assert.equal(bin_to_hexstr(c.serialize([1, 2, 3])), "0100000026000000090003000000000000000000f03f00000000000000400000000000000840");
683 | });
684 | it("multiple elements, different types", function() {
685 | assert.equal(bin_to_hexstr(c.serialize([1, true, 3])), "0100000022000000000003000000f7000000000000f03fff01f70000000000000840");
686 | });
687 | it("Array of Array same type", function() {
688 | assert.equal(bin_to_hexstr(c.serialize([[1, 2, 3]])), "010000002c000000000001000000090003000000000000000000f03f00000000000000400000000000000840");
689 | });
690 | it("Array of Array different types", function() {
691 | assert.equal(bin_to_hexstr(c.serialize([[1, true, 3]])), "0100000028000000000001000000000003000000f7000000000000f03fff01f70000000000000840");
692 | });
693 | it("one null", function() {
694 | assert.equal(bin_to_hexstr(c.serialize([null])), "01000000100000000000010000006500");
695 | });
696 | it("three nulls", function() {
697 | assert.equal(bin_to_hexstr(c.serialize([null, null, null])), "0100000014000000000003000000650065006500");
698 | });
699 | });
700 | it("Null", function() {
701 | assert.equal(bin_to_hexstr(c.serialize(null)), "010000000a0000006500");
702 | });
703 | it("Infinity", function() {
704 | assert.equal(bin_to_hexstr(c.serialize(Infinity)), "0100000011000000f7000000000000f07f");
705 | });
706 | it("-Infinity", function() {
707 | assert.equal(bin_to_hexstr(c.serialize(-Infinity)), "0100000011000000f7000000000000f0ff");
708 | });
709 | });
710 | });
711 | describe("typed", function() {
712 | describe("little", function() {
713 | describe("primitives", function() {
714 | it("boolean", function() { // 1b
715 | assert.equal(bin_to_hexstr(c.serialize(typed.boolean(true))), "010000000a000000ff01");
716 | });
717 | describe("guid", function() {
718 | it("guid", function() { // 0a369037-75d3-b24d-6721-5a1d44d4bed5
719 | assert.equal(bin_to_hexstr(c.serialize(typed.guid("0a369037-75d3-b24d-6721-5a1d44d4bed5"))), "0100000019000000fe0a36903775d3b24d67215a1d44d4bed5");
720 | });
721 | it("null", function() { // 0Ng
722 | assert.equal(bin_to_hexstr(c.serialize(typed.guid(null))), "0100000019000000fe00000000000000000000000000000000");
723 | });
724 | });
725 | it("byte", function() { // 0x01
726 | assert.equal(bin_to_hexstr(c.serialize(typed.byte(1))), "010000000a000000fc01");
727 | });
728 | describe("short", function() {
729 | it("1", function() { // 1h
730 | assert.equal(bin_to_hexstr(c.serialize(typed.short(1))), "010000000b000000fb0100");
731 | });
732 | it("-1", function() { // -1h
733 | assert.equal(bin_to_hexstr(c.serialize(typed.short(-1))), "010000000b000000fbffff");
734 | });
735 | it("null", function() { // 0Nh
736 | assert.equal(bin_to_hexstr(c.serialize(typed.short(null))), "010000000b000000fb0080");
737 | });
738 | it("Infinity", function() { // 0wh
739 | assert.equal(bin_to_hexstr(c.serialize(typed.short(Infinity))), "010000000b000000fbff7f");
740 | });
741 | it("-Infinity", function() { // -0wh
742 | assert.equal(bin_to_hexstr(c.serialize(typed.short(-Infinity))), "010000000b000000fb0180");
743 | });
744 | });
745 | describe("integer", function() {
746 | it("1", function() { // 1i
747 | assert.equal(bin_to_hexstr(c.serialize(typed.int(1))), "010000000d000000fa01000000");
748 | });
749 | it("-1", function() { // -1i
750 | assert.equal(bin_to_hexstr(c.serialize(typed.int(-1))), "010000000d000000faffffffff");
751 | });
752 | it("null", function() { // 0Ni
753 | assert.equal(bin_to_hexstr(c.serialize(typed.int(null))), "010000000d000000fa00000080");
754 | });
755 | it("Infinity", function() { // 0wi
756 | assert.equal(bin_to_hexstr(c.serialize(typed.int(Infinity))), "010000000d000000faffffff7f");
757 | });
758 | it("-Infinity", function() { // -0wi
759 | assert.equal(bin_to_hexstr(c.serialize(typed.int(-Infinity))), "010000000d000000fa01000080");
760 | });
761 | });
762 | describe("long", function() {
763 | it("1", function() { // 1j
764 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("1", false, 10)))), "0100000011000000f90100000000000000");
765 | });
766 | it("-1", function() { // -1j
767 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("-1", false, 10)))), "0100000011000000f9ffffffffffffffff");
768 | });
769 | it("2147483647", function() { // 2147483647j
770 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("2147483647", false, 10)))), "0100000011000000f9ffffff7f00000000");
771 | });
772 | it("2147483648", function() { // 2147483648j
773 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("2147483648", false, 10)))), "0100000011000000f90000008000000000");
774 | });
775 | it("2147483649", function() { // 2147483649j
776 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("2147483649", false, 10)))), "0100000011000000f90100008000000000");
777 | });
778 | it("4294967295", function() { // 4294967295j
779 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("4294967295", false, 10)))), "0100000011000000f9ffffffff00000000");
780 | });
781 | it("4294967296", function() { // 4294967296j
782 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("4294967296", false, 10)))), "0100000011000000f90000000001000000");
783 | });
784 | it("4294967297", function() { // 4294967297j
785 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Long.fromString("4294967297", false, 10)))), "0100000011000000f90100000001000000");
786 | });
787 | it("null", function() { // 0Nj
788 | assert.equal(bin_to_hexstr(c.serialize(typed.long(null))), "0100000011000000f90000000000000080");
789 | });
790 | it("Infinity", function() { // 0wj
791 | assert.equal(bin_to_hexstr(c.serialize(typed.long(Infinity))), "0100000011000000f9ffffffffffffff7f");
792 | });
793 | it("-Infinity", function() { // -0wj
794 | assert.equal(bin_to_hexstr(c.serialize(typed.long(-Infinity))), "0100000011000000f90100000000000080");
795 | });
796 | });
797 | describe("real", function() {
798 | it("1", function() { // 1e
799 | assert.equal(bin_to_hexstr(c.serialize(typed.real(1.0))), "010000000d000000f80000803f");
800 | });
801 | it("-1", function() { // -1e
802 | assert.equal(bin_to_hexstr(c.serialize(typed.real(-1.0))), "010000000d000000f8000080bf");
803 | });
804 | it("null", function() { // 0Ne
805 | assert.equal(bin_to_hexstr(c.serialize(typed.real(null))), "010000000d000000f80000c0ff");
806 | });
807 | it("Infinity", function() { // 0we
808 | assert.equal(bin_to_hexstr(c.serialize(typed.real(Infinity))), "010000000d000000f80000807f");
809 | });
810 | it("-Infinity", function() { // -0we
811 | assert.equal(bin_to_hexstr(c.serialize(typed.real(-Infinity))), "010000000d000000f8000080ff");
812 | });
813 | });
814 | describe("float", function() {
815 | it("1", function() { // 1f
816 | assert.equal(bin_to_hexstr(c.serialize(typed.float(1.0))), "0100000011000000f7000000000000f03f");
817 | });
818 | it("-1", function() { // -1f
819 | assert.equal(bin_to_hexstr(c.serialize(typed.float(-1.0))), "0100000011000000f7000000000000f0bf");
820 | });
821 | it("null", function() { // 0Nf
822 | assert.equal(bin_to_hexstr(c.serialize(typed.float(null))), "0100000011000000f7000000000000f8ff");
823 | });
824 | it("Infinity", function() { // 0wf
825 | assert.equal(bin_to_hexstr(c.serialize(typed.float(Infinity))), "0100000011000000f7000000000000f07f");
826 | });
827 | it("-Infinity", function() { // -0wf
828 | assert.equal(bin_to_hexstr(c.serialize(typed.float(-Infinity))), "0100000011000000f7000000000000f0ff");
829 | });
830 | });
831 | describe("char", function() {
832 | it("a", function() { // "a"
833 | assert.equal(bin_to_hexstr(c.serialize(typed.char("a"))), "010000000a000000f661");
834 | });
835 | it("null", function() { // " "
836 | assert.equal(bin_to_hexstr(c.serialize(typed.char(null))), "010000000a000000f620");
837 | });
838 | });
839 | describe("symbol", function() {
840 | it("length 1", function() { // `a
841 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("a"))), "010000000b000000f56100");
842 | });
843 | it("unicode", function() { // `你
844 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("你"))), "010000000d000000f5e4bda000");
845 | });
846 | it("null", function() { // `
847 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol(null))), "010000000a000000f500");
848 | });
849 | it("length 2", function() { // `ab
850 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("ab"))), "010000000c000000f5616200");
851 | });
852 | it("length 3", function() { // `abc
853 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("abc"))), "010000000d000000f561626300");
854 | });
855 | it("length 4", function() { // `abcd
856 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("abcd"))), "010000000e000000f56162636400");
857 | });
858 | it("length 5", function() { // `abcde
859 | assert.equal(bin_to_hexstr(c.serialize(typed.symbol("abcde"))), "010000000f000000f5616263646500");
860 | });
861 | });
862 | describe("timestamp", function() {
863 | it("timestamp", function() { // 2014.06.23D11:34:39.412000000
864 | assert.equal(bin_to_hexstr(c.serialize(typed.timestamp(new Date("2014-06-23T11:34:39.412000000")))), "0100000011000000f400f514352d045706");
865 | });
866 | it("null", function() { // 0Np
867 | assert.equal(bin_to_hexstr(c.serialize(typed.timestamp(null))), "0100000011000000f40000000000000080");
868 | });
869 | });
870 | describe("month", function() {
871 | it("201401", function() { // 2014.01m
872 | assert.equal(bin_to_hexstr(c.serialize(typed.month(new Date("2014-01-01")))), "010000000d000000f3a8000000");
873 | });
874 | it("null", function() { // 0Nm
875 | assert.equal(bin_to_hexstr(c.serialize(typed.month(null))), "010000000d000000f300000080");
876 | });
877 | it("199501", function() { // 1995.01m
878 | assert.equal(bin_to_hexstr(c.serialize(typed.month(new Date("1995-01-01")))), "010000000d000000f3c4ffffff");
879 | });
880 | });
881 | describe("date", function() {
882 | it("20140101", function() { // 2014.01.01
883 | assert.equal(bin_to_hexstr(c.serialize(typed.date(new Date("2014-01-01")))), "010000000d000000f2fa130000");
884 | });
885 | it("null", function() { // 0Nd
886 | assert.equal(bin_to_hexstr(c.serialize(typed.date(null))), "010000000d000000f200000080");
887 | });
888 | it("19950101", function() { // 1995.01.01
889 | assert.equal(bin_to_hexstr(c.serialize(typed.date(new Date("1995-01-01")))), "010000000d000000f2def8ffff");
890 | });
891 | });
892 | describe("datetime", function() {
893 | it("datetime", function() { // 2014.06.23T11:49:31.533
894 | assert.equal(bin_to_hexstr(c.serialize(typed.datetime(new Date("2014-06-23T11:49:31.533")))), "0100000011000000f1facf4b237ea7b440");
895 | });
896 | it("null", function() { // 0Nz
897 | assert.equal(bin_to_hexstr(c.serialize(typed.datetime(null))), "0100000011000000f1000000000000f8ff");
898 | });
899 | });
900 | describe("timespan", function() {
901 | it("timespan", function() { // 00:01:00.000000000
902 | assert.equal(bin_to_hexstr(c.serialize(typed.timespan(new Date("2000-01-01T00:01:00.000")))), "0100000011000000f0005847f80d000000");
903 | });
904 | it("null", function() { // 0Nn
905 | assert.equal(bin_to_hexstr(c.serialize(typed.timespan(null))), "0100000011000000f00000000000000080");
906 | });
907 | });
908 | describe("minute", function() {
909 | it("minute", function() { // 00:01
910 | assert.equal(bin_to_hexstr(c.serialize(typed.minute(new Date("2000-01-01T00:01:00.000")))), "010000000d000000ef01000000");
911 | });
912 | it("null", function() { // 0Nu
913 | assert.equal(bin_to_hexstr(c.serialize(typed.minute(null))), "010000000d000000ef00000080");
914 | });
915 | });
916 | describe("second", function() {
917 | it("second", function() { // 00:00:01
918 | assert.equal(bin_to_hexstr(c.serialize(typed.second(new Date("2000-01-01T00:00:01.000")))), "010000000d000000ee01000000");
919 | });
920 | it("null", function() { // 0Nv
921 | assert.equal(bin_to_hexstr(c.serialize(typed.second(null))), "010000000d000000ee00000080");
922 | });
923 | });
924 | describe("time", function() {
925 | it("time", function() { // 00:00:00.001
926 | assert.equal(bin_to_hexstr(c.serialize(typed.time(new Date("2000-01-01T00:00:00.001")))), "010000000d000000ed01000000");
927 | });
928 | it("null", function() { // 0Nt
929 | assert.equal(bin_to_hexstr(c.serialize(typed.time(null))), "010000000d000000ed00000080");
930 | });
931 | });
932 | });
933 | describe("list", function() {
934 | describe("generic", function() {
935 | it("two values", function() {
936 | assert.equal(bin_to_hexstr(c.serialize([typed.boolean(true), typed.float(1)])), "0100000019000000000002000000ff01f7000000000000f03f");
937 | });
938 | it("three values", function() { // (1l;1b;`a)
939 | assert.equal(bin_to_hexstr(c.serialize([typed.long(Long.fromString("1", false, 10)), typed.boolean(true), typed.symbol("a")])), "010000001c000000000003000000f90100000000000000ff01f56100");
940 | });
941 | it("list of list", function() {
942 | assert.equal(bin_to_hexstr(c.serialize([typed.bytes([0, 1, 2, 3, 4])])), "01000000190000000000010000000400050000000001020304");
943 | });
944 | });
945 | describe("typed", function() {
946 | it("boolean", function() {
947 | assert.equal(bin_to_hexstr(c.serialize(typed.booleans([true, false]))), "01000000100000000100020000000100");
948 | });
949 | it("guid", function() {
950 | assert.equal(bin_to_hexstr(c.serialize(typed.guids(["0a369037-75d3-b24d-6721-5a1d44d4bed5", "0a369037-75d3-b24d-6721-5a1d44d4bed5"]))), "010000002e0000000200020000000a36903775d3b24d67215a1d44d4bed50a36903775d3b24d67215a1d44d4bed5");
951 | });
952 | it("byte", function() {
953 | assert.equal(bin_to_hexstr(c.serialize(typed.bytes([0, 1, 2, 3, 4]))), "01000000130000000400050000000001020304");
954 | });
955 | it("short", function() {
956 | assert.equal(bin_to_hexstr(c.serialize(typed.shorts([1, 2, 3]))), "0100000014000000050003000000010002000300");
957 | });
958 | it("1 integer", function() {
959 | assert.equal(bin_to_hexstr(c.serialize(typed.ints([1]))), "010000001200000006000100000001000000");
960 | });
961 | it("3 integers", function() {
962 | assert.equal(bin_to_hexstr(c.serialize(typed.ints([1, 2, 3]))), "010000001a000000060003000000010000000200000003000000");
963 | });
964 | it("long", function() { //
965 | assert.equal(bin_to_hexstr(c.serialize(typed.longs([Long.fromString("1", false, 10), Long.fromString("2", false, 10), Long.fromString("3", false, 10)]))), "0100000026000000070003000000010000000000000002000000000000000300000000000000");
966 | });
967 | it("real", function() { //
968 | assert.equal(bin_to_hexstr(c.serialize(typed.reals([1.0, 2.0, 3.0]))), "010000001a0000000800030000000000803f0000004000004040");
969 | });
970 | it("float", function() { //
971 | assert.equal(bin_to_hexstr(c.serialize(typed.floats([1.0, 2.0, 3.0]))), "0100000026000000090003000000000000000000f03f00000000000000400000000000000840");
972 | });
973 | it("char", function() { //
974 | assert.equal(bin_to_hexstr(c.serialize(typed.chars(["a", "b", "c"]))), "01000000110000000a0003000000616263");
975 | });
976 | it("symbol", function() { //
977 | assert.equal(bin_to_hexstr(c.serialize(typed.symbols(["a", "ab", "abc"]))), "01000000170000000b0003000000610061620061626300");
978 | });
979 | it("timestamp", function() { // (2014.01.01D12:00:00.000000000;2014.01.02D12:00:00.000000000;2014.01.03D12:00:00.000000000)
980 | assert.equal(bin_to_hexstr(c.serialize(typed.timestamps([new Date("2014-01-01T12:00:00.000000000"), new Date("2014-01-02T12:00:00.00000000"), new Date("2014-01-03T12:00:00.000000000")]))), "01000000260000000c00030000000080cd0c29eb210600801c9ebd39220600806b2f52882206");
981 | });
982 | it("month", function() { // (1995.01m;1995.02m;1995.03m)
983 | assert.equal(bin_to_hexstr(c.serialize(typed.months([new Date("1995-01-01"), new Date("1995-02-01"), new Date("1995-03-01")]))), "010000001a0000000d0003000000c4ffffffc5ffffffc6ffffff");
984 | });
985 | it("date", function() { // (2014.01.01;2014.01.02;2014.01.03)
986 | assert.equal(bin_to_hexstr(c.serialize(typed.dates([new Date("2014-01-01"), new Date("2014-01-02"), new Date("2014-01-03")]))), "010000001a0000000e0003000000fa130000fb130000fc130000");
987 | });
988 | it("datetime", function() { // (2014.06.23T11:49:31.533;2014.06.23T11:49:31.534;2014.06.23T11:49:31.535)
989 | assert.equal(bin_to_hexstr(c.serialize(typed.datetimes([new Date("2014-06-23T11:49:31.533"), new Date("2014-06-23T11:49:31.534"), new Date("2014-06-23T11:49:31.535")]))), "01000000260000000f0003000000facf4b237ea7b440b0014c237ea7b44066334c237ea7b440");
990 | });
991 | it("timespan", function() { // (00:01:00.000000000;00:02:00.000000000;00:03:00.000000000)
992 | assert.equal(bin_to_hexstr(c.serialize(typed.timespans([new Date("2000-01-01T00:01:00.000"), new Date("2000-01-01T00:02:00.000"), new Date("2000-01-01T00:03:00.000")]))), "0100000026000000100003000000005847f80d00000000b08ef01b0000000008d6e829000000");
993 | });
994 | it("minute", function() { // (00:01;00:02;00:03)
995 | assert.equal(bin_to_hexstr(c.serialize(typed.minutes([new Date("2000-01-01T00:01:00.000"), new Date("2000-01-01T00:02:00.000"), new Date("2000-01-01T00:03:00.000")]))), "010000001a000000110003000000010000000200000003000000");
996 | });
997 | it("second", function() { // (00:00:01;00:00:02;00:00:03)
998 | assert.equal(bin_to_hexstr(c.serialize(typed.seconds([new Date("2000-01-01T00:00:01.000"), new Date("2000-01-01T00:00:02.000"), new Date("2000-01-01T00:00:03.000")]))), "010000001a000000120003000000010000000200000003000000");
999 | });
1000 | it("time", function() { // (00:00:00.001;00:00:00.002;00:00:00.003)
1001 | assert.equal(bin_to_hexstr(c.serialize(typed.times([new Date("2000-01-01T00:00:00.001"), new Date("2000-01-01T00:00:00.002"), new Date("2000-01-01T00:00:00.003")]))), "010000001a000000130003000000010000000200000003000000");
1002 | });
1003 | });
1004 | });
1005 | it("mixedlist", function() { // (1j;1b;3h)
1006 | assert.equal(bin_to_hexstr(c.serialize(typed.mixedlist([typed.long(Long.fromString("1", false, 10)), typed.boolean(true), typed.short(3)]))), "010000001c000000000003000000f90100000000000000ff01fb0300");
1007 | });
1008 | describe("dict", function() {
1009 | it("one key", function() {
1010 | assert.equal(bin_to_hexstr(c.serialize(typed.dict({a: typed.byte(1)}))), "0100000018000000630b0001000000610004000100000001");
1011 | });
1012 | it("multiple keys, same value type", function() {
1013 | assert.equal(bin_to_hexstr(c.serialize(typed.dict({a: typed.long(Long.fromString("1", false, 10)), b: typed.long(Long.fromString("2", false, 10)), c: typed.long(Long.fromString("3", false, 10))}))), "0100000033000000630b0003000000610062006300070003000000010000000000000002000000000000000300000000000000");
1014 | });
1015 | it("multiple keys, different value types", function() {
1016 | assert.equal(bin_to_hexstr(c.serialize(typed.dict({a: typed.long(Long.fromString("1", false, 10)), b: typed.boolean(true), c: typed.float(3)}))), "010000002f000000630b0003000000610062006300000003000000f90100000000000000ff01f70000000000000840");
1017 | });
1018 | });
1019 | // TODO test serialize table
1020 | });
1021 | });
1022 | });
1023 | });
1024 |
--------------------------------------------------------------------------------
/test/compress.js:
--------------------------------------------------------------------------------
1 | var c = require("../lib/c.js"),
2 | typed = require("../lib/typed.js"),
3 | moment = require("moment"),
4 | assert = require("assert"),
5 | Long = require("long");
6 |
7 | function hexstr_to_bin(str) {
8 | "use strict";
9 | return new Buffer(str, "hex");
10 | }
11 |
12 | function bin_to_hexstr(b) {
13 | "use strict";
14 | return b.toString("hex");
15 | }
16 |
17 | // use -18! in q to get the compressed byte representation
18 |
19 | describe("compress", function() {
20 | "use strict";
21 | describe("deserialize", function() {
22 | describe("little", function() {
23 | describe("list", function() {
24 | it("booleans", function() {
25 | assert.equal(c.deserialize(hexstr_to_bin("01000100680000001e270000000100102700000101ff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ff7f00ff00ff00ff00ff00ff00ff00e6")).length, 10000);
26 | });
27 | it("guid", function() {
28 | assert.equal(c.deserialize(hexstr_to_bin("01000100b60000008e3e0000000200e803000042d8008ac824e2f268a5be80629cacef657f4252ffef42ffecffc6ff10fff2cdff1bffdcffbffeff30ff43ff8aff1aff3dff4252ffef42ffecffc6ff10fff2cdff1bffdcffbffeff30ff43ff8aff1aff3dff4252ffef42ffecffc6ff10fff2cdff1bffdcffbffeff30ff43ff8aff1aff3dff4252ffef42ffecffc6ff10fff2cdff1bffdcffbffeff30ff43ff8aff1aff3dff4252ff6f42ffecffc6ff10fff2cdff1b26")).length, 1000);
29 | });
30 | it("byte", function() {
31 | assert.equal(c.deserialize(hexstr_to_bin("01000100680000001e270000000400102700000101ff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ffff00ff00ff00ff00ff00ff00ff00ff00ff7f00ff00ff00ff00ff00ff00ff00e6")).length, 10000);
32 | });
33 | it("short", function() {
34 | assert.equal(c.deserialize(hexstr_to_bin("01000100110100002e4e0000800500102700000101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ffaa0101ff0101ff0101ff0101ff02010183")).length, 10000);
35 | });
36 | it("integer", function() {
37 | assert.equal(c.deserialize(hexstr_to_bin("0100010054000000ae0f0000800600e8030000010000be0001ff00ff000001ff00000001ffef00ff000001ff00000001ff00ff0000fb01ff00000001ff00ff000001ff0000be0001ff00ff000001ff0000000172")).length, 1000);
38 | });
39 | it("long", function() {
40 | assert.equal(c.deserialize(hexstr_to_bin("01000100da0000004e1f0000800700e8030000010000ff000301ff0003000001ff0000000301ffff0003000001ff0000000301ff00030000ff01ff0000000301ff0003000001ff0000ff000301ff0003000001ff0000000301ffff0003000001ff0000000301ff00030000ff01ff0000000301ff0003000001ff0000ff000301ff0003000001ff0000000301ffff0003000001ff0000000301ff00030000ff01ff0000000301ff0003000001ff0000ff000301ff0003000001ff0000000301ffff0003000001ff0000000301ff000300000f01ff000000030146")).length, 1000);
41 | });
42 | it("real", function() {
43 | assert.equal(c.deserialize(hexstr_to_bin("010001003b000000ae0f0000400800e8030000000080fa3f00ff00bfff3fff00ff80ffbfffff3fff00ff80ffbfff3fff00ff80ffbfff033fff008a")).length, 1000);
44 | });
45 | it("float", function() {
46 | assert.equal(c.deserialize(hexstr_to_bin("01000100720000004e1f0000400900e80300000004f0be3f00ff0003cfff3fff000300cfffff3fff00ff0003cfff3fff0003f0ffcfffff3fff00ff0003cfff3fff0003f0ffcfffff3fff00ff0003cfff3fff0003f0ffcfffff3fff00ff0003cfff3fff0003f0ffcfff0f3fff00ff0003cfe0")).length, 1000);
47 | });
48 | //it("char", function() { no compression?
49 | //});
50 | it("symbol", function() {
51 | assert.equal(c.deserialize(hexstr_to_bin("010001002d000000de070000800b00e80300006161ffaa6161ff6161ff6161ff6161ff2a6161ff6161ff6161bf")).length, 1000);
52 | });
53 | it("timestamp", function() {
54 | assert.equal(c.deserialize(hexstr_to_bin("01000100600000004e1f0000000c00e8030000c087c0ff599c3c1a0747ff78ffffa6ffc5ffa0ff26ff1dffc7ff47ff78ffffa6ffc5ffa0ff26ff1dffc7ff47ff78ffffa6ffc5ffa0ff26ff1dffc7ff47ff78ff3fa6ffc5ffa0ff26ff1dffc717")).length, 1000);
55 | });
56 | it("month", function() {
57 | assert.equal(c.deserialize(hexstr_to_bin("010001008c0000004e1f0000000900e80300006666f10001789f4000010000e7ffdfffff26ff00000001e7ffdfff26ff00010000ffe7ffdfff26ff00000001e7ffdfff26ffff00010000e7ffdfff26ff00000001e7ffffdfff26ff00010000e7ffdfff26ff0000ff0001e7ffdfff26ff00010000e7ffdfffff26ff00000001e7ffdfff26ff0001000001e7e1")).length, 1000);
58 | });
59 | it("date", function() {
60 | assert.equal(c.deserialize(hexstr_to_bin("0100010037000000ae0f0000000e00e80300000b15ff00ff0bff1eff15ff00ff0bff1eff15ffff00ff0bff1eff15ff00ff0bff1eff158d")).length, 1000);
61 | });
62 | it("datetime", function() {
63 | assert.equal(c.deserialize(hexstr_to_bin("01000100600000004e1f0000000f00e8030000facfc04b237ea7b44035ff84ffff68ff5dffd9ff13fff4ffbaff35ff84ffff68ff5dffd9ff13fff4ffbaff35ff84ffff68ff5dffd9ff13fff4ffbaff35ff84ff3f68ff5dffd9ff13fff4ffba17")).length, 1000);
64 | });
65 | it("minute", function() {
66 | assert.equal(c.deserialize(hexstr_to_bin("0100010054000000ae0f0000801100e8030000010000be0001ff00ff000001ff00000001ffef00ff000001ff00000001ff00ff0000fb01ff00000001ff00ff000001ff0000be0001ff00ff000001ff0000000172")).length, 1000);
67 | });
68 | it("second", function() {
69 | assert.equal(c.deserialize(hexstr_to_bin("0100010054000000ae0f0000801200e8030000010000be0001ff00ff000001ff00000001ffef00ff000001ff00000001ff00ff0000fb01ff00000001ff00ff000001ff0000be0001ff00ff000001ff0000000172")).length, 1000);
70 | });
71 | it("time", function() {
72 | assert.equal(c.deserialize(hexstr_to_bin("0100010054000000ae0f0000801300e8030000010000be0001ff00ff000001ff00000001ffef00ff000001ff00000001ff00ff0000fb01ff00000001ff00ff000001ff0000be0001ff00ff000001ff0000000172")).length, 1000);
73 | });
74 | });
75 | it("dict", function() {
76 | assert.equal(Object.keys(c.deserialize(hexstr_to_bin("0100010099010000055e000000630b00060000006100006200630064006514006600000006020900f4a60100010003f03f000300cfffff3fff00ff0003cfff3fff0003f0ffcfffff3fff00ff0003cfff3fff0003f0ffcfffff3fff00ff0003cf6809ff0001cf680001ff0001cfff3fff00010001cfff3fff0001ff0001cfff3fff00010001cfff3fff0001ff0001cfff3fff00010001cfff3fff0001ff0001cfff3fff09ff00ff0000cfff3fffff00000002cfff3fff00020000cfff3fffff00000002cfff3fff00020000cfff3fffff00000002cfff3fff00020000cfff3f6fff09ff0000f0ffcfff3f6f00010001cfffff3fff00010001cfff3fff00010001cfffff3fff00010001cfff3fff00010001cfffff3fff00010001cfff3fff09ff00ff0000ffcfff3fff00000002cfff3fff00020000ffcfff3fff00000002cfff3fff00020000ffcfff3fff00000002cfff3fff00020000ffcfff3f6f09ff0000f0ffcfff3f6f0001ff0001cfff3fff00010001cfff3fff0001ff0001cfff3fff00010001cfff3fff00017f0001cfff3fff00010001cfff3fff"))).length, 6);
77 | });
78 | it("table", function() {
79 | assert.equal(c.deserialize(hexstr_to_bin("0100010008010000a73e0000006200630b00020000380061006200000002020900cce80300000004f03f00ff0003f7cfff3fff000300cfff3fff00ff0003ffcfff3fff0003f0ffcfff3fff00ff0003ffcfff3fff0003f0ffcfff3fff00ff0003ffcfff3fff0003f0ffcfff3fff00ff0003ffcfff3fff0003f0ffcfff3fff00ff0003ffcfe009ff0001cfe000010001cfff3fffff00010001cfff3fff00010001cfff3fffff00010001cfff3fff00010001cfff3fffff00010001cfff3fff00010001cfff3fffff00010001cfff3fff00010001cfff3fffff00010001cfff3fff00010001cfff3fffff00010001cfff3fff00010001cfff3fff7f00010001cfff3fff00010001cfe8")).length, 1000);
80 | });
81 | });
82 | });
83 | });
84 |
--------------------------------------------------------------------------------
/test/connect.js:
--------------------------------------------------------------------------------
1 | var nodeq = require("../index.js"),
2 | assert = require("assert");
3 |
4 | describe("connect", function() {
5 | "use strict";
6 | describe("old API", function() {
7 | it("should fail if enpoint is unavailable", function(done){
8 | nodeq.connect("localhost", 9999, function(err) {
9 | if (err) {
10 | done();
11 | } else {
12 | assert.fail("no err");
13 | }
14 | });
15 | });
16 | });
17 | describe("new API", function() {
18 | it("should fail if enpoint is unavailable", function(done){
19 | nodeq.connect({host: "localhost", port: 9999}, function(err) {
20 | if (err) {
21 | done();
22 | } else {
23 | assert.fail("no err");
24 | }
25 | });
26 | });
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/test/typed.js:
--------------------------------------------------------------------------------
1 | var typed = require("../lib/typed.js"),
2 | assert = require("assert");
3 |
4 | describe("typed", function() {
5 | describe("toString", function() {
6 | it("int", function() {
7 | assert.equal(typed.int(1) + "", "int(1)");
8 | });
9 | it("ints", function() {
10 | assert.equal(typed.ints([1, 2, 3]) + "", "list[int](1,2,3)");
11 | });
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "target": "es2015",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "declaration": true,
8 | "noEmit": true,
9 | "strictNullChecks": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------