1 /**************************************************************************
2 Copyright (c) 2017 sewenew
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 *************************************************************************/
16
17 #include "redis_cluster.h"
18 #include <hiredis/hiredis.h>
19 #include "command.h"
20 #include "errors.h"
21 #include "queued_redis.h"
22
23 namespace sw {
24
25 namespace redis {
26
RedisCluster(const std::string & uri)27 RedisCluster::RedisCluster(const std::string &uri) : RedisCluster(ConnectionOptions(uri)) {}
28
redis(const StringView & hash_tag)29 Redis RedisCluster::redis(const StringView &hash_tag) {
30 auto opts = _pool.connection_options(hash_tag);
31 return Redis(std::make_shared<Connection>(opts));
32 }
33
pipeline(const StringView & hash_tag)34 Pipeline RedisCluster::pipeline(const StringView &hash_tag) {
35 auto opts = _pool.connection_options(hash_tag);
36 return Pipeline(std::make_shared<Connection>(opts));
37 }
38
transaction(const StringView & hash_tag,bool piped)39 Transaction RedisCluster::transaction(const StringView &hash_tag, bool piped) {
40 auto opts = _pool.connection_options(hash_tag);
41 return Transaction(std::make_shared<Connection>(opts), piped);
42 }
43
subscriber()44 Subscriber RedisCluster::subscriber() {
45 auto opts = _pool.connection_options();
46 return Subscriber(Connection(opts));
47 }
48
49 // KEY commands.
50
del(const StringView & key)51 long long RedisCluster::del(const StringView &key) {
52 auto reply = command(cmd::del, key);
53
54 return reply::parse<long long>(*reply);
55 }
56
dump(const StringView & key)57 OptionalString RedisCluster::dump(const StringView &key) {
58 auto reply = command(cmd::dump, key);
59
60 return reply::parse<OptionalString>(*reply);
61 }
62
exists(const StringView & key)63 long long RedisCluster::exists(const StringView &key) {
64 auto reply = command(cmd::exists, key);
65
66 return reply::parse<long long>(*reply);
67 }
68
expire(const StringView & key,long long timeout)69 bool RedisCluster::expire(const StringView &key, long long timeout) {
70 auto reply = command(cmd::expire, key, timeout);
71
72 return reply::parse<bool>(*reply);
73 }
74
expireat(const StringView & key,long long timestamp)75 bool RedisCluster::expireat(const StringView &key, long long timestamp) {
76 auto reply = command(cmd::expireat, key, timestamp);
77
78 return reply::parse<bool>(*reply);
79 }
80
persist(const StringView & key)81 bool RedisCluster::persist(const StringView &key) {
82 auto reply = command(cmd::persist, key);
83
84 return reply::parse<bool>(*reply);
85 }
86
pexpire(const StringView & key,long long timeout)87 bool RedisCluster::pexpire(const StringView &key, long long timeout) {
88 auto reply = command(cmd::pexpire, key, timeout);
89
90 return reply::parse<bool>(*reply);
91 }
92
pexpireat(const StringView & key,long long timestamp)93 bool RedisCluster::pexpireat(const StringView &key, long long timestamp) {
94 auto reply = command(cmd::pexpireat, key, timestamp);
95
96 return reply::parse<bool>(*reply);
97 }
98
pttl(const StringView & key)99 long long RedisCluster::pttl(const StringView &key) {
100 auto reply = command(cmd::pttl, key);
101
102 return reply::parse<long long>(*reply);
103 }
104
rename(const StringView & key,const StringView & newkey)105 void RedisCluster::rename(const StringView &key, const StringView &newkey) {
106 auto reply = command(cmd::rename, key, newkey);
107
108 reply::parse<void>(*reply);
109 }
110
renamenx(const StringView & key,const StringView & newkey)111 bool RedisCluster::renamenx(const StringView &key, const StringView &newkey) {
112 auto reply = command(cmd::renamenx, key, newkey);
113
114 return reply::parse<bool>(*reply);
115 }
116
restore(const StringView & key,const StringView & val,long long ttl,bool replace)117 void RedisCluster::restore(const StringView &key,
118 const StringView &val,
119 long long ttl,
120 bool replace) {
121 auto reply = command(cmd::restore, key, val, ttl, replace);
122
123 reply::parse<void>(*reply);
124 }
125
touch(const StringView & key)126 long long RedisCluster::touch(const StringView &key) {
127 auto reply = command(cmd::touch, key);
128
129 return reply::parse<long long>(*reply);
130 }
131
ttl(const StringView & key)132 long long RedisCluster::ttl(const StringView &key) {
133 auto reply = command(cmd::ttl, key);
134
135 return reply::parse<long long>(*reply);
136 }
137
type(const StringView & key)138 std::string RedisCluster::type(const StringView &key) {
139 auto reply = command(cmd::type, key);
140
141 return reply::parse<std::string>(*reply);
142 }
143
unlink(const StringView & key)144 long long RedisCluster::unlink(const StringView &key) {
145 auto reply = command(cmd::unlink, key);
146
147 return reply::parse<long long>(*reply);
148 }
149
150 // STRING commands.
151
append(const StringView & key,const StringView & val)152 long long RedisCluster::append(const StringView &key, const StringView &val) {
153 auto reply = command(cmd::append, key, val);
154
155 return reply::parse<long long>(*reply);
156 }
157
bitcount(const StringView & key,long long start,long long end)158 long long RedisCluster::bitcount(const StringView &key, long long start, long long end) {
159 auto reply = command(cmd::bitcount, key, start, end);
160
161 return reply::parse<long long>(*reply);
162 }
163
bitop(BitOp op,const StringView & destination,const StringView & key)164 long long RedisCluster::bitop(BitOp op, const StringView &destination, const StringView &key) {
165 auto reply = _command(cmd::bitop, destination, op, destination, key);
166
167 return reply::parse<long long>(*reply);
168 }
169
bitpos(const StringView & key,long long bit,long long start,long long end)170 long long RedisCluster::bitpos(const StringView &key,
171 long long bit,
172 long long start,
173 long long end) {
174 auto reply = command(cmd::bitpos, key, bit, start, end);
175
176 return reply::parse<long long>(*reply);
177 }
178
decr(const StringView & key)179 long long RedisCluster::decr(const StringView &key) {
180 auto reply = command(cmd::decr, key);
181
182 return reply::parse<long long>(*reply);
183 }
184
decrby(const StringView & key,long long decrement)185 long long RedisCluster::decrby(const StringView &key, long long decrement) {
186 auto reply = command(cmd::decrby, key, decrement);
187
188 return reply::parse<long long>(*reply);
189 }
190
get(const StringView & key)191 OptionalString RedisCluster::get(const StringView &key) {
192 auto reply = command(cmd::get, key);
193
194 return reply::parse<OptionalString>(*reply);
195 }
196
getbit(const StringView & key,long long offset)197 long long RedisCluster::getbit(const StringView &key, long long offset) {
198 auto reply = command(cmd::getbit, key, offset);
199
200 return reply::parse<long long>(*reply);
201 }
202
getrange(const StringView & key,long long start,long long end)203 std::string RedisCluster::getrange(const StringView &key, long long start, long long end) {
204 auto reply = command(cmd::getrange, key, start, end);
205
206 return reply::parse<std::string>(*reply);
207 }
208
getset(const StringView & key,const StringView & val)209 OptionalString RedisCluster::getset(const StringView &key, const StringView &val) {
210 auto reply = command(cmd::getset, key, val);
211
212 return reply::parse<OptionalString>(*reply);
213 }
214
incr(const StringView & key)215 long long RedisCluster::incr(const StringView &key) {
216 auto reply = command(cmd::incr, key);
217
218 return reply::parse<long long>(*reply);
219 }
220
incrby(const StringView & key,long long increment)221 long long RedisCluster::incrby(const StringView &key, long long increment) {
222 auto reply = command(cmd::incrby, key, increment);
223
224 return reply::parse<long long>(*reply);
225 }
226
incrbyfloat(const StringView & key,double increment)227 double RedisCluster::incrbyfloat(const StringView &key, double increment) {
228 auto reply = command(cmd::incrbyfloat, key, increment);
229
230 return reply::parse<double>(*reply);
231 }
232
psetex(const StringView & key,long long ttl,const StringView & val)233 void RedisCluster::psetex(const StringView &key,
234 long long ttl,
235 const StringView &val) {
236 auto reply = command(cmd::psetex, key, ttl, val);
237
238 reply::parse<void>(*reply);
239 }
240
set(const StringView & key,const StringView & val,const std::chrono::milliseconds & ttl,UpdateType type)241 bool RedisCluster::set(const StringView &key,
242 const StringView &val,
243 const std::chrono::milliseconds &ttl,
244 UpdateType type) {
245 auto reply = command(cmd::set, key, val, ttl.count(), type);
246
247 reply::rewrite_set_reply(*reply);
248
249 return reply::parse<bool>(*reply);
250 }
251
setex(const StringView & key,long long ttl,const StringView & val)252 void RedisCluster::setex(const StringView &key,
253 long long ttl,
254 const StringView &val) {
255 auto reply = command(cmd::setex, key, ttl, val);
256
257 reply::parse<void>(*reply);
258 }
259
setnx(const StringView & key,const StringView & val)260 bool RedisCluster::setnx(const StringView &key, const StringView &val) {
261 auto reply = command(cmd::setnx, key, val);
262
263 return reply::parse<bool>(*reply);
264 }
265
setrange(const StringView & key,long long offset,const StringView & val)266 long long RedisCluster::setrange(const StringView &key, long long offset, const StringView &val) {
267 auto reply = command(cmd::setrange, key, offset, val);
268
269 return reply::parse<long long>(*reply);
270 }
271
strlen(const StringView & key)272 long long RedisCluster::strlen(const StringView &key) {
273 auto reply = command(cmd::strlen, key);
274
275 return reply::parse<long long>(*reply);
276 }
277
278 // LIST commands.
279
blpop(const StringView & key,long long timeout)280 OptionalStringPair RedisCluster::blpop(const StringView &key, long long timeout) {
281 auto reply = command(cmd::blpop, key, timeout);
282
283 return reply::parse<OptionalStringPair>(*reply);
284 }
285
blpop(const StringView & key,const std::chrono::seconds & timeout)286 OptionalStringPair RedisCluster::blpop(const StringView &key, const std::chrono::seconds &timeout) {
287 return blpop(key, timeout.count());
288 }
289
brpop(const StringView & key,long long timeout)290 OptionalStringPair RedisCluster::brpop(const StringView &key, long long timeout) {
291 auto reply = command(cmd::brpop, key, timeout);
292
293 return reply::parse<OptionalStringPair>(*reply);
294 }
295
brpop(const StringView & key,const std::chrono::seconds & timeout)296 OptionalStringPair RedisCluster::brpop(const StringView &key, const std::chrono::seconds &timeout) {
297 return brpop(key, timeout.count());
298 }
299
brpoplpush(const StringView & source,const StringView & destination,long long timeout)300 OptionalString RedisCluster::brpoplpush(const StringView &source,
301 const StringView &destination,
302 long long timeout) {
303 auto reply = command(cmd::brpoplpush, source, destination, timeout);
304
305 return reply::parse<OptionalString>(*reply);
306 }
307
lindex(const StringView & key,long long index)308 OptionalString RedisCluster::lindex(const StringView &key, long long index) {
309 auto reply = command(cmd::lindex, key, index);
310
311 return reply::parse<OptionalString>(*reply);
312 }
313
linsert(const StringView & key,InsertPosition position,const StringView & pivot,const StringView & val)314 long long RedisCluster::linsert(const StringView &key,
315 InsertPosition position,
316 const StringView &pivot,
317 const StringView &val) {
318 auto reply = command(cmd::linsert, key, position, pivot, val);
319
320 return reply::parse<long long>(*reply);
321 }
322
llen(const StringView & key)323 long long RedisCluster::llen(const StringView &key) {
324 auto reply = command(cmd::llen, key);
325
326 return reply::parse<long long>(*reply);
327 }
328
lpop(const StringView & key)329 OptionalString RedisCluster::lpop(const StringView &key) {
330 auto reply = command(cmd::lpop, key);
331
332 return reply::parse<OptionalString>(*reply);
333 }
334
lpush(const StringView & key,const StringView & val)335 long long RedisCluster::lpush(const StringView &key, const StringView &val) {
336 auto reply = command(cmd::lpush, key, val);
337
338 return reply::parse<long long>(*reply);
339 }
340
lpushx(const StringView & key,const StringView & val)341 long long RedisCluster::lpushx(const StringView &key, const StringView &val) {
342 auto reply = command(cmd::lpushx, key, val);
343
344 return reply::parse<long long>(*reply);
345 }
346
lrem(const StringView & key,long long count,const StringView & val)347 long long RedisCluster::lrem(const StringView &key, long long count, const StringView &val) {
348 auto reply = command(cmd::lrem, key, count, val);
349
350 return reply::parse<long long>(*reply);
351 }
352
lset(const StringView & key,long long index,const StringView & val)353 void RedisCluster::lset(const StringView &key, long long index, const StringView &val) {
354 auto reply = command(cmd::lset, key, index, val);
355
356 reply::parse<void>(*reply);
357 }
358
ltrim(const StringView & key,long long start,long long stop)359 void RedisCluster::ltrim(const StringView &key, long long start, long long stop) {
360 auto reply = command(cmd::ltrim, key, start, stop);
361
362 reply::parse<void>(*reply);
363 }
364
rpop(const StringView & key)365 OptionalString RedisCluster::rpop(const StringView &key) {
366 auto reply = command(cmd::rpop, key);
367
368 return reply::parse<OptionalString>(*reply);
369 }
370
rpoplpush(const StringView & source,const StringView & destination)371 OptionalString RedisCluster::rpoplpush(const StringView &source, const StringView &destination) {
372 auto reply = command(cmd::rpoplpush, source, destination);
373
374 return reply::parse<OptionalString>(*reply);
375 }
376
rpush(const StringView & key,const StringView & val)377 long long RedisCluster::rpush(const StringView &key, const StringView &val) {
378 auto reply = command(cmd::rpush, key, val);
379
380 return reply::parse<long long>(*reply);
381 }
382
rpushx(const StringView & key,const StringView & val)383 long long RedisCluster::rpushx(const StringView &key, const StringView &val) {
384 auto reply = command(cmd::rpushx, key, val);
385
386 return reply::parse<long long>(*reply);
387 }
388
hdel(const StringView & key,const StringView & field)389 long long RedisCluster::hdel(const StringView &key, const StringView &field) {
390 auto reply = command(cmd::hdel, key, field);
391
392 return reply::parse<long long>(*reply);
393 }
394
hexists(const StringView & key,const StringView & field)395 bool RedisCluster::hexists(const StringView &key, const StringView &field) {
396 auto reply = command(cmd::hexists, key, field);
397
398 return reply::parse<bool>(*reply);
399 }
400
hget(const StringView & key,const StringView & field)401 OptionalString RedisCluster::hget(const StringView &key, const StringView &field) {
402 auto reply = command(cmd::hget, key, field);
403
404 return reply::parse<OptionalString>(*reply);
405 }
406
hincrby(const StringView & key,const StringView & field,long long increment)407 long long RedisCluster::hincrby(const StringView &key, const StringView &field, long long increment) {
408 auto reply = command(cmd::hincrby, key, field, increment);
409
410 return reply::parse<long long>(*reply);
411 }
412
hincrbyfloat(const StringView & key,const StringView & field,double increment)413 double RedisCluster::hincrbyfloat(const StringView &key, const StringView &field, double increment) {
414 auto reply = command(cmd::hincrbyfloat, key, field, increment);
415
416 return reply::parse<double>(*reply);
417 }
418
hlen(const StringView & key)419 long long RedisCluster::hlen(const StringView &key) {
420 auto reply = command(cmd::hlen, key);
421
422 return reply::parse<long long>(*reply);
423 }
424
hset(const StringView & key,const StringView & field,const StringView & val)425 bool RedisCluster::hset(const StringView &key, const StringView &field, const StringView &val) {
426 auto reply = command(cmd::hset, key, field, val);
427
428 return reply::parse<bool>(*reply);
429 }
430
hset(const StringView & key,const std::pair<StringView,StringView> & item)431 bool RedisCluster::hset(const StringView &key, const std::pair<StringView, StringView> &item) {
432 return hset(key, item.first, item.second);
433 }
434
hsetnx(const StringView & key,const StringView & field,const StringView & val)435 bool RedisCluster::hsetnx(const StringView &key, const StringView &field, const StringView &val) {
436 auto reply = command(cmd::hsetnx, key, field, val);
437
438 return reply::parse<bool>(*reply);
439 }
440
hsetnx(const StringView & key,const std::pair<StringView,StringView> & item)441 bool RedisCluster::hsetnx(const StringView &key, const std::pair<StringView, StringView> &item) {
442 return hsetnx(key, item.first, item.second);
443 }
444
hstrlen(const StringView & key,const StringView & field)445 long long RedisCluster::hstrlen(const StringView &key, const StringView &field) {
446 auto reply = command(cmd::hstrlen, key, field);
447
448 return reply::parse<long long>(*reply);
449 }
450
451 // SET commands.
452
sadd(const StringView & key,const StringView & member)453 long long RedisCluster::sadd(const StringView &key, const StringView &member) {
454 auto reply = command(cmd::sadd, key, member);
455
456 return reply::parse<long long>(*reply);
457 }
458
scard(const StringView & key)459 long long RedisCluster::scard(const StringView &key) {
460 auto reply = command(cmd::scard, key);
461
462 return reply::parse<long long>(*reply);
463 }
464
sdiffstore(const StringView & destination,const StringView & key)465 long long RedisCluster::sdiffstore(const StringView &destination, const StringView &key) {
466 auto reply = command(cmd::sdiffstore, destination, key);
467
468 return reply::parse<long long>(*reply);
469 }
470
sinterstore(const StringView & destination,const StringView & key)471 long long RedisCluster::sinterstore(const StringView &destination, const StringView &key) {
472 auto reply = command(cmd::sinterstore, destination, key);
473
474 return reply::parse<long long>(*reply);
475 }
476
sismember(const StringView & key,const StringView & member)477 bool RedisCluster::sismember(const StringView &key, const StringView &member) {
478 auto reply = command(cmd::sismember, key, member);
479
480 return reply::parse<bool>(*reply);
481 }
482
smove(const StringView & source,const StringView & destination,const StringView & member)483 bool RedisCluster::smove(const StringView &source,
484 const StringView &destination,
485 const StringView &member) {
486 auto reply = command(cmd::smove, source, destination, member);
487
488 return reply::parse<bool>(*reply);
489 }
490
spop(const StringView & key)491 OptionalString RedisCluster::spop(const StringView &key) {
492 auto reply = command(cmd::spop, key);
493
494 return reply::parse<OptionalString>(*reply);
495 }
496
srandmember(const StringView & key)497 OptionalString RedisCluster::srandmember(const StringView &key) {
498 auto reply = command(cmd::srandmember, key);
499
500 return reply::parse<OptionalString>(*reply);
501 }
502
srem(const StringView & key,const StringView & member)503 long long RedisCluster::srem(const StringView &key, const StringView &member) {
504 auto reply = command(cmd::srem, key, member);
505
506 return reply::parse<long long>(*reply);
507 }
508
sunionstore(const StringView & destination,const StringView & key)509 long long RedisCluster::sunionstore(const StringView &destination, const StringView &key) {
510 auto reply = command(cmd::sunionstore, destination, key);
511
512 return reply::parse<long long>(*reply);
513 }
514
515 // SORTED SET commands.
516
bzpopmax(const StringView & key,long long timeout)517 auto RedisCluster::bzpopmax(const StringView &key, long long timeout)
518 -> Optional<std::tuple<std::string, std::string, double>> {
519 auto reply = command(cmd::bzpopmax, key, timeout);
520
521 return reply::parse<Optional<std::tuple<std::string, std::string, double>>>(*reply);
522 }
523
bzpopmin(const StringView & key,long long timeout)524 auto RedisCluster::bzpopmin(const StringView &key, long long timeout)
525 -> Optional<std::tuple<std::string, std::string, double>> {
526 auto reply = command(cmd::bzpopmin, key, timeout);
527
528 return reply::parse<Optional<std::tuple<std::string, std::string, double>>>(*reply);
529 }
530
zadd(const StringView & key,const StringView & member,double score,UpdateType type,bool changed)531 long long RedisCluster::zadd(const StringView &key,
532 const StringView &member,
533 double score,
534 UpdateType type,
535 bool changed) {
536 auto reply = command(cmd::zadd, key, member, score, type, changed);
537
538 return reply::parse<long long>(*reply);
539 }
540
zcard(const StringView & key)541 long long RedisCluster::zcard(const StringView &key) {
542 auto reply = command(cmd::zcard, key);
543
544 return reply::parse<long long>(*reply);
545 }
546
zincrby(const StringView & key,double increment,const StringView & member)547 double RedisCluster::zincrby(const StringView &key, double increment, const StringView &member) {
548 auto reply = command(cmd::zincrby, key, increment, member);
549
550 return reply::parse<double>(*reply);
551 }
552
zinterstore(const StringView & destination,const StringView & key,double weight)553 long long RedisCluster::zinterstore(const StringView &destination,
554 const StringView &key,
555 double weight) {
556 auto reply = command(cmd::zinterstore, destination, key, weight);
557
558 return reply::parse<long long>(*reply);
559 }
560
zpopmax(const StringView & key)561 Optional<std::pair<std::string, double>> RedisCluster::zpopmax(const StringView &key) {
562 auto reply = command(cmd::zpopmax, key, 1);
563
564 return reply::parse<Optional<std::pair<std::string, double>>>(*reply);
565 }
566
zpopmin(const StringView & key)567 Optional<std::pair<std::string, double>> RedisCluster::zpopmin(const StringView &key) {
568 auto reply = command(cmd::zpopmin, key, 1);
569
570 return reply::parse<Optional<std::pair<std::string, double>>>(*reply);
571 }
572
zrank(const StringView & key,const StringView & member)573 OptionalLongLong RedisCluster::zrank(const StringView &key, const StringView &member) {
574 auto reply = command(cmd::zrank, key, member);
575
576 return reply::parse<OptionalLongLong>(*reply);
577 }
578
zrem(const StringView & key,const StringView & member)579 long long RedisCluster::zrem(const StringView &key, const StringView &member) {
580 auto reply = command(cmd::zrem, key, member);
581
582 return reply::parse<long long>(*reply);
583 }
584
zremrangebyrank(const StringView & key,long long start,long long stop)585 long long RedisCluster::zremrangebyrank(const StringView &key, long long start, long long stop) {
586 auto reply = command(cmd::zremrangebyrank, key, start, stop);
587
588 return reply::parse<long long>(*reply);
589 }
590
zrevrank(const StringView & key,const StringView & member)591 OptionalLongLong RedisCluster::zrevrank(const StringView &key, const StringView &member) {
592 auto reply = command(cmd::zrevrank, key, member);
593
594 return reply::parse<OptionalLongLong>(*reply);
595 }
596
zscore(const StringView & key,const StringView & member)597 OptionalDouble RedisCluster::zscore(const StringView &key, const StringView &member) {
598 auto reply = command(cmd::zscore, key, member);
599
600 return reply::parse<OptionalDouble>(*reply);
601 }
602
zunionstore(const StringView & destination,const StringView & key,double weight)603 long long RedisCluster::zunionstore(const StringView &destination,
604 const StringView &key,
605 double weight) {
606 auto reply = command(cmd::zunionstore, destination, key, weight);
607
608 return reply::parse<long long>(*reply);
609 }
610
611 // HYPERLOGLOG commands.
612
pfadd(const StringView & key,const StringView & element)613 bool RedisCluster::pfadd(const StringView &key, const StringView &element) {
614 auto reply = command(cmd::pfadd, key, element);
615
616 return reply::parse<bool>(*reply);
617 }
618
pfcount(const StringView & key)619 long long RedisCluster::pfcount(const StringView &key) {
620 auto reply = command(cmd::pfcount, key);
621
622 return reply::parse<long long>(*reply);
623 }
624
pfmerge(const StringView & destination,const StringView & key)625 void RedisCluster::pfmerge(const StringView &destination, const StringView &key) {
626 auto reply = command(cmd::pfmerge, destination, key);
627
628 reply::parse<void>(*reply);
629 }
630
631 // GEO commands.
632
geoadd(const StringView & key,const std::tuple<StringView,double,double> & member)633 long long RedisCluster::geoadd(const StringView &key,
634 const std::tuple<StringView, double, double> &member) {
635 auto reply = command(cmd::geoadd, key, member);
636
637 return reply::parse<long long>(*reply);
638 }
639
geodist(const StringView & key,const StringView & member1,const StringView & member2,GeoUnit unit)640 OptionalDouble RedisCluster::geodist(const StringView &key,
641 const StringView &member1,
642 const StringView &member2,
643 GeoUnit unit) {
644 auto reply = command(cmd::geodist, key, member1, member2, unit);
645
646 return reply::parse<OptionalDouble>(*reply);
647 }
648
georadius(const StringView & key,const std::pair<double,double> & loc,double radius,GeoUnit unit,const StringView & destination,bool store_dist,long long count)649 OptionalLongLong RedisCluster::georadius(const StringView &key,
650 const std::pair<double, double> &loc,
651 double radius,
652 GeoUnit unit,
653 const StringView &destination,
654 bool store_dist,
655 long long count) {
656 auto reply = command(cmd::georadius_store,
657 key,
658 loc,
659 radius,
660 unit,
661 destination,
662 store_dist,
663 count);
664
665 reply::rewrite_georadius_reply(*reply);
666
667 return reply::parse<OptionalLongLong>(*reply);
668 }
669
georadiusbymember(const StringView & key,const StringView & member,double radius,GeoUnit unit,const StringView & destination,bool store_dist,long long count)670 OptionalLongLong RedisCluster::georadiusbymember(const StringView &key,
671 const StringView &member,
672 double radius,
673 GeoUnit unit,
674 const StringView &destination,
675 bool store_dist,
676 long long count) {
677 auto reply = command(cmd::georadiusbymember_store,
678 key,
679 member,
680 radius,
681 unit,
682 destination,
683 store_dist,
684 count);
685
686 reply::rewrite_georadius_reply(*reply);
687
688 return reply::parse<OptionalLongLong>(*reply);
689 }
690
691 // PUBSUB commands.
692
publish(const StringView & channel,const StringView & message)693 long long RedisCluster::publish(const StringView &channel, const StringView &message) {
694 auto reply = command(cmd::publish, channel, message);
695
696 return reply::parse<long long>(*reply);
697 }
698
699 // Stream commands.
700
xack(const StringView & key,const StringView & group,const StringView & id)701 long long RedisCluster::xack(const StringView &key, const StringView &group, const StringView &id) {
702 auto reply = command(cmd::xack, key, group, id);
703
704 return reply::parse<long long>(*reply);
705 }
706
xdel(const StringView & key,const StringView & id)707 long long RedisCluster::xdel(const StringView &key, const StringView &id) {
708 auto reply = command(cmd::xdel, key, id);
709
710 return reply::parse<long long>(*reply);
711 }
712
xgroup_create(const StringView & key,const StringView & group,const StringView & id,bool mkstream)713 void RedisCluster::xgroup_create(const StringView &key,
714 const StringView &group,
715 const StringView &id,
716 bool mkstream) {
717 auto reply = command(cmd::xgroup_create, key, group, id, mkstream);
718
719 reply::parse<void>(*reply);
720 }
721
xgroup_setid(const StringView & key,const StringView & group,const StringView & id)722 void RedisCluster::xgroup_setid(const StringView &key,
723 const StringView &group,
724 const StringView &id) {
725 auto reply = command(cmd::xgroup_setid, key, group, id);
726
727 reply::parse<void>(*reply);
728 }
729
xgroup_destroy(const StringView & key,const StringView & group)730 long long RedisCluster::xgroup_destroy(const StringView &key, const StringView &group) {
731 auto reply = command(cmd::xgroup_destroy, key, group);
732
733 return reply::parse<long long>(*reply);
734 }
735
xgroup_delconsumer(const StringView & key,const StringView & group,const StringView & consumer)736 long long RedisCluster::xgroup_delconsumer(const StringView &key,
737 const StringView &group,
738 const StringView &consumer) {
739 auto reply = command(cmd::xgroup_delconsumer, key, group, consumer);
740
741 return reply::parse<long long>(*reply);
742 }
743
xlen(const StringView & key)744 long long RedisCluster::xlen(const StringView &key) {
745 auto reply = command(cmd::xlen, key);
746
747 return reply::parse<long long>(*reply);
748 }
749
xtrim(const StringView & key,long long count,bool approx)750 long long RedisCluster::xtrim(const StringView &key, long long count, bool approx) {
751 auto reply = command(cmd::xtrim, key, count, approx);
752
753 return reply::parse<long long>(*reply);
754 }
755
_asking(Connection & connection)756 void RedisCluster::_asking(Connection &connection) {
757 // Send ASKING command.
758 connection.send("ASKING");
759
760 auto reply = connection.recv();
761
762 assert(reply);
763
764 reply::parse<void>(*reply);
765 }
766
767 }
768
769 }
770