Code Monkey home page Code Monkey logo

node-q's Introduction

node-q

Q interfacing with Node.js. Supports decompression. Can deserialize all q data types (including guid) to JavaScript. Can serialize all JavaScript data types to q.

Installation

npm install node-q

Usage

Create Connection

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 5000}, function(err, con) {
	if (err) throw err;
	console.log("connected");
	// interact with con like demonstrated below
});

Create TLS Connection

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 6000, useTLS: true}, function(err, con) {
	if (err) throw err;
	console.log("connected");
	// interact with con like demonstrated below
});

Create Connection with user and password auth

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 5000, user: "user", password: "password"}, function(err, con) {
	if (err) throw err;
	console.log("connected");
	// interact with con like demonstrated below
});

Create Connection with Unix Domain Socket (Doesn't support abstract namespace sockets: KDB 3.5+ on Linux)

nodeq.connect({ unixSocket: "/path/to/socket" }, function(err, con) {
	if (err) throw err;
	console.log("connected");
});

Execute Q code and receive result

con.k("sum 1 2 3", function(err, res) {
	if (err) throw err;
	console.log("result", res); // 6
});

Execute function with one parameter and receive result

con.k("sum", [1, 2, 3], function(err, res) {
	if (err) throw err;
	console.log("result", res); // 6
});

Execute function with two parameters and receive result

con.k("cor", [1, 2, 3], [4, 5, 6], function(err, res) {
	if (err) throw err;
	console.log("result", res); // 1
});

Async execute Q code

con.ks("show 1 2 3", function(err) {
	if (err) throw err;
});

Async execute function with parameters

con.ks("show", [1, 2, 3], function(err) {
	if (err) throw err;
});

Listen to a handle

con.k(function(err, res) {
	if (err) throw err;
	console.log("result", res);
});

Subscribe to kdb+tick

con.on("upd", function(table, data) {
	console.log(table, data);
});

con.ks(".u.sub[`;`]", function(err) { // subscribe to all tables and all symbols
	if (err) throw err;
});

Close connection

con.close(function() {
	console.log("con closed");
});

Types

q has more data types than JavaScript. Therefore you need to know how types are converted.

From q to JavaScript (deserialization)

q type JavaScript type Null +Infinity -Infinity
boolean Boolean
guid String Null
byte Number
short Number Null Infinity -Infinity
int Number Null Infinity -Infinity
long Number 5 Null Infinity -Infinity
real Number Null Infinity -Infinity
float Number Null Infinity -Infinity
char String Null 4
symbol String Null
timestamp Date 1, 2 Null
month Date 2 Null
date Date 2 Null
datetime Date 2 Null
timespan Date 1, 2, 3 Null
minute Date 2, 3 Null
second Date 2, 3 Null
time Date 2, 3 Null
  • 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.
  • 2: think about running your Node.js process with TZ=UTC node ... to run in UTC timezone. q doesn't know timezones.
  • 3: date is set to 2000-01-01 in the Date object. Only evaluate the time part.
  • 4: You can disable emptyChar2null deserialization during connect(params, cb) to keep the empty char.
  • 5: You can disable long2number deserialization during connect(params, cb) to represent longs as long.js.

dict

q) (`a`b`c)!(1 2 3i)

becomes Object

{
	a: 1,
	b: 2,
	c: 3
}

list

q) 1 2 3i

becomes Array

[1, 2, 3]

table

q) ([] sym:`a`b`c; size:(1 2 3i))

becomes Array of Object per row.

[
	{sym: "a", size: 1},
	{sym: "b", size: 2},
	{sym: "c", size: 3}
]

You can disable flipTables during connect(params, cb) to get a table as an Object with an Array per column.

{
	sym: ["a", "b", "c"],
	size: [1, 2, 3]
}

From JavaScript to q (serialization)

Simple (infer type)

JavaScript type q type
Boolean boolean
String starting with ` symbol
String list[char]
Number float
Date datetime
Object dict
Array[*] list[*]
Null unary primitive
Infinity float
-Infinity float

Advanced (explicit types)

If you want to explicitly serialize a JavaScript type as a q type you need to use the typed API.

Let's start with two examples:

con.k("type", nodeq.short(1), function(err, res) {
	if (err) throw err;
	console.log("result", res); // -5
});

con.k("type", nodeq.shorts([1, 2, 3]), function(err, res) {
	if (err) throw err;
	console.log("result", res); // 5
});

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.

q type primitive wrapper array wrapper
boolean boolean(Boolean) booleans(Array[Boolean])
guid guid(String) guids(Array[String])
byte byte(Number) bytes(Array[Number])
short short(Number) shorts(Array[Number])
int int(Number) ints(Array[Number])
long long(long) 1 longs(Array[long]) 1
real real(Number) reals(Array[Number])
float float(Number) floats(Array[Number])
char char(String) chars(Array[String])
symbol symbol(String) symbols(Array[String])
timestamp timestamp(Date) timestamps(Array[Date])
month month(Date) months(Array[Date])
date date(Date) dates(Array[Date])
datetime datetime(Date) datetimes(Array[Date])
timespan timespan(Date) timespans(Array[Date])
minute minute(Date) minutes(Array[Date])
second second(Date) seconds(Array[Date])
time time(Date) times(Array[Date])
  • 1: JavaScript can not represent 64bit longs. Therefore this module uses the long.js module to represent longs.

API

connect(params, cb)

  • params: Object
    • host: String (e. g. "localhost") (optional)
    • port: Number (e. g. 5000) (optional)
    • unixSocket: String (e. g. "/path/to/socket") (optional)
    • user: String (optional)
    • password: String (optional)
    • useTLS: Boolean (optional)
    • ca: Buffer | String (e.g. fs.readFileSync('path\to\cert.pem')) (optional)
    • socketNoDelay : Boolean (optional, see http://nodejs.org/api/net.html#net_socket_setnodelay_nodelay)
    • socketTimeout: Number (optional, see http://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback)
    • nanos2date: Boolean (optional, default: true)
    • flipTables: Boolean (optional, default: true)
    • emptyChar2null: Boolean (optional, default: true)
    • long2number: Boolean (optional, default: true)
  • cb: Function(err, con)
    • err: Error or undefined
    • conn: Connection or undefined

@deprecated connect(host, port, [user, password,] cb)

This is deprecated. Please use the new, mor flexible API above!

  • host: String (e. g. "localhost")
  • port: Number (e. g. 5000)
  • user: String (optional)
  • password: String (optional)

Connection

Is an EventEmitter.

k(s, [x, [y, [z, [...,] ] ] ] cb)

Sync request/response.

  • s: String
  • x: Object (optional)
  • y: Object (optional)
  • z: Object (optional)
  • ...: Object (optional)
  • cb: Function(err, res)
    • err: Error or undefined
    • res: Object or undefined

ks(s, [x, [y, [z, [...,] ] ] ] cb)

Async request.

  • s: String
  • x: Object (optional)
  • y: Object (optional)
  • z: Object (optional)
  • ...: Object (optional)
  • cb: Function(err)
    • err: Error or undefined

close(cb)

  • cb: Function(err) (optional)
    • err: Error or undefined

Events

upd(table, data)

If you use kdb+tick and subscribe like con.ks(".u.sub[;]", function(err) { throw err; }) you will receive all Updates via upd Event.

  • table: String (e.g. trades)
  • data: Object (table represented in JavaScript as Array of Object)
error(err)

If the socket emit an error event.

  • err: Error
end()

If the socket emit an end event.

timeout()

If the socket emit a timeout event.

close(had_error)

If the socket emit a close event.

  • had_error: Boolean (true if the socket had a transmission error)

Contribution

If you want to create a Pull-Request please make sure that make test runs without failures.

If you have a kdb+tick setup please also run make mochait.

Code Style

make jshint

Unit Tests

make mocha

Integration Test

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. If you are using a self signed certificate you will also need to set the NODE_TLS_REJECT_UNAUTHORIZED environment variable to 0.

make mochait

Circular depdendencies

make circular

node-q's People

Contributors

amirburbea avatar caleteeter avatar emilebres avatar gmelika avatar iuhh avatar michaelwittig avatar mm00re1 avatar na21 avatar oinutter avatar wwarby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-q's Issues

Serialiser does not escape the null character in strings, causing badmsg error

With the help of a consultant at Kx, I've got to the bottom of an issue we were facing where certain row upserts we were sending caused a badmsg error followed by the socket being forcibly closed by the q process. It turns out we had some strings that contain the null character which the serializer uses as a terminator between elements of the message, and those null characters are not being properly escaped by the serializer. This simple example can demonstrate the problem:

var conn = nodeq.connect('localhost', 5004, (err, conn) => {
  conn.k('show', nodeq.symbol('foo\u0000'), (err, result) => {
    if (err) { console.error(err); }
    console.log(result);
  });
});

In the above example the server shows badmsg, but the callback passed to conn.k is never called. If I use conn.ks, the connection eventually seems to get terminated by the server.

I've worked around this for now by replacing every nodeq.symbol(x) call with sanitise(nodeq.symbol(x)) where sanitise() simply removes the \u0000 from the input string. That works but really it seems as though the serialiser should be able to handle and properly escape input containing the character it uses as a delimiter. I realise the serialiser is part of c.js but since your library depends on it I'm reporting it here. I've also reported it to Kx.

Localtime is assumed to be UTC..

First of all I am based in 'Asia/Kolkata' timezone which is +530 from UTC
The value which I input in the DB looks like this -> 2017.12.24T21:32:59.103 317.5 . -> this is the localtime
When I query this value from the kdb console I get the above value back, which is correct.
However when I try to use this node adapter I get -> 2017.12-25 02:56:59.770.
The difference is exactly +530 from the local time.
When I use nodejs to get the local time it gives the right output. So my best guess is during transformation the timezone value is changed here

Dates reduced by a few nanoseconds when sent to KDB

Somehow my dates are being corrupted by tiny margins when they are sent to a KDB process. In the very simplest form I can demonstrate the problem with this code:

conn.k('show', nodeq.timestamp(new Date(2019, 4, 10, 12)))

Output in KDB:

2019.05.10D10:59:59.999999872

The date is also off by an hour but I haven't tried dealing with the timezone issue yet - for now I need to deal with the weirdness in the nanoseconds. Any ideas why this is happening?

同学,您这个项目引入了99个开源组件,存在20个漏洞,辛苦升级一下

检测到 michaelwittig/node-q 一共引入了99个开源组件,存在20个漏洞

漏洞标题:Growl命令执行漏洞
缺陷组件:[email protected]
漏洞编号:CVE-2017-16042
漏洞描述:Growl是一套支持Node.js的通知系统。
Growl 1.10.2之前版本中存在安全漏洞,该漏洞源于在将输入传递到shell命令之前,程序未能正确的对其进行过滤。攻击者可利用该漏洞执行任意命令。
国家漏洞库信息:https://www.cnvd.org.cn/flaw/show/CNVD-2018-24664
影响范围:(∞, 1.10.0)
最小修复版本:1.10.0
缺陷组件引入路径:[email protected]>[email protected]>[email protected]

另外还有20个漏洞,详细报告:https://mofeisec.com/jr?p=ie9057

Command getting corrupted through serialisation?

I'm trying to query a function, which would be called q-side like this (this would return me a table):

q) `.xyz.getTrades; `VOD.L, 2015.07.08; 0t; 2015.07.09; 24t; ()!()

However, I've tried a few variations, such as the below (and every permutation between symbols, date objects, strings, etc) with nodeq.k without success, but I'm not sure which part is getting corrupted as KDB errors are, well, you know :)

nodeq.k('.xyz.getTrades', ['`VOD.L', '2015.07.08', '0t', '2015.07.09', '24t', {}], function ...

nodeq.k('.xyz.getTrades', ['VOD.L', '2015.07.08', '0t', '2015.07.09', '24t', '()!()'], function ...

nodeq.k('`.xyz.getTrades', ['`VOD.L', new Date(2015, 6, 8), '0t', new Date(2015, 6, 9), '24t', {}], function ...

nodeq.k('`.xyz.getTrades' ['`VOD.L; 2015.07.08; 0t; 2015.07.09; 24t; ()!()'], function ...

And also the full command as a string:

nodeq.k('`.xyz.getTrades; `VOD.L; 2015.07.08; 0t; 2015.07.09; 24t; ()!()', function ...

nodeq.k('.xyz.getTrades; `VOD.L; 2015.07.08; 0t; 2015.07.09; 24t; ()!()', function ...

I get varying errors but mostly badreq. Is there something obvious that I'm doing wrong here?

issue parsing negative number

Hi Michael,

Thanks for your work. I've played around with the module a bit and found this issue. It seems node-q cannot parse negative no. from kdb (-1j, or -1i) I'm getting 18446744073709552000 instead

This is how to reproduce

var nodeq = require('node-q');

 nodeq.connect({host: 'localhost', port: 5555}, function(err, con) {
    con.k('-1j', function(err, response) {
        console.log(response);
    });
});
//output
//18446744073709552000
//'-1i' is also returning 4294967295

I'm using kdb 3.3 32bit on windows

C:\q>q -p 5555
KDB+ 3.3 2015.07.09 Copyright (C) 1993-2015 Kx Systems

Komsit

backtick escape issue for symbol

Hi Michael,

I notice a small issue in sending Q symbol with backtick; Actually we need an extra space to escape the leading backtick. I just tested following code :

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 5000}, function(err, con) {
    if (err) throw err;
    con.k("`a`b`c", function(err, res) {
        if (err) throw err;
        console.log("result", res); // Error a`b`c
    });    
    con.k(" `a`b`c", function(err, res) {
        if (err) throw err;
        console.log("result", res); // "result" [ 'a', 'b', 'c' ]
    });
});

We can hack it on user side by adding extra space to query string, but is it possible to fix it at package level ?

Thanks,
Duo

Problem when using 'strict mode'

I'm getting TypeError when running node with strict mode. This seems to be an issue in assert-plus. Strict mode doesn't allow assert-plus to access caller's properties. I can get around this by adding environment variable NODE_NDEBUG (this will disable assert).

Looks like you are using assert-plus for checking args. Maybe this is not really required? or maybe this issue should be raised with assert-plus instead?

p.s. using strict mode is not a must, but it would be nice so I can use some cool ES6 features :)

Here is how to reproduce:
node --use_strict qfunc_test.js

var nodeq = require("node-q");

nodeq.connect({host: 'localhost', port: 5555}, function(err, con) {
    console.log('connected');
});
/Users/komsit/.nvm/versions/node/v0.12.7/bin/node --use_strict qfunc_test.js
/workspace/mysnippets/node_modules/node-q/node_modules/assert-plus/assert.js:41
                stackFunc = stackFunc || _assert.caller;
                                                ^
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
    at _assert (/workspace/mysnippets/node_modules/node-q/node_modules/assert-plus/assert.js:41:49)
    at Object.object (/workspace/mysnippets/node_modules/node-q/node_modules/assert-plus/assert.js:141:9)
    at Object.connect (/workspace/mysnippets/node_modules/node-q/index.js:185:9)
    at Object.<anonymous> (/workspace/mysnippets/q/qfunc_test.js:3:7)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)

Unicode string turns into a messy code

Examples:

var nodeq = require("node-q");

nodeq.connect({ host: "localhost", port: 5000 }, function(err, con) {
    if (err) throw err;
    console.log("connected");
    // interact with con like demonstrated below 
    con.k('aa:`$"你好"', function(err, res) {
        if (err) throw err;
        console.log("result", res); // 6 
    });
    con.close(function() {
        console.log("con closed");
    });
});

But when I look at the variable aa in q, it returns with a totally different string:

`浣犲ソ

How could I solve this problem?

Server crash when using node v0.10.31

Hey just letting you know I was getting a server crash when running a query on a KDB server. It had no error message the app would just stop working. a "Count xxxxx" ran fine but a "select from xxxxx where i>0,i<=100" would crash the whole node server. This was on linux and node v0.10.31. I upgraded the server to the version of node I was running locally, v0.12.2 and everything is working fine now. Just thought you might want to take a look at your required node version in package.js

Infinty for different data types

Hi!

I'm struggling with this task: sometimes I need to send timestamp as infinity (0Wp). Is it possible? Perhaps typed could take Infinity or some parameter that means "I want to deserialize it as null/inf etc... on kdb side"?

Thanks!

Precision error on real (explicit) type:

It looks to me like something is off on the encoding of a real ...
A simple usecase:

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 5000}, function(err, con) {
	con.k("", nodeq.real(1.2345),function(err, res){
		console.log(res)
	});
	});

Returns

>node t.js
1.2345000505447388

Type Definition Errors

Output

node_modules/node-q/lib/typed.d.ts:1:23 - error TS2688: Cannot find type definition file for 'long'.

1 /// <reference types="long" />
                        ~~~~

node_modules/node-q/lib/typed.d.ts:56:37 - error TS2304: Cannot find name 'Long'.

56 export declare function long(value: Long): Typed;
                                       ~~~~

node_modules/node-q/lib/typed.d.ts:149:38 - error TS2304: Cannot find name 'Long'.

149 export declare function longs(value: Long[] | ReadonlyArray<Long>): Typed;
                                         ~~~~

node_modules/node-q/lib/typed.d.ts:149:61 - error TS2304: Cannot find name 'Long'.

149 export declare function longs(value: Long[] | ReadonlyArray<Long>): Typed;

Error condition being triggered unexpectedly

Hi Michael

I have a "good" query, which returns a table back from KDB via the q command line. Most of the time, it returns fine through node-q, but when I give it a certain date range (the query is a time series call), the condition if (type === -128) resolves to true, and the entire binary response gets spat back at me as an error.

The query is...

.ceq.getQuotes[`BP.L;2015.09.08;10:52:42.861t;2015.09.08;10:57:36.911t;(`source`tz)!(`casheq;`UTC)]

...which I'm submitting as a raw string, and works for most dates. I assume the response packet must contain a -128 for another purpose, possibly one of the column values, but my binary/hex isn't great so I can't tell.

Any ideas what might be causing this? It doesn't seem to be isolated to a particular row in the response - a binary search of the date range doesn't uncover anything obvious.

passing an array or object where the only values are null fails serialization causes connection to lock up

If we pass anything through node-q where all values are null (either an object or an array), serialization into q types fail and causes connection to kdb to lock up completely.

c.k('x', [null, null, null], (e,r) => console.log(e, r))
Error: bad type null

c.k('x', {hello: null, world: null}, (e,r) => console.log(e, r))
Error: bad type null

Any of these calls will lock up the socket completely.
It should correctly serialize the values in the list to ::

Custom upd

My company's KDB team has a non standard 'upd' call that will push more than two values.

You have the following code in your node-q library:
if (err === undefined && Array.isArray(o) && o[0] === "upd") { self.emit('upd', o[1], o[2]); }

Can this be changed to:
if (err === undefined && Array.isArray(o) && o[0] === "upd") { events.EventEmitter.prototype.emit.apply(self, o); }

or simply self.emit(...o); since pretty much every version of node today supports that syntax.

Basically allowing the array to be a variable length??

timezone

why a Date date type from q getting converted to datetime in json ?
example
2016.09.20
to
2016-09-20T00:00:00.000Z

How to change the timezone form utc to eastern?

Errors not returned when using conn.ks

There doesn't seem to be any way of reaching an error thrown by an asynchronous call using the conn.ks method. I've put together a simple example of what I mean below - if I call a non-existent function I see an error output directly on the running q process and I can capture that error if I call conn.k, but error argument to the conn.ks method is always undefined, and the connection never fires it's 'error' event.

Is this just an intrinsic limitation of asynchronous calls in node-q or am I doing something wrong? Or is this a bug? I want the performance advantages of asynchronous calls to KDB but I can't risk being unaware of errors returned by the server.

nodeq.connect(
  {
    host: 'localhost',
    port: 5004
  },
  (err, conn) => {
    if (err) {
      console.error(err);
    }
    conn.on('error', err => {
      console.error(err); //Never reaches here
    });
    conn.k('nonExistentFunc', (err, result) => {
      if (err) {
        console.error(err); //Works as expected
      }
    });
    conn.ks('nonExistentFunc', err => {
      if (err) {
        console.error(err); //Never reaches here - err is always undefined
      }
    });
  }
);

handle chunk data packages

Reported from Markus Sieber via [email protected]

you assume that a whole message comes in one chunk in the data event "this.socket.on("data", function(buffer) {."
unfortunately this is not always correct. Tcp can split the data and so the data callback might be triggered mutliple times for one k ipc message. You have to buffer the data and check the length.

Error at .deserialize when inserting to table

Hello @michaelwittig ,

I'm experiencing weird difficulties with simple table insertions.

I can create a new table and run queries on it without a problem, but always get weird deserialisation error when trying to insert a record to the table.

It feels to me like the backtick (`) in the first position is the problem. Here's a toy example:

    coll.con.k('progress:([]gender:`symbol$();weight:`long$())', err => {
	if (err) throw err
	console.log('created new table')

	coll.con.k("`progress insert (`male, 91)", (err, res) => {
	    if (err) throw err
	    console.log('wrote new record', res)
	})

    })

The error I get points to this if statement, but I don't really understand its context.

Error: progress insert (`male, 91)
    at r (/Users/radek/Documents/Work/PROJECTS/spotter/node_modules/node-q/lib/c.js:327:10)
    at Object.deserialize (/Users/radek/Documents/Work/PROJECTS/spotter/node_modules/node-q/lib/c.js:402:9)
    at Socket.<anonymous> (/Users/radek/Documents/Work/PROJECTS/spotter/node_modules/node-q/index.js:55:15)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:597:20)

I don't know it it's just the way error messages got printed, but it misses the backtick in the first position.

Obviously, if you put the string

`progress insert (`male, 91)

to the q console itself, it inserts the record.

Can you please help? Am I doing something wrong?

Thank you :)

Calling upd with tablular data

Apologies if this is my mistake because I'm very new to node-q (and q itself) but I'm struggling to send tabular data to the upd function (or any function for that matter) as an argument to the k function rather than as a raw string. Specifically:

This works:

conn.k('upd[`demoTable; ([]demoSymbol:`a`b)];');

But this does not:

conn.k('upd', nodeq.symbol('demoTable'), {
  demoSymbol: nodeq.symbols(['a', 'b'])
});

The latter give a 'type error response.

I've tried a few variations of this without success. Is what I'm trying to do actually possible with node-q? All I'm really aiming for is to insert data into a table without composing the raw q string myself.

BigInt for long

Hi!

Can I choose a custom serializer/deserializer for data types? I'm specicially wanting longs to be represented as JS native BigInt type. I'm also happy to provide a PR if this is something you'd want in the module

Space decoded to "null"

Hey Michael,

Found the new commit decodes spaces in string to nulls, as it's done char by char this renders the output incorrectly, one would end up with a string "null" in place of " ".

function rChar() {

c58528c@michaelwittigsupport for nulls, infinity and guid
michaelwittig authored 14 days ago
54 var val = rInt8();
55 if (val === 32) {
56 return null;
57 } else {
58 return String.fromCharCode(val);
59 }

Perhaps there was a rationale to add this in earlier? In any case I'd say the old behaviour is correct.

Thanks
Hui

problem with the net module when used inside react app

Hi, I use node-q to send queries to kdb+ db. I created a code that worked when I executed it directly from cmd (i.e. "node sendQuery.js" on terminal).

For some reason, when used inside react app, the exact same code gives an error TypeError: Cannot read property 'apply' of undefined.
This is the traceback, on node_modules/node-q/index.js:241:

238 | });
239 | }
240 | });
241 | socket = net.connect.apply(null, socketArgs); // problem in this line.
242 | if (params.socketTimeout !== undefined) {
243 | socket.setTimeout(params.socketTimeout);
244 | }

Do you have any idea why this happens? or how can I solve this?

Incorrect timestamp values inserted

const now = new Date()

con.ks(
    "insert", 
    "`incoming",
    [
      nodeq.timespan(now),
      nodeq.timestamp(now)
    ]
); 
timespan             timestamp
--------------------------------------------------
0D04:08:00.595000000 2023.08.17D04:08:00.595000064
0D04:08:00.610000000 2023.08.17D04:08:00.610000000
0D04:08:00.612000000 2023.08.17D04:08:00.612000000
0D04:08:00.613000000 2023.08.17D04:08:00.612999936
0D04:08:00.614000000 2023.08.17D04:08:00.614000000
0D04:08:04.616000000 2023.08.17D04:08:04.616000000
0D04:08:04.630000000 2023.08.17D04:08:04.630000000
0D04:08:04.632000000 2023.08.17D04:08:04.632000000
0D04:08:04.633000000 2023.08.17D04:08:04.632999936
0D04:08:04.634000000 2023.08.17D04:08:04.634000000

timespan column values look correct, no "rounding errors". How can I make sure that the timespan part in the timestamp column looks the same?

null for time type

Hi, I want to insert data from node-q to kdb table. One of the columns in the table is of type time. How can I insert a null (0Nt) value in time column?

Typed - functional select

Hi Michael

Have you considered how this library might support functional selects (parse trees) via its serialisation capability? For example, the Q expression:

.xyz.func[`test;(`filterClause`foo)!(enlist[(=;`account;`C12345)];1b)]

could be expressed as something like this:

connection.k('.xyz.func', [
  '`test', {
    filterClause: [
      [typed.operator('='), '`account', '`C12345'] // could be one of '=', '>=', '>', 'in', etc
    ],
    foo: true
  }
], callback);

charCode 32 (" ") deserialized into null

We are having issues with string based responses from q, spaces are being translated into nulls

Test app

#!/usr/bin/env node

var cmd = process.argv[2] || '';
var nodeq = require('node-q');
var assert = require('assert');

nodeq.connect({
  host: 'localhost',
  port: 5080
}, function(err, q) {
  q.k(cmd, function(err, out) {
    console.log("in:", cmd, "out:", out);
    process.exit(0);
  });
});

output

❯ ./test.js '"this is a string"'
in: "this is a string" out: thisnullisnullanullstring

We expected " " to translate into " " in javascript.

Code that deserializes ' ' into null
https://github.com/michaelwittig/node-q/blob/master/lib/c.js#L53-L60

Tested for here:
https://github.com/michaelwittig/node-q/blob/master/itest/deserialization.js#L296-L303

Is this behaviour intended?

Thanks

make upd function configurable

Hello, great library it works well!

Unfortunately as is typical with kdb, we have a custom upd function this is actually .u.upd

This means I can't subscribe with out hacking the following line:

if (err === undefined && Array.isArray(o) && o[0] === "upd") 
{
   events.EventEmitter.prototype.emit.apply(self, o);
} 

to

if (err === undefined && Array.isArray(o) && o[0] === ".u.upd") 
{
   o[0] = "upd";
   events.EventEmitter.prototype.emit.apply(self, o);
} 

Any chance we could change to pass in the function name to subscribe to?

Queries with 'by' clauses do not return results

Hi Michael,

Great work on the module! I've run into an issue - it seems like 'by' clauses confuse node-q. It doesn't throw an exception, I just get an empty-ish result:

q)\c 10 150
q)numtests:100; timerange:10D; freq:0D00:05;
testid:(til numtests)!000000999999+numtests?20;
fcn:numtests*fc:`long$timerange%freq;
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)

q)select min testin by test from tests
test| testin    
----| ----------
0   | 8564163863
1   | 2297114685
2   | 1001314197
3   | 4260343635
4   | 4177822301
..
q)

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 4000}, function(err, con) {
        if (err) throw err;
        console.log("connected");
        console.time("query");
        con.k("select min testin by test from tests", function(err, res) {
                if (err) throw err;
                console.timeEnd("query");
                console.log("test(" + res.length + " samples)");
                console.log(res);
                console.log("first", res[0]);
                console.log(" last", res[res.length-1]);
        });
});

connected
query: 5ms
test(2 samples)
[ ,  ]
first undefined
 last undefined
^C

var nodeq = require("node-q");
nodeq.connect({host: "localhost", port: 4000}, function(err, con) {
    if (err) throw err;
    console.log("connected");
    console.time("query");
    con.k("select min testin from tests", function(err, res) {
        if (err) throw err;
        console.timeEnd("query");
        console.log("test(" + res.length + " samples)");
        console.log(res);
        console.log("first", res[0]);
        console.log(" last", res[res.length-1]);
    });
});

connected
query: 3ms
test(1 samples)
[ { testin: 40638960 } ]
first { testin: 40638960 }
 last { testin: 40638960 }
^C

doesn't support unicode and calls with unicode strings cause stream to hang

Example:

> onn.k('show', '你好', function(err, d) { console.log(err, d) })
TypeError: value is out of bounds
    at checkInt (buffer.js:716:11)
    at Buffer.writeInt8 (buffer.js:864:5)
    at wb (/Users/kevin/dev/yb/ybend/node_modules/node-q/lib/c.js:370:5)
    at w (/Users/kevin/dev/yb/ybend/node_modules/node-q/lib/c.js:433:7)
    at w (/Users/kevin/dev/yb/ybend/node_modules/node-q/lib/c.js:450:7)
    at Object.serialize (/Users/kevin/dev/yb/ybend/node_modules/node-q/lib/c.js:473:2)
    at Connection.k (/Users/kevin/dev/yb/ybend/node_modules/node-q/index.js:125:11)
    at repl:1:9
    at REPLServer.defaultEval (repl.js:132:27)
    at bound (domain.js:254:14)
    at REPLServer.runBound [as eval] (domain.js:267:12)
    at REPLServer.<anonymous> (repl.js:279:12)
    at REPLServer.emit (events.js:107:17)
    at REPLServer.Interface._onLine (readline.js:214:10)
    at REPLServer.Interface._line (readline.js:553:8)
    at REPLServer.Interface._ttyWrite (readline.js:830:14)```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.