1 /* 2 * Hunt - A redis client library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.redis.BinaryClient; 13 14 import hunt.redis.AbstractClient; 15 import hunt.redis.BitOP; 16 import hunt.redis.BitPosParams; 17 import hunt.redis.ListPosition; 18 import hunt.redis.GeoCoordinate; 19 import hunt.redis.GeoUnit; 20 import hunt.redis.Protocol; 21 import hunt.redis.ScanParams; 22 import hunt.redis.SortingParams; 23 import hunt.redis.ZParams; 24 25 // import hunt.redis.Protocol.Keyword; 26 import hunt.redis.params.ClientKillParams; 27 import hunt.redis.params.GeoRadiusParam; 28 import hunt.redis.params.MigrateParams; 29 import hunt.redis.params.SetParams; 30 import hunt.redis.params.ZAddParams; 31 import hunt.redis.params.ZIncrByParams; 32 import hunt.redis.util.SafeEncoder; 33 34 import hunt.collection.ArrayList; 35 import hunt.collection.List; 36 import hunt.collection.Map; 37 38 import std.conv; 39 40 alias Keyword = Protocol.Keyword; 41 alias Command = Protocol.Command; 42 alias toByteArray = Protocol.toByteArray; 43 44 class BinaryClient : AbstractClient { 45 46 private bool _isInMulti; 47 48 private string password; 49 50 private int db; 51 52 private bool _isInWatch; 53 54 this() { 55 super(); 56 } 57 58 this(string host) { 59 super(host); 60 } 61 62 this(string host, int port) { 63 super(host, port); 64 } 65 66 this(string host, int port, bool ssl) { 67 super(host, port, ssl); 68 } 69 70 // this(string host, int port, bool ssl, 71 // SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, 72 // HostnameVerifier hostnameVerifier) { 73 // super(host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier); 74 // } 75 76 bool isInMulti() { 77 return _isInMulti; 78 } 79 80 bool isInWatch() { 81 return _isInWatch; 82 } 83 84 private const(ubyte)[][] joinParameters(const(ubyte)[] first, const(ubyte)[][] rest) { 85 const(ubyte)[][] result = new const(ubyte)[][rest.length + 1]; 86 result[0] = first; 87 // System.arraycopy(rest, 0, result, 1, rest.length); 88 result[1 .. $] = rest[0 .. $]; 89 return result; 90 } 91 92 private const(ubyte)[][] joinParameters(const(ubyte)[] first, const(ubyte)[] second, const(ubyte)[][] rest) { 93 const(ubyte)[][] result = new const(ubyte)[][rest.length + 2]; 94 result[0] = first; 95 result[1] = second; 96 // System.arraycopy(rest, 0, result, 2, rest.length); 97 result[2 .. $] = rest[0 .. $]; 98 return result; 99 } 100 101 void setPassword(string password) { 102 this.password = password; 103 } 104 105 void setDb(int db) { 106 this.db = db; 107 } 108 109 override 110 void connect() { 111 if (!isConnected()) { 112 super.connect(); 113 if (password !is null) { 114 auth(password); 115 getStatusCodeReply(); 116 } 117 if (db > 0) { 118 select(db); 119 getStatusCodeReply(); 120 } 121 } 122 } 123 124 void ping() { 125 sendCommand(Command.PING); 126 } 127 128 void ping(const(ubyte)[] message) { 129 sendCommand(Command.PING, [message]); 130 } 131 132 void set(const(ubyte)[] key, const(ubyte)[] value) { 133 sendCommand(Command.SET, key, value); 134 } 135 136 void set(const(ubyte)[] key, const(ubyte)[] value, SetParams params) { 137 sendCommand(Command.SET, params.getByteParams(key, value)); 138 } 139 140 void get(const(ubyte)[] key) { 141 sendCommand(Command.GET, key); 142 } 143 144 void quit() { 145 db = 0; 146 sendCommand(Command.QUIT); 147 } 148 149 void exists(const(ubyte)[][] keys...) { 150 sendCommand(Command.EXISTS, keys); 151 } 152 153 void del(const(ubyte)[][] keys...) { 154 sendCommand(Command.DEL, keys); 155 } 156 157 void unlink(const(ubyte)[][] keys...) { 158 sendCommand(Command.UNLINK, keys); 159 } 160 161 void type(const(ubyte)[] key) { 162 sendCommand(Command.TYPE, key); 163 } 164 165 void flushDB() { 166 sendCommand(Command.FLUSHDB); 167 } 168 169 void keys(const(ubyte)[] pattern) { 170 sendCommand(Command.KEYS, pattern); 171 } 172 173 void randomKey() { 174 sendCommand(Command.RANDOMKEY); 175 } 176 177 void rename(const(ubyte)[] oldkey, const(ubyte)[] newkey) { 178 sendCommand(Command.RENAME, oldkey, newkey); 179 } 180 181 void renamenx(const(ubyte)[] oldkey, const(ubyte)[] newkey) { 182 sendCommand(Command.RENAMENX, oldkey, newkey); 183 } 184 185 void dbSize() { 186 sendCommand(Command.DBSIZE); 187 } 188 189 void expire(const(ubyte)[] key, int seconds) { 190 sendCommand(Command.EXPIRE, key, toByteArray(seconds)); 191 } 192 193 void expireAt(const(ubyte)[] key, long unixTime) { 194 sendCommand(Command.EXPIREAT, key, toByteArray(unixTime)); 195 } 196 197 void ttl(const(ubyte)[] key) { 198 sendCommand(Command.TTL, key); 199 } 200 201 void touch(const(ubyte)[][] keys...) { 202 sendCommand(Command.TOUCH, keys); 203 } 204 205 void select(int index) { 206 sendCommand(Command.SELECT, toByteArray(index)); 207 } 208 209 void swapDB(int index1, int index2) { 210 sendCommand(Command.SWAPDB, toByteArray(index1), toByteArray(index2)); 211 } 212 213 void move(const(ubyte)[] key, int dbIndex) { 214 sendCommand(Command.MOVE, key, toByteArray(dbIndex)); 215 } 216 217 void flushAll() { 218 sendCommand(Command.FLUSHALL); 219 } 220 221 void getSet(const(ubyte)[] key, const(ubyte)[] value) { 222 sendCommand(Command.GETSET, key, value); 223 } 224 225 void mget(const(ubyte)[][] keys...) { 226 sendCommand(Command.MGET, keys); 227 } 228 229 void setnx(const(ubyte)[] key, const(ubyte)[] value) { 230 sendCommand(Command.SETNX, key, value); 231 } 232 233 void setex(const(ubyte)[] key, int seconds, const(ubyte)[] value) { 234 sendCommand(Command.SETEX, key, toByteArray(seconds), value); 235 } 236 237 void mset(const(ubyte)[][] keysvalues...) { 238 sendCommand(Command.MSET, keysvalues); 239 } 240 241 void msetnx(const(ubyte)[][] keysvalues...) { 242 sendCommand(Command.MSETNX, keysvalues); 243 } 244 245 void decrBy(const(ubyte)[] key, long decrement) { 246 sendCommand(Command.DECRBY, key, toByteArray(decrement)); 247 } 248 249 void decr(const(ubyte)[] key) { 250 sendCommand(Command.DECR, key); 251 } 252 253 void incrBy(const(ubyte)[] key, long increment) { 254 sendCommand(Command.INCRBY, key, toByteArray(increment)); 255 } 256 257 void incrByFloat(const(ubyte)[] key, double increment) { 258 sendCommand(Command.INCRBYFLOAT, key, toByteArray(increment)); 259 } 260 261 void incr(const(ubyte)[] key) { 262 sendCommand(Command.INCR, key); 263 } 264 265 void append(const(ubyte)[] key, const(ubyte)[] value) { 266 sendCommand(Command.APPEND, key, value); 267 } 268 269 void substr(const(ubyte)[] key, int start, int end) { 270 sendCommand(Command.SUBSTR, key, toByteArray(start), toByteArray(end)); 271 } 272 273 void hset(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) { 274 sendCommand(Command.HSET, key, field, value); 275 } 276 277 void hset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) { 278 const(ubyte)[][] params = new const(ubyte)[][1 + hash.size() * 2]; 279 280 int index = 0; 281 params[index++] = key; 282 foreach (const(ubyte)[] k, const(ubyte)[] value; hash) { 283 params[index++] = k; 284 params[index++] = value; 285 } 286 sendCommand(Command.HSET, params); 287 } 288 289 void hget(const(ubyte)[] key, const(ubyte)[] field) { 290 sendCommand(Command.HGET, key, field); 291 } 292 293 void hsetnx(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) { 294 sendCommand(Command.HSETNX, key, field, value); 295 } 296 297 void hmset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) { 298 List!(const(ubyte)[]) params = new ArrayList!(const(ubyte)[])(); 299 params.add(key); 300 301 foreach(const(ubyte)[] k, const(ubyte)[] value ; hash) { 302 params.add(k); 303 params.add(value); 304 } 305 sendCommand(Command.HMSET, params.toArray()); 306 } 307 308 void hmget(const(ubyte)[] key, const(ubyte)[][] fields...) { 309 sendCommand(Command.HMGET, joinParameters(key, fields)); 310 } 311 312 void hincrBy(const(ubyte)[] key, const(ubyte)[] field, long value) { 313 sendCommand(Command.HINCRBY, key, field, toByteArray(value)); 314 } 315 316 void hexists(const(ubyte)[] key, const(ubyte)[] field) { 317 sendCommand(Command.HEXISTS, key, field); 318 } 319 320 void hdel(const(ubyte)[] key, const(ubyte)[][] fields...) { 321 sendCommand(Command.HDEL, joinParameters(key, fields)); 322 } 323 324 void hlen(const(ubyte)[] key) { 325 sendCommand(Command.HLEN, key); 326 } 327 328 void hkeys(const(ubyte)[] key) { 329 sendCommand(Command.HKEYS, key); 330 } 331 332 void hvals(const(ubyte)[] key) { 333 sendCommand(Command.HVALS, key); 334 } 335 336 void hgetAll(const(ubyte)[] key) { 337 sendCommand(Command.HGETALL, key); 338 } 339 340 void rpush(const(ubyte)[] key, const(ubyte)[][] strings...) { 341 sendCommand(Command.RPUSH, joinParameters(key, strings)); 342 } 343 344 void lpush(const(ubyte)[] key, const(ubyte)[][] strings...) { 345 sendCommand(Command.LPUSH, joinParameters(key, strings)); 346 } 347 348 void llen(const(ubyte)[] key) { 349 sendCommand(Command.LLEN, key); 350 } 351 352 void lrange(const(ubyte)[] key, long start, long stop) { 353 sendCommand(Command.LRANGE, key, toByteArray(start), toByteArray(stop)); 354 } 355 356 void ltrim(const(ubyte)[] key, long start, long stop) { 357 sendCommand(Command.LTRIM, key, toByteArray(start), toByteArray(stop)); 358 } 359 360 void lindex(const(ubyte)[] key, long index) { 361 sendCommand(Command.LINDEX, key, toByteArray(index)); 362 } 363 364 void lset(const(ubyte)[] key, long index, const(ubyte)[] value) { 365 sendCommand(Command.LSET, key, toByteArray(index), value); 366 } 367 368 void lrem(const(ubyte)[] key, long count, const(ubyte)[] value) { 369 sendCommand(Command.LREM, key, toByteArray(count), value); 370 } 371 372 void lpop(const(ubyte)[] key) { 373 sendCommand(Command.LPOP, key); 374 } 375 376 void rpop(const(ubyte)[] key) { 377 sendCommand(Command.RPOP, key); 378 } 379 380 void rpoplpush(const(ubyte)[] srckey, const(ubyte)[] dstkey) { 381 sendCommand(Command.RPOPLPUSH, srckey, dstkey); 382 } 383 384 void sadd(const(ubyte)[] key, const(ubyte)[][] members...) { 385 sendCommand(Command.SADD, joinParameters(key, members)); 386 } 387 388 void smembers(const(ubyte)[] key) { 389 sendCommand(Command.SMEMBERS, key); 390 } 391 392 void srem(const(ubyte)[] key, const(ubyte)[][] members...) { 393 sendCommand(Command.SREM, joinParameters(key, members)); 394 } 395 396 void spop(const(ubyte)[] key) { 397 sendCommand(Command.SPOP, key); 398 } 399 400 void spop(const(ubyte)[] key, long count) { 401 sendCommand(Command.SPOP, key, toByteArray(count)); 402 } 403 404 void smove(const(ubyte)[] srckey, const(ubyte)[] dstkey, const(ubyte)[] member) { 405 sendCommand(Command.SMOVE, srckey, dstkey, member); 406 } 407 408 void scard(const(ubyte)[] key) { 409 sendCommand(Command.SCARD, key); 410 } 411 412 void sismember(const(ubyte)[] key, const(ubyte)[] member) { 413 sendCommand(Command.SISMEMBER, key, member); 414 } 415 416 void sinter(const(ubyte)[][] keys...) { 417 sendCommand(Command.SINTER, keys); 418 } 419 420 void sinterstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) { 421 sendCommand(Command.SINTERSTORE, joinParameters(dstkey, keys)); 422 } 423 424 void sunion(const(ubyte)[][] keys...) { 425 sendCommand(Command.SUNION, keys); 426 } 427 428 void sunionstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) { 429 sendCommand(Command.SUNIONSTORE, joinParameters(dstkey, keys)); 430 } 431 432 void sdiff(const(ubyte)[][] keys...) { 433 sendCommand(Command.SDIFF, keys); 434 } 435 436 void sdiffstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) { 437 sendCommand(Command.SDIFFSTORE, joinParameters(dstkey, keys)); 438 } 439 440 void srandmember(const(ubyte)[] key) { 441 sendCommand(Command.SRANDMEMBER, key); 442 } 443 444 void zadd(const(ubyte)[] key, double score, const(ubyte)[] member) { 445 sendCommand(Command.ZADD, key, toByteArray(score), member); 446 } 447 448 void zadd(const(ubyte)[] key, double score, const(ubyte)[] member, 449 ZAddParams params) { 450 sendCommand(Command.ZADD, params.getByteParams(key, toByteArray(score), member)); 451 } 452 453 void zadd(const(ubyte)[] key, Map!(const(ubyte)[], double) scoreMembers) { 454 ArrayList!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(scoreMembers.size() * 2 + 1); 455 args.add(key); 456 args.addAll(convertScoreMembersToByteArrays(scoreMembers)); 457 458 const(ubyte)[][] argsArray = args.toArray(); 459 460 sendCommand(Command.ZADD, argsArray); 461 } 462 463 void zadd(const(ubyte)[] key, Map!(const(ubyte)[], double) scoreMembers, ZAddParams params) { 464 ArrayList!(const(ubyte)[]) args = convertScoreMembersToByteArrays(scoreMembers); 465 const(ubyte)[][] argsArray = args.toArray(); 466 467 sendCommand(Command.ZADD, params.getByteParams(key, argsArray)); 468 } 469 470 void zrange(const(ubyte)[] key, long start, long stop) { 471 sendCommand(Command.ZRANGE, key, toByteArray(start), toByteArray(stop)); 472 } 473 474 void zrem(const(ubyte)[] key, const(ubyte)[][] members...) { 475 sendCommand(Command.ZREM, joinParameters(key, members)); 476 } 477 478 void zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member) { 479 sendCommand(Command.ZINCRBY, key, toByteArray(increment), member); 480 } 481 482 void zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member, 483 ZIncrByParams params) { 484 // Note that it actually calls ZADD with INCR option, so it requires Redis 3.0.2 or upper. 485 sendCommand(Command.ZADD, params.getByteParams(key, toByteArray(increment), member)); 486 } 487 488 void zrank(const(ubyte)[] key, const(ubyte)[] member) { 489 sendCommand(Command.ZRANK, key, member); 490 } 491 492 void zrevrank(const(ubyte)[] key, const(ubyte)[] member) { 493 sendCommand(Command.ZREVRANK, key, member); 494 } 495 496 void zrevrange(const(ubyte)[] key, long start, long stop) { 497 sendCommand(Command.ZREVRANGE, key, toByteArray(start), toByteArray(stop)); 498 } 499 500 void zrangeWithScores(const(ubyte)[] key, long start, long stop) { 501 sendCommand(Command.ZRANGE, key, toByteArray(start), toByteArray(stop), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 502 } 503 504 void zrevrangeWithScores(const(ubyte)[] key, long start, long stop) { 505 sendCommand(Command.ZREVRANGE, key, toByteArray(start), toByteArray(stop), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 506 } 507 508 void zcard(const(ubyte)[] key) { 509 sendCommand(Command.ZCARD, key); 510 } 511 512 void zscore(const(ubyte)[] key, const(ubyte)[] member) { 513 sendCommand(Command.ZSCORE, key, member); 514 } 515 516 void multi() { 517 sendCommand(Command.MULTI); 518 _isInMulti = true; 519 } 520 521 void discard() { 522 sendCommand(Command.DISCARD); 523 _isInMulti = false; 524 _isInWatch = false; 525 } 526 527 void exec() { 528 sendCommand(Command.EXEC); 529 _isInMulti = false; 530 _isInWatch = false; 531 } 532 533 void watch(const(ubyte)[][] keys...) { 534 sendCommand(Command.WATCH, keys); 535 _isInWatch = true; 536 } 537 538 void unwatch() { 539 sendCommand(Command.UNWATCH); 540 _isInWatch = false; 541 } 542 543 void sort(const(ubyte)[] key) { 544 sendCommand(Command.SORT, key); 545 } 546 547 void sort(const(ubyte)[] key, SortingParams sortingParameters) { 548 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 549 args.add(key); 550 args.addAll(sortingParameters.getParams()); 551 sendCommand(Command.SORT, args.toArray()); 552 } 553 554 void blpop(const(ubyte)[][] args) { 555 sendCommand(Command.BLPOP, args); 556 } 557 558 void blpop(int timeout, const(ubyte)[][] keys...) { 559 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 560 foreach(const(ubyte)[] arg ; keys) { 561 args.add(arg); 562 } 563 args.add(Protocol.toByteArray(timeout)); 564 blpop(args.toArray()); 565 } 566 567 void sort(const(ubyte)[] key, SortingParams sortingParameters, const(ubyte)[] dstkey) { 568 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 569 args.add(key); 570 args.addAll(sortingParameters.getParams()); 571 args.add(cast(const(ubyte)[])to!string(Keyword.STORE)); 572 args.add(dstkey); 573 sendCommand(Command.SORT, args.toArray()); 574 } 575 576 void sort(const(ubyte)[] key, const(ubyte)[] dstkey) { 577 sendCommand(Command.SORT, key, cast(const(ubyte)[])to!string(Keyword.STORE), dstkey); 578 } 579 580 void brpop(const(ubyte)[][] args) { 581 sendCommand(Command.BRPOP, args); 582 } 583 584 void brpop(int timeout, const(ubyte)[][] keys...) { 585 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 586 foreach(const(ubyte)[] arg ; keys) { 587 args.add(arg); 588 } 589 args.add(Protocol.toByteArray(timeout)); 590 brpop(args.toArray()); 591 } 592 593 void auth(string password) { 594 import std.range; 595 if(password.empty) return; 596 setPassword(password); 597 sendCommand(Command.AUTH, password); 598 } 599 600 void subscribe(const(ubyte)[][] channels...) { 601 sendCommand(Command.SUBSCRIBE, channels); 602 } 603 604 void publish(const(ubyte)[] channel, const(ubyte)[] message) { 605 sendCommand(Command.PUBLISH, channel, message); 606 } 607 608 void unsubscribe() { 609 sendCommand(Command.UNSUBSCRIBE); 610 } 611 612 void unsubscribe(const(ubyte)[][] channels...) { 613 sendCommand(Command.UNSUBSCRIBE, channels); 614 } 615 616 void psubscribe(const(ubyte)[][] patterns...) { 617 sendCommand(Command.PSUBSCRIBE, patterns); 618 } 619 620 void punsubscribe() { 621 sendCommand(Command.PUNSUBSCRIBE); 622 } 623 624 void punsubscribe(const(ubyte)[][] patterns...) { 625 sendCommand(Command.PUNSUBSCRIBE, patterns); 626 } 627 628 void pubsub(const(ubyte)[][] args...) { 629 sendCommand(Command.PUBSUB, args); 630 } 631 632 void zcount(const(ubyte)[] key, double min, double max) { 633 sendCommand(Command.ZCOUNT, key, toByteArray(min), toByteArray(max)); 634 } 635 636 void zcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 637 sendCommand(Command.ZCOUNT, key, min, max); 638 } 639 640 void zrangeByScore(const(ubyte)[] key, double min, double max) { 641 sendCommand(Command.ZRANGEBYSCORE, key, toByteArray(min), toByteArray(max)); 642 } 643 644 void zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 645 sendCommand(Command.ZRANGEBYSCORE, key, min, max); 646 } 647 648 void zrevrangeByScore(const(ubyte)[] key, double max, double min) { 649 sendCommand(Command.ZREVRANGEBYSCORE, key, toByteArray(max), toByteArray(min)); 650 } 651 652 void zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) { 653 sendCommand(Command.ZREVRANGEBYSCORE, key, max, min); 654 } 655 656 void zrangeByScore(const(ubyte)[] key, double min, double max, int offset, 657 int count) { 658 sendCommand(Command.ZRANGEBYSCORE, key, toByteArray(min), toByteArray(max), cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), 659 toByteArray(count)); 660 } 661 662 void zrevrangeByScore(const(ubyte)[] key, double max, double min, 663 int offset, int count) { 664 sendCommand(Command.ZREVRANGEBYSCORE, key, toByteArray(max), toByteArray(min), cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), 665 toByteArray(count)); 666 } 667 668 void zrangeByScoreWithScores(const(ubyte)[] key, double min, double max) { 669 sendCommand(Command.ZRANGEBYSCORE, key, toByteArray(min), toByteArray(max), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 670 } 671 672 void zrevrangeByScoreWithScores(const(ubyte)[] key, double max, double min) { 673 sendCommand(Command.ZREVRANGEBYSCORE, key, toByteArray(max), toByteArray(min), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 674 } 675 676 void zrangeByScoreWithScores(const(ubyte)[] key, double min, double max, 677 int offset, int count) { 678 sendCommand(Command.ZRANGEBYSCORE, key, toByteArray(min), toByteArray(max), cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), 679 toByteArray(count), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 680 } 681 682 void zrevrangeByScoreWithScores(const(ubyte)[] key, double max, double min, 683 int offset, int count) { 684 sendCommand(Command.ZREVRANGEBYSCORE, key, toByteArray(max), toByteArray(min), cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), 685 toByteArray(count), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 686 } 687 688 void zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max, int offset, 689 int count) { 690 sendCommand(Command.ZRANGEBYSCORE, key, min, max, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), toByteArray(count)); 691 } 692 693 void zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, 694 int offset, int count) { 695 sendCommand(Command.ZREVRANGEBYSCORE, key, max, min, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), toByteArray(count)); 696 } 697 698 void zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 699 sendCommand(Command.ZRANGEBYSCORE, key, min, max, cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 700 } 701 702 void zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) { 703 sendCommand(Command.ZREVRANGEBYSCORE, key, max, min, cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 704 } 705 706 void zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max, 707 int offset, int count) { 708 sendCommand(Command.ZRANGEBYSCORE, key, min, max, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), toByteArray(count), 709 cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 710 } 711 712 void zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, 713 int offset, int count) { 714 sendCommand(Command.ZREVRANGEBYSCORE, key, max, min, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), 715 toByteArray(count), cast(const(ubyte)[])to!string(Keyword.WITHSCORES)); 716 } 717 718 void zremrangeByRank(const(ubyte)[] key, long start, long stop) { 719 sendCommand(Command.ZREMRANGEBYRANK, key, toByteArray(start), toByteArray(stop)); 720 } 721 722 void zremrangeByScore(const(ubyte)[] key, double min, double max) { 723 sendCommand(Command.ZREMRANGEBYSCORE, key, toByteArray(min), toByteArray(max)); 724 } 725 726 void zremrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 727 sendCommand(Command.ZREMRANGEBYSCORE, key, min, max); 728 } 729 730 void zunionstore(const(ubyte)[] dstkey, const(ubyte)[][] sets...) { 731 sendCommand(Command.ZUNIONSTORE, joinParameters(dstkey, toByteArray(sets.length), sets)); 732 } 733 734 void zunionstore(const(ubyte)[] dstkey, ZParams params, const(ubyte)[][] sets...) { 735 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 736 args.add(dstkey); 737 args.add(Protocol.toByteArray(sets.length)); 738 foreach(const(ubyte)[] set ; sets) { 739 args.add(set); 740 } 741 args.addAll(params.getParams()); 742 sendCommand(Command.ZUNIONSTORE, args.toArray()); 743 } 744 745 void zinterstore(const(ubyte)[] dstkey, const(ubyte)[][] sets...) { 746 sendCommand(Command.ZINTERSTORE, joinParameters(dstkey, Protocol.toByteArray(sets.length), sets)); 747 } 748 749 void zinterstore(const(ubyte)[] dstkey, ZParams params, const(ubyte)[][] sets...) { 750 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 751 args.add(dstkey); 752 args.add(Protocol.toByteArray(sets.length)); 753 foreach(const(ubyte)[] set ; sets) { 754 args.add(set); 755 } 756 args.addAll(params.getParams()); 757 sendCommand(Command.ZINTERSTORE, args.toArray()); 758 } 759 760 void zlexcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 761 sendCommand(Command.ZLEXCOUNT, key, min, max); 762 } 763 764 void zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 765 sendCommand(Command.ZRANGEBYLEX, key, min, max); 766 } 767 768 void zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max, int offset, 769 int count) { 770 sendCommand(Command.ZRANGEBYLEX, key, min, max, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), toByteArray(count)); 771 } 772 773 void zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) { 774 sendCommand(Command.ZREVRANGEBYLEX, key, max, min); 775 } 776 777 void zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, 778 int offset, int count) { 779 sendCommand(Command.ZREVRANGEBYLEX, key, max, min, cast(const(ubyte)[])to!string(Keyword.LIMIT), toByteArray(offset), toByteArray(count)); 780 } 781 782 void zremrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) { 783 sendCommand(Command.ZREMRANGEBYLEX, key, min, max); 784 } 785 786 void save() { 787 sendCommand(Command.SAVE); 788 } 789 790 void bgsave() { 791 sendCommand(Command.BGSAVE); 792 } 793 794 void bgrewriteaof() { 795 sendCommand(Command.BGREWRITEAOF); 796 } 797 798 void lastsave() { 799 sendCommand(Command.LASTSAVE); 800 } 801 802 void shutdown() { 803 sendCommand(Command.SHUTDOWN); 804 } 805 806 void info() { 807 sendCommand(Command.INFO); 808 } 809 810 void info(string section) { 811 sendCommand(Command.INFO, section); 812 } 813 814 void monitor() { 815 sendCommand(Command.MONITOR); 816 } 817 818 void slaveof(string host, int port) { 819 sendCommand(Command.SLAVEOF, host, port.to!string); 820 } 821 822 void slaveofNoOne() { 823 sendCommand(Command.SLAVEOF, cast(const(ubyte)[])to!string(Keyword.NO), cast(const(ubyte)[])to!string(Keyword.ONE)); 824 } 825 826 void configGet(const(ubyte)[] pattern) { 827 sendCommand(Command.CONFIG, cast(const(ubyte)[])to!string(Keyword.GET), pattern); 828 } 829 830 void configSet(const(ubyte)[] parameter, const(ubyte)[] value) { 831 sendCommand(Command.CONFIG, cast(const(ubyte)[])to!string(Keyword.SET), parameter, value); 832 } 833 834 void strlen(const(ubyte)[] key) { 835 sendCommand(Command.STRLEN, key); 836 } 837 838 void sync() { 839 sendCommand(Command.SYNC); 840 } 841 842 void lpushx(const(ubyte)[] key, const(ubyte)[][] strings...) { 843 sendCommand(Command.LPUSHX, joinParameters(key, strings)); 844 } 845 846 void persist(const(ubyte)[] key) { 847 sendCommand(Command.PERSIST, key); 848 } 849 850 void rpushx(const(ubyte)[] key, const(ubyte)[][] strings...) { 851 sendCommand(Command.RPUSHX, joinParameters(key, strings)); 852 } 853 854 void echo(const(ubyte)[] strings) { 855 sendCommand(Command.ECHO, strings); 856 } 857 858 void linsert(const(ubyte)[] key, ListPosition where, const(ubyte)[] pivot, 859 const(ubyte)[] value) { 860 sendCommand(Command.LINSERT, key, cast(const(ubyte)[])to!string(where), pivot, value); 861 } 862 863 // void debug(DebugParams params) { 864 // sendCommand(Command.DEBUG, params.getCommand()); 865 // } 866 867 void brpoplpush(const(ubyte)[] source, const(ubyte)[] destination, int timeout) { 868 sendCommand(Command.BRPOPLPUSH, source, destination, toByteArray(timeout)); 869 } 870 871 void configResetStat() { 872 sendCommand(Command.CONFIG, cast(const(ubyte)[])to!string(Keyword.RESETSTAT)); 873 } 874 875 void configRewrite() { 876 sendCommand(Command.CONFIG, cast(const(ubyte)[])to!string(Keyword.REWRITE)); 877 } 878 879 void setbit(const(ubyte)[] key, long offset, const(ubyte)[] value) { 880 sendCommand(Command.SETBIT, key, toByteArray(offset), value); 881 } 882 883 void setbit(const(ubyte)[] key, long offset, bool value) { 884 sendCommand(Command.SETBIT, key, toByteArray(offset), toByteArray(value)); 885 } 886 887 void getbit(const(ubyte)[] key, long offset) { 888 sendCommand(Command.GETBIT, key, toByteArray(offset)); 889 } 890 891 void bitpos(const(ubyte)[] key, bool value, BitPosParams params) { 892 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 893 args.add(key); 894 args.add(toByteArray(value)); 895 args.addAll(params.getParams()); 896 sendCommand(Command.BITPOS, args.toArray()); 897 } 898 899 void setrange(const(ubyte)[] key, long offset, const(ubyte)[] value) { 900 sendCommand(Command.SETRANGE, key, toByteArray(offset), value); 901 } 902 903 void getrange(const(ubyte)[] key, long startOffset, long endOffset) { 904 sendCommand(Command.GETRANGE, key, toByteArray(startOffset), toByteArray(endOffset)); 905 } 906 907 int getDB() { 908 return db; 909 } 910 911 // override 912 // void disconnect() { 913 // db = 0; 914 // super.disconnect(); 915 // } 916 917 override 918 void close() { 919 db = 0; 920 super.close(); 921 } 922 923 void resetState() { 924 if (isInWatch()) { 925 unwatch(); 926 getStatusCodeReply(); 927 } 928 } 929 930 void eval(const(ubyte)[] script, const(ubyte)[] keyCount, const(ubyte)[][] params) { 931 sendCommand(Command.EVAL, joinParameters(script, keyCount, params)); 932 } 933 934 void eval(const(ubyte)[] script, int keyCount, const(ubyte)[][] params...) { 935 sendCommand(Command.EVAL, joinParameters(script, toByteArray(keyCount), params)); 936 } 937 938 void evalsha(const(ubyte)[] sha1, const(ubyte)[] keyCount, const(ubyte)[][] params...) { 939 sendCommand(Command.EVALSHA, joinParameters(sha1, keyCount, params)); 940 } 941 942 void evalsha(const(ubyte)[] sha1, int keyCount, const(ubyte)[][] params...) { 943 sendCommand(Command.EVALSHA, joinParameters(sha1, toByteArray(keyCount), params)); 944 } 945 946 void scriptFlush() { 947 sendCommand(Command.SCRIPT, cast(const(ubyte)[])to!string(Keyword.FLUSH)); 948 } 949 950 void scriptExists(const(ubyte)[][] sha1...) { 951 sendCommand(Command.SCRIPT, joinParameters(cast(const(ubyte)[])to!string(Keyword.EXISTS), sha1)); 952 } 953 954 void scriptLoad(const(ubyte)[] script) { 955 sendCommand(Command.SCRIPT, cast(const(ubyte)[])to!string(Keyword.LOAD), script); 956 } 957 958 void scriptKill() { 959 sendCommand(Command.SCRIPT, cast(const(ubyte)[])to!string(Keyword.KILL)); 960 } 961 962 void slowlogGet() { 963 sendCommand(Command.SLOWLOG, cast(const(ubyte)[])to!string(Keyword.GET)); 964 } 965 966 void slowlogGet(long entries) { 967 sendCommand(Command.SLOWLOG, cast(const(ubyte)[])to!string(Keyword.GET), toByteArray(entries)); 968 } 969 970 void slowlogReset() { 971 sendCommand(Command.SLOWLOG, cast(const(ubyte)[])to!string(Keyword.RESET)); 972 } 973 974 void slowlogLen() { 975 sendCommand(Command.SLOWLOG, cast(const(ubyte)[])to!string(Keyword.LEN)); 976 } 977 978 void objectRefcount(const(ubyte)[] key) { 979 sendCommand(Command.OBJECT, cast(const(ubyte)[])to!string(Keyword.REFCOUNT), key); 980 } 981 982 void objectIdletime(const(ubyte)[] key) { 983 sendCommand(Command.OBJECT, cast(const(ubyte)[])to!string(Keyword.IDLETIME), key); 984 } 985 986 void objectEncoding(const(ubyte)[] key) { 987 sendCommand(Command.OBJECT, cast(const(ubyte)[])to!string(Keyword.ENCODING), key); 988 } 989 990 void bitcount(const(ubyte)[] key) { 991 sendCommand(Command.BITCOUNT, key); 992 } 993 994 void bitcount(const(ubyte)[] key, long start, long end) { 995 sendCommand(Command.BITCOUNT, key, toByteArray(start), toByteArray(end)); 996 } 997 998 void bitop(BitOP op, const(ubyte)[] destKey, const(ubyte)[][] srcKeys...) { 999 sendCommand(Command.BITOP, joinParameters(cast(const(ubyte)[])to!string(op), destKey, srcKeys)); 1000 } 1001 1002 void sentinel(const(ubyte)[][] args...) { 1003 sendCommand(Command.SENTINEL, args); 1004 } 1005 1006 void dump(const(ubyte)[] key) { 1007 sendCommand(Command.DUMP, key); 1008 } 1009 1010 void restore(const(ubyte)[] key, int ttl, const(ubyte)[] serializedValue) { 1011 sendCommand(Command.RESTORE, key, toByteArray(ttl), serializedValue); 1012 } 1013 1014 void restoreReplace(const(ubyte)[] key, int ttl, const(ubyte)[] serializedValue) { 1015 sendCommand(Command.RESTORE, key, toByteArray(ttl), serializedValue, cast(const(ubyte)[])to!string(Keyword.REPLACE)); 1016 } 1017 1018 void pexpire(const(ubyte)[] key, long milliseconds) { 1019 sendCommand(Command.PEXPIRE, key, toByteArray(milliseconds)); 1020 } 1021 1022 void pexpireAt(const(ubyte)[] key, long millisecondsTimestamp) { 1023 sendCommand(Command.PEXPIREAT, key, toByteArray(millisecondsTimestamp)); 1024 } 1025 1026 void pttl(const(ubyte)[] key) { 1027 sendCommand(Command.PTTL, key); 1028 } 1029 1030 void psetex(const(ubyte)[] key, long milliseconds, const(ubyte)[] value) { 1031 sendCommand(Command.PSETEX, key, toByteArray(milliseconds), value); 1032 } 1033 1034 void srandmember(const(ubyte)[] key, int count) { 1035 sendCommand(Command.SRANDMEMBER, key, toByteArray(count)); 1036 } 1037 1038 void memoryDoctor() { 1039 sendCommand(Command.MEMORY, cast(const(ubyte)[])to!string(Keyword.DOCTOR)); 1040 } 1041 1042 void clientKill(const(ubyte)[] ipPort) { 1043 sendCommand(Command.CLIENT, cast(const(ubyte)[])to!string(Keyword.KILL), ipPort); 1044 } 1045 1046 void clientKill(string ip, int port) { 1047 sendCommand(Command.CLIENT, Keyword.KILL.to!string(), ip ~ ":" ~ port.to!string); 1048 } 1049 1050 void clientKill(ClientKillParams params) { 1051 sendCommand(Command.CLIENT, joinParameters(cast(const(ubyte)[])to!string(Keyword.KILL), params.getByteParams())); 1052 } 1053 1054 void clientGetname() { 1055 sendCommand(Command.CLIENT, cast(const(ubyte)[])to!string(Keyword.GETNAME)); 1056 } 1057 1058 void clientList() { 1059 sendCommand(Command.CLIENT, cast(const(ubyte)[])to!string(Keyword.LIST)); 1060 } 1061 1062 void clientSetname(const(ubyte)[] name) { 1063 sendCommand(Command.CLIENT, cast(const(ubyte)[])to!string(Keyword.SETNAME), name); 1064 } 1065 1066 void clientPause(long timeout) { 1067 sendCommand(Command.CLIENT, cast(const(ubyte)[])to!string(Keyword.PAUSE), toByteArray(timeout)); 1068 } 1069 1070 void time() { 1071 sendCommand(Command.TIME); 1072 } 1073 1074 void migrate(string host, int port, const(ubyte)[] key, int destinationDb, 1075 int timeout) { 1076 sendCommand(Command.MIGRATE, SafeEncoder.encode(host), toByteArray(port), key, 1077 toByteArray(destinationDb), toByteArray(timeout)); 1078 } 1079 1080 void migrate(string host, int port, int destinationDB, 1081 int timeout, MigrateParams params, const(ubyte)[][] keys...) { 1082 const(ubyte)[][] bparams = params.getByteParams(); 1083 int len = cast(int)(5 + bparams.length + 1 + keys.length); 1084 const(ubyte)[][] args = new const(ubyte)[][len]; 1085 int i = 0; 1086 args[i++] = SafeEncoder.encode(host); 1087 args[i++] = toByteArray(port); 1088 args[i++] = []; 1089 args[i++] = toByteArray(destinationDB); 1090 args[i++] = toByteArray(timeout); 1091 // System.arraycopy(bparams, 0, args, i, bparams.length); 1092 args[i .. i+bparams.length] = bparams[0 .. $]; 1093 i += bparams.length; 1094 args[i++] = cast(const(ubyte)[])to!string(Keyword.KEYS); 1095 // System.arraycopy(keys, 0, args, i, keys.length); 1096 args[i .. i+keys.length] = keys[0 .. $]; 1097 sendCommand(Command.MIGRATE, args); 1098 } 1099 1100 void hincrByFloat(const(ubyte)[] key, const(ubyte)[] field, double increment) { 1101 sendCommand(Command.HINCRBYFLOAT, key, field, toByteArray(increment)); 1102 } 1103 1104 void scan(const(ubyte)[] cursor, ScanParams params) { 1105 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 1106 args.add(cursor); 1107 args.addAll(params.getParams()); 1108 sendCommand(Command.SCAN, args.toArray()); 1109 } 1110 1111 void hscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) { 1112 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 1113 args.add(key); 1114 args.add(cursor); 1115 args.addAll(params.getParams()); 1116 sendCommand(Command.HSCAN, args.toArray()); 1117 } 1118 1119 void sscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) { 1120 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 1121 args.add(key); 1122 args.add(cursor); 1123 args.addAll(params.getParams()); 1124 sendCommand(Command.SSCAN, args.toArray()); 1125 } 1126 1127 void zscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) { 1128 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(); 1129 args.add(key); 1130 args.add(cursor); 1131 args.addAll(params.getParams()); 1132 sendCommand(Command.ZSCAN, args.toArray()); 1133 } 1134 1135 void waitReplicas(int replicas, long timeout) { 1136 sendCommand(Command.WAIT, toByteArray(replicas), toByteArray(timeout)); 1137 } 1138 1139 void cluster(const(ubyte)[][] args...) { 1140 sendCommand(Command.CLUSTER, args); 1141 } 1142 1143 void asking() { 1144 sendCommand(Command.ASKING); 1145 } 1146 1147 void pfadd(const(ubyte)[] key, const(ubyte)[][] elements...) { 1148 sendCommand(Command.PFADD, joinParameters(key, elements)); 1149 } 1150 1151 void pfcount(const(ubyte)[] key) { 1152 sendCommand(Command.PFCOUNT, key); 1153 } 1154 1155 void pfcount(const(ubyte)[][] keys...) { 1156 sendCommand(Command.PFCOUNT, keys); 1157 } 1158 1159 void pfmerge(const(ubyte)[] destkey, const(ubyte)[][] sourcekeys...) { 1160 sendCommand(Command.PFMERGE, joinParameters(destkey, sourcekeys)); 1161 } 1162 1163 void readonly() { 1164 sendCommand(Command.READONLY); 1165 } 1166 1167 void geoadd(const(ubyte)[] key, double longitude, double latitude, const(ubyte)[] member) { 1168 sendCommand(Command.GEOADD, key, toByteArray(longitude), toByteArray(latitude), member); 1169 } 1170 1171 void geoadd(const(ubyte)[] key, Map!(const(ubyte)[], GeoCoordinate) memberCoordinateMap) { 1172 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(memberCoordinateMap.size() * 3 + 1); 1173 args.add(key); 1174 args.addAll(convertGeoCoordinateMapToByteArrays(memberCoordinateMap)); 1175 1176 const(ubyte)[][] argsArray = args.toArray(); 1177 1178 sendCommand(Command.GEOADD, argsArray); 1179 } 1180 1181 void geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2) { 1182 sendCommand(Command.GEODIST, key, member1, member2); 1183 } 1184 1185 void geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2, GeoUnit unit) { 1186 sendCommand(Command.GEODIST, key, member1, member2, cast(const(ubyte)[])(unit.toString())); 1187 } 1188 1189 void geohash(const(ubyte)[] key, const(ubyte)[][] members...) { 1190 sendCommand(Command.GEOHASH, joinParameters(key, members)); 1191 } 1192 1193 void geopos(const(ubyte)[] key, const(ubyte)[][] members) { 1194 sendCommand(Command.GEOPOS, joinParameters(key, members)); 1195 } 1196 1197 void georadius(const(ubyte)[] key, double longitude, double latitude, double radius, GeoUnit unit) { 1198 sendCommand(Command.GEORADIUS, key, toByteArray(longitude), toByteArray(latitude), toByteArray(radius), 1199 cast(const(ubyte)[])(unit.toString())); 1200 } 1201 1202 void georadiusReadonly(const(ubyte)[] key, double longitude, double latitude, double radius, GeoUnit unit) { 1203 sendCommand(Command.GEORADIUS_RO, key, toByteArray(longitude), toByteArray(latitude), toByteArray(radius), 1204 cast(const(ubyte)[])(unit.toString())); 1205 } 1206 1207 void georadius(const(ubyte)[] key, double longitude, double latitude, double radius, GeoUnit unit, 1208 GeoRadiusParam param) { 1209 sendCommand(Command.GEORADIUS, param.getByteParams(key, toByteArray(longitude), toByteArray(latitude), 1210 toByteArray(radius), cast(const(ubyte)[])(unit.toString()))); 1211 } 1212 1213 void georadiusReadonly(const(ubyte)[] key, double longitude, double latitude, double radius, GeoUnit unit, 1214 GeoRadiusParam param) { 1215 sendCommand(Command.GEORADIUS_RO, param.getByteParams(key, toByteArray(longitude), toByteArray(latitude), 1216 toByteArray(radius), cast(const(ubyte)[])(unit.toString()))); 1217 } 1218 1219 void georadiusByMember(const(ubyte)[] key, const(ubyte)[] member, double radius, GeoUnit unit) { 1220 sendCommand(Command.GEORADIUSBYMEMBER, key, member, toByteArray(radius), cast(const(ubyte)[])(unit.toString())); 1221 } 1222 1223 void georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member, double radius, GeoUnit unit) { 1224 sendCommand(Command.GEORADIUSBYMEMBER_RO, key, member, toByteArray(radius), cast(const(ubyte)[])(unit.toString())); 1225 } 1226 1227 void georadiusByMember(const(ubyte)[] key, const(ubyte)[] member, double radius, GeoUnit unit, 1228 GeoRadiusParam param) { 1229 sendCommand(Command.GEORADIUSBYMEMBER, param.getByteParams(key, member, toByteArray(radius), cast(const(ubyte)[])(unit.toString()))); 1230 } 1231 1232 void georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member, double radius, GeoUnit unit, 1233 GeoRadiusParam param) { 1234 sendCommand(Command.GEORADIUSBYMEMBER_RO, param.getByteParams(key, member, toByteArray(radius), cast(const(ubyte)[])(unit.toString()))); 1235 } 1236 1237 void moduleLoad(const(ubyte)[] path) { 1238 sendCommand(Command.MODULE, cast(const(ubyte)[])to!string(Keyword.LOAD), path); 1239 } 1240 1241 void moduleList() { 1242 sendCommand(Command.MODULE, cast(const(ubyte)[])to!string(Keyword.LIST)); 1243 } 1244 1245 void moduleUnload(const(ubyte)[] name) { 1246 sendCommand(Command.MODULE, cast(const(ubyte)[])to!string(Keyword.UNLOAD), name); 1247 } 1248 1249 private ArrayList!(const(ubyte)[]) convertScoreMembersToByteArrays(Map!(const(ubyte)[], double) scoreMembers) { 1250 ArrayList!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(scoreMembers.size() * 2); 1251 1252 foreach(const(ubyte)[] key, double value ; scoreMembers) { 1253 args.add(toByteArray(value)); 1254 args.add(key); 1255 } 1256 1257 return args; 1258 } 1259 1260 private List!(const(ubyte)[]) convertGeoCoordinateMapToByteArrays( 1261 Map!(const(ubyte)[], GeoCoordinate) memberCoordinateMap) { 1262 List!(const(ubyte)[]) args = new ArrayList!(const(ubyte)[])(memberCoordinateMap.size() * 3); 1263 1264 foreach(const(ubyte)[] key, GeoCoordinate coordinate ; memberCoordinateMap) { 1265 args.add(toByteArray(coordinate.getLongitude())); 1266 args.add(toByteArray(coordinate.getLatitude())); 1267 args.add(key); 1268 } 1269 1270 return args; 1271 } 1272 1273 void bitfield(const(ubyte)[] key, const(ubyte)[][] value...) { 1274 sendCommand(Command.BITFIELD, joinParameters(key, value)); 1275 } 1276 1277 void hstrlen(const(ubyte)[] key, const(ubyte)[] field) { 1278 sendCommand(Command.HSTRLEN, key, field); 1279 } 1280 1281 void xadd(const(ubyte)[] key, const(ubyte)[] id, Map!(const(ubyte)[], const(ubyte)[]) hash, long maxLen, bool approximateLength) { 1282 int maxLexArgs = 0; 1283 if(maxLen < long.max) { // optional arguments 1284 if(approximateLength) { 1285 maxLexArgs = 3; // e.g. MAXLEN ~ 1000 1286 } else { 1287 maxLexArgs = 2; // e.g. MAXLEN 1000 1288 } 1289 } 1290 1291 const(ubyte)[][] params = new const(ubyte)[][2 + maxLexArgs + hash.size() * 2]; 1292 int index = 0; 1293 params[index++] = key; 1294 if(maxLen < long.max) { 1295 params[index++] = cast(const(ubyte)[])to!string(Keyword.MAXLEN); 1296 if(approximateLength) { 1297 params[index++] = cast(const(ubyte)[])Protocol.BYTES_TILDE; 1298 } 1299 params[index++] = toByteArray(maxLen); 1300 } 1301 1302 params[index++] = id; 1303 foreach(const(ubyte)[] k, const(ubyte)[] value ; hash) { 1304 params[index++] = k; 1305 params[index++] = value; 1306 } 1307 sendCommand(Command.XADD, params); 1308 } 1309 1310 void xlen(const(ubyte)[] key) { 1311 sendCommand(Command.XLEN, key); 1312 } 1313 1314 void xrange(const(ubyte)[] key, const(ubyte)[] start, const(ubyte)[] end, long count) { 1315 sendCommand(Command.XRANGE, key, start, end, cast(const(ubyte)[])to!string(Keyword.COUNT), toByteArray(count)); 1316 } 1317 1318 void xrevrange(const(ubyte)[] key, const(ubyte)[] end, const(ubyte)[] start, int count) { 1319 sendCommand(Command.XREVRANGE, key, end, start, cast(const(ubyte)[])to!string(Keyword.COUNT), toByteArray(count)); 1320 } 1321 1322 void xread(int count, long block, Map!(const(ubyte)[], const(ubyte)[]) streams) { 1323 const(ubyte)[][] params = new const(ubyte)[][3 + streams.size() * 2 + (block > 0 ? 2 : 0)]; 1324 1325 int streamsIndex = 0; 1326 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.COUNT); 1327 params[streamsIndex++] = toByteArray(count); 1328 if(block > 0) { 1329 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.BLOCK); 1330 params[streamsIndex++] = toByteArray(block); 1331 } 1332 1333 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.STREAMS); 1334 int idsIndex = streamsIndex + streams.size(); 1335 1336 foreach(const(ubyte)[] key, const(ubyte)[] value; streams) { 1337 params[streamsIndex++] = key; 1338 params[idsIndex++] = value; 1339 } 1340 1341 sendCommand(Command.XREAD, params); 1342 } 1343 1344 void xack(const(ubyte)[] key, const(ubyte)[] group, const(ubyte)[][] ids...) { 1345 const(ubyte)[][] params = new const(ubyte)[][2 + ids.length]; 1346 int index = 0; 1347 params[index++] = key; 1348 params[index++] = group; 1349 foreach(const(ubyte)[] id ; ids) { 1350 params[index++] = id; 1351 } 1352 sendCommand(Command.XACK, params); 1353 } 1354 1355 void xgroupCreate(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] id, bool makeStream) { 1356 if(makeStream) { 1357 sendCommand(Command.XGROUP, cast(const(ubyte)[])to!string(Keyword.CREATE), key, groupname, id, cast(const(ubyte)[])to!string(Keyword.MKSTREAM)); 1358 } else { 1359 sendCommand(Command.XGROUP, cast(const(ubyte)[])to!string(Keyword.CREATE), key, groupname, id); 1360 } 1361 } 1362 1363 void xgroupSetID(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] id) { 1364 sendCommand(Command.XGROUP, cast(const(ubyte)[])to!string(Keyword.SETID), key, groupname, id); 1365 } 1366 1367 void xgroupDestroy(const(ubyte)[] key, const(ubyte)[] groupname) { 1368 sendCommand(Command.XGROUP, cast(const(ubyte)[])to!string(Keyword.DESTROY), key, groupname); 1369 } 1370 1371 void xgroupDelConsumer(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] consumerName) { 1372 sendCommand(Command.XGROUP, cast(const(ubyte)[])to!string(Keyword.DELCONSUMER), key, groupname, consumerName); 1373 } 1374 1375 void xdel(const(ubyte)[] key, const(ubyte)[][] ids...) { 1376 const(ubyte)[][] params = new const(ubyte)[][1 + ids.length]; 1377 int index = 0; 1378 params[index++] = key; 1379 foreach(const(ubyte)[] id ; ids) { 1380 params[index++] = id; 1381 } 1382 sendCommand(Command.XDEL, params); 1383 } 1384 1385 void xtrim(const(ubyte)[] key, long maxLen, bool approximateLength) { 1386 if(approximateLength) { 1387 sendCommand(Command.XTRIM, key, cast(const(ubyte)[])to!string(Keyword.MAXLEN), Protocol.BYTES_TILDE ,toByteArray(maxLen)); 1388 } else { 1389 sendCommand(Command.XTRIM, key, cast(const(ubyte)[])to!string(Keyword.MAXLEN), toByteArray(maxLen)); 1390 } 1391 } 1392 1393 void xreadGroup(const(ubyte)[] groupname, const(ubyte)[] consumer, int count, 1394 long block, bool noAck, Map!(const(ubyte)[], const(ubyte)[]) streams) { 1395 1396 int optional = 0; 1397 if(count>0) { 1398 optional += 2; 1399 } 1400 if(block > 0) { 1401 optional += 2; 1402 } 1403 if(noAck) { 1404 optional += 1; 1405 } 1406 1407 1408 const(ubyte)[][] params = new const(ubyte)[][4 + optional + streams.size() * 2]; 1409 1410 int streamsIndex = 0; 1411 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.GROUP); 1412 params[streamsIndex++] = groupname; 1413 params[streamsIndex++] = consumer; 1414 if(count>0) { 1415 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.COUNT); 1416 params[streamsIndex++] = toByteArray(count); 1417 } 1418 if(block > 0) { 1419 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.BLOCK); 1420 params[streamsIndex++] = toByteArray(block); 1421 } 1422 if(noAck) { 1423 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.NOACK); 1424 } 1425 params[streamsIndex++] = cast(const(ubyte)[])to!string(Keyword.STREAMS); 1426 1427 int idsIndex = streamsIndex + streams.size(); 1428 foreach(const(ubyte)[] key, const(ubyte)[] value ; streams) { 1429 params[streamsIndex++] = key; 1430 params[idsIndex++] = value; 1431 } 1432 1433 sendCommand(Command.XREADGROUP, params); 1434 } 1435 1436 1437 void xpending(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] start, 1438 const(ubyte)[] end, int count, const(ubyte)[] consumername) { 1439 if(consumername is null) { 1440 sendCommand(Command.XPENDING, key, groupname, start, end, toByteArray(count)); 1441 } else { 1442 sendCommand(Command.XPENDING, key, groupname, start, end, toByteArray(count), consumername); 1443 } 1444 } 1445 1446 void xclaim(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] consumername, long minIdleTime, 1447 long newIdleTime, int retries, bool force, const(ubyte)[][] ids) { 1448 1449 ArrayList!(const(ubyte)[]) arguments = new ArrayList!(const(ubyte)[])(cast(int)(10 + ids.length)); 1450 1451 arguments.add(key); 1452 arguments.add(groupname); 1453 arguments.add(consumername); 1454 arguments.add(toByteArray(minIdleTime)); 1455 1456 foreach(const(ubyte)[] id ; ids) { 1457 arguments.add(id); 1458 } 1459 if(newIdleTime > 0) { 1460 arguments.add(cast(const(ubyte)[])to!string(Keyword.IDLE)); 1461 arguments.add(toByteArray(newIdleTime)); 1462 } 1463 if(retries > 0) { 1464 arguments.add(cast(const(ubyte)[])to!string(Keyword.RETRYCOUNT)); 1465 arguments.add(toByteArray(retries)); 1466 } 1467 if(force) { 1468 arguments.add(cast(const(ubyte)[])to!string(Keyword.FORCE)); 1469 } 1470 sendCommand(Command.XCLAIM, arguments.toArray()); 1471 } 1472 1473 }