1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | exports.fast = false;
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | var index = require ( "redis" ),
|
20 | Backend = require ( "./lib/backend" ).Backend,
|
21 | Connection = require ( "./lib/connection" ).Connection,
|
22 | helpers = require ( "./lib/helpers" ),
|
23 |
|
24 | backends = {},
|
25 | RedisClient = index.RedisClient,
|
26 |
|
27 | anon = 0;
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | exports.RedisClient = index.RedisClient;
|
33 | exports.Multi = index.Multi;
|
34 | exports.print = index.print;
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | exports.createClient = function ( port, host, options )
|
40 | {
|
41 | var id = !port && !host ? 'fake_' + ( ++ anon ) : ( host || "" ) + ( port || "" ),
|
42 | lat = options && options.fast || exports.fast ? 1 : null,
|
43 | c = new Connection ( backends [ id ] || ( backends [ id ] = new Backend ), lat, lat ),
|
44 | cl = new RedisClient ( { on : function () {} } ),
|
45 | ns = options && options.no_sugar;
|
46 |
|
47 | if ( options && options.verbose )
|
48 | c.verbose = true;
|
49 |
|
50 | cl.connected = true;
|
51 | cl.ready = true;
|
52 |
|
53 | cl.end = function() {
|
54 | cl.send_command = function(command) {
|
55 | throw new Error("fakeredis: You've closed this connection with .end(), cannot " + command);
|
56 | };
|
57 | };
|
58 |
|
59 | cl.send_command = function ( command, args, callback )
|
60 | {
|
61 |
|
62 |
|
63 | if (typeof command !== "string") {
|
64 | throw new Error("First argument to send_command must be the command name string, not " + typeof command);
|
65 | }
|
66 |
|
67 | if (Array.isArray(args)) {
|
68 | if (typeof callback === "function") {
|
69 |
|
70 |
|
71 |
|
72 | } else if (! callback) {
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | var last_arg_type = typeof args[args.length - 1];
|
81 | if (last_arg_type === "function" || last_arg_type === "undefined") {
|
82 | callback = args.pop();
|
83 | }
|
84 | } else {
|
85 | throw new Error("send_command: last argument must be a callback or undefined");
|
86 | }
|
87 | } else {
|
88 | throw new Error("send_command: second argument must be an array");
|
89 | }
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | if (Array.isArray(args[args.length - 1])) {
|
97 | args = args.slice(0, -1).concat(args[args.length - 1]);
|
98 | }
|
99 |
|
100 |
|
101 |
|
102 | if ( !options || !options.no_lint )
|
103 | {
|
104 | var i, n;
|
105 | n = args.length;
|
106 | for ( i = 0; i < n; i ++ )
|
107 | if ( typeof args [ i ] !== 'string' && typeof args [ i ] !== 'number' )
|
108 | throw new Error ( "fakeredis/lint: Argument #" + i + " for " + command + " is not a String or Number: " + args [ i ] );
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 | var cb;
|
114 | if ( callback && !ns && /^hgetall/i.test ( command ) )
|
115 | cb = function ( err, data )
|
116 | {
|
117 | if ( !err && data )
|
118 | data = reply_to_object ( data );
|
119 |
|
120 | callback ( err, data );
|
121 | };
|
122 |
|
123 | else
|
124 | cb = callback;
|
125 |
|
126 | c.push ( this, command, args, cb );
|
127 | };
|
128 |
|
129 | cl.pushMessage = cl.emit.bind ( cl );
|
130 |
|
131 | ( function ()
|
132 | {
|
133 | var prop;
|
134 | for ( prop in helpers )
|
135 | cl [ prop ] = helpers [ prop ];
|
136 | }
|
137 | () );
|
138 |
|
139 | return cl;
|
140 | };
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 | function reply_to_object(reply) {
|
147 | var obj = {}, j, jl, key, val;
|
148 |
|
149 | if (reply.length === 0) {
|
150 | return null;
|
151 | }
|
152 |
|
153 | for (j = 0, jl = reply.length; j < jl; j += 2) {
|
154 | key = reply[j].toString();
|
155 | val = reply[j + 1];
|
156 | obj[key] = val;
|
157 | }
|
158 |
|
159 | return obj;
|
160 | }
|
161 |
|