-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
115 lines (103 loc) · 3.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var ref = require('ref');
var ffi = require('ffi');
var Struct = require('ref-struct');
// typedef
var rlite = ref.types.void;
var rlitePtr = ref.refType(rlite);
var rlitePtrPtr = ref.refType(rlitePtr);
var stringPtr = ref.refType(ref.types.CString);
var reply = Struct();
var replyPtr = ref.refType(reply);
reply.defineProperty('type', 'int');
reply.defineProperty('integer', 'long long');
reply.defineProperty('len', 'int');
reply.defineProperty('str', 'string');
reply.defineProperty('elements', 'size_t');
reply.defineProperty('element', replyPtr);
var size_tPtr = ref.refType(ref.types.size_t)
var libsrlite = ffi.Library(__dirname + '/vendor/rlite/src/libhirlite', {
'rliteConnect': [ rlitePtr, [ 'string', 'int' ] ],
'rliteFree': [ 'void', [ rlitePtr ] ],
'rliteCommandArgv': [ replyPtr, [ rlitePtr, 'int', stringPtr, size_tPtr ] ],
'rliteFreeReplyObject': [ 'void', [ replyPtr ] ],
});
var RLITE_REPLY_STRING = 1;
var RLITE_REPLY_ARRAY = 2;
var RLITE_REPLY_INTEGER = 3;
var RLITE_REPLY_NIL = 4;
var RLITE_REPLY_STATUS = 5;
var RLITE_REPLY_ERROR = 6;
var reply_to_js = function(reply) {
if (reply.type == RLITE_REPLY_STRING || reply.type == RLITE_REPLY_STATUS) {
// TODO: binary safe
return reply.str;
}
if (reply.type == RLITE_REPLY_NIL) {
return null;
}
if (reply.type == RLITE_REPLY_INTEGER) {
return reply.integer;
}
if (reply.type == RLITE_REPLY_ERROR) {
return new Error(reply.str);
}
if (reply.type == RLITE_REPLY_ARRAY) {
var arr = [];
for (var i = 0; i < reply.elements; i++) {
// var ptr = ref.readPointer(reply.element, ref.sizeof.pointer * i);
// arr.push(reply_to_js(ptr.deref()));
var obj = ref.get(reply.element, ref.sizeof.pointer * i, replyPtr);
arr.push(reply_to_js(obj.deref()));
}
return arr;
}
throw new Error('Unexpected type ' + reply.type);
};
var prepareReply = function(replyObj) {
var data = replyObj.deref();
var obj = reply_to_js(data);
libsrlite.rliteFreeReplyObject(replyObj);
return obj;
}
var prepareArgs = function(args) {
var argv = new Buffer(ref.sizeof.pointer * args.length);
var argvlen = new Buffer(ref.sizeof.uint64 * args.length);
for (var i = 0; i < args.length; i++) {
var value = new Buffer(ref.sizeof.char * (args[i].length + 1));
ref.writeCString(value, 0, args[i]);
ref.writePointer(argv, ref.sizeof.pointer * i, value);
ref.writeUInt64(argvlen, ref.sizeof.uint64 * i, args[i].length);
}
return {argv: argv, argvlen: argvlen, argc: args.length};
}
var command = function(db, args, callback) {
var p = prepareArgs(args);
return libsrlite.rliteCommandArgv.async(db, p.argc, p.argv, p.argvlen, function (err, ret) {
if (err) {
callback(err);
return;
}
var reply = prepareReply(ret);
if (reply instanceof Error) {
callback(reply);
} else {
callback(null, reply);
}
});
};
var commandSync = function(db, args, callback) {
var p = prepareArgs(args);
var ret = libsrlite.rliteCommandArgv(db, p.argc, p.argv, p.argvlen);
return prepareReply(ret);
};
exports.createClient = function(arg0, arg1){
var db = libsrlite.rliteConnect(arg0 || ':memory:', arg1 || 0);
return {
command: function(args, callback) {
return command(db, args, callback);
},
commandSync: function(args) {
return commandSync(db, args);
},
};
}