12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523 |
- /**************************************************************************
- Copyright (c) 2017 sewenew
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- *************************************************************************/
- #ifndef SEWENEW_REDISPLUSPLUS_REDIS_H
- #define SEWENEW_REDISPLUSPLUS_REDIS_H
- #include <string>
- #include <chrono>
- #include <memory>
- #include <initializer_list>
- #include <tuple>
- #include "connection_pool.h"
- #include "reply.h"
- #include "command_options.h"
- #include "utils.h"
- #include "subscriber.h"
- #include "pipeline.h"
- #include "transaction.h"
- #include "sentinel.h"
- namespace sw {
- namespace redis {
- template <typename Impl>
- class QueuedRedis;
- using Transaction = QueuedRedis<TransactionImpl>;
- using Pipeline = QueuedRedis<PipelineImpl>;
- class Redis {
- public:
- Redis(const ConnectionOptions &connection_opts,
- const ConnectionPoolOptions &pool_opts = {}) : _pool(pool_opts, connection_opts) {}
- // Construct Redis instance with URI:
- // "tcp://127.0.0.1", "tcp://127.0.0.1:6379", or "unix://path/to/socket"
- explicit Redis(const std::string &uri);
- Redis(const std::shared_ptr<Sentinel> &sentinel,
- const std::string &master_name,
- Role role,
- const ConnectionOptions &connection_opts,
- const ConnectionPoolOptions &pool_opts = {}) :
- _pool(SimpleSentinel(sentinel, master_name, role), pool_opts, connection_opts) {}
- Redis(const Redis &) = delete;
- Redis& operator=(const Redis &) = delete;
- Redis(Redis &&) = default;
- Redis& operator=(Redis &&) = default;
- Pipeline pipeline();
- Transaction transaction(bool piped = false);
- Subscriber subscriber();
- template <typename Cmd, typename ...Args>
- auto command(Cmd cmd, Args &&...args)
- -> typename std::enable_if<!std::is_convertible<Cmd, StringView>::value, ReplyUPtr>::type;
- template <typename ...Args>
- auto command(const StringView &cmd_name, Args &&...args)
- -> typename std::enable_if<!IsIter<typename LastType<Args...>::type>::value,
- ReplyUPtr>::type;
- template <typename ...Args>
- auto command(const StringView &cmd_name, Args &&...args)
- -> typename std::enable_if<IsIter<typename LastType<Args...>::type>::value, void>::type;
- template <typename Result, typename ...Args>
- Result command(const StringView &cmd_name, Args &&...args);
- template <typename Input>
- auto command(Input first, Input last)
- -> typename std::enable_if<IsIter<Input>::value, ReplyUPtr>::type;
- template <typename Result, typename Input>
- auto command(Input first, Input last)
- -> typename std::enable_if<IsIter<Input>::value, Result>::type;
- template <typename Input, typename Output>
- auto command(Input first, Input last, Output output)
- -> typename std::enable_if<IsIter<Input>::value, void>::type;
- // CONNECTION commands.
- void auth(const StringView &password);
- std::string echo(const StringView &msg);
- std::string ping();
- std::string ping(const StringView &msg);
- // After sending QUIT, only the current connection will be close, while
- // other connections in the pool is still open. This is a strange behavior.
- // So we DO NOT support the QUIT command. If you want to quit connection to
- // server, just destroy the Redis object.
- //
- // void quit();
- // We get a connection from the pool, and send the SELECT command to switch
- // to a specified DB. However, when we try to send other commands to the
- // given DB, we might get a different connection from the pool, and these
- // commands, in fact, work on other DB. e.g.
- //
- // redis.select(1); // get a connection from the pool and switch to the 1th DB
- // redis.get("key"); // might get another connection from the pool,
- // // and try to get 'key' on the default DB
- //
- // Obviously, this is NOT what we expect. So we DO NOT support SELECT command.
- // In order to select a DB, we can specify the DB index with the ConnectionOptions.
- //
- // However, since Pipeline and Transaction always send multiple commands on a
- // single connection, these two classes have a *select* method.
- //
- // void select(long long idx);
- void swapdb(long long idx1, long long idx2);
- // SERVER commands.
- void bgrewriteaof();
- void bgsave();
- long long dbsize();
- void flushall(bool async = false);
- void flushdb(bool async = false);
- std::string info();
- std::string info(const StringView §ion);
- long long lastsave();
- void save();
- // KEY commands.
- long long del(const StringView &key);
- template <typename Input>
- long long del(Input first, Input last);
- template <typename T>
- long long del(std::initializer_list<T> il) {
- return del(il.begin(), il.end());
- }
- OptionalString dump(const StringView &key);
- long long exists(const StringView &key);
- template <typename Input>
- long long exists(Input first, Input last);
- template <typename T>
- long long exists(std::initializer_list<T> il) {
- return exists(il.begin(), il.end());
- }
- bool expire(const StringView &key, long long timeout);
- bool expire(const StringView &key, const std::chrono::seconds &timeout);
- bool expireat(const StringView &key, long long timestamp);
- bool expireat(const StringView &key,
- const std::chrono::time_point<std::chrono::system_clock,
- std::chrono::seconds> &tp);
- template <typename Output>
- void keys(const StringView &pattern, Output output);
- bool move(const StringView &key, long long db);
- bool persist(const StringView &key);
- bool pexpire(const StringView &key, long long timeout);
- bool pexpire(const StringView &key, const std::chrono::milliseconds &timeout);
- bool pexpireat(const StringView &key, long long timestamp);
- bool pexpireat(const StringView &key,
- const std::chrono::time_point<std::chrono::system_clock,
- std::chrono::milliseconds> &tp);
- long long pttl(const StringView &key);
- OptionalString randomkey();
- void rename(const StringView &key, const StringView &newkey);
- bool renamenx(const StringView &key, const StringView &newkey);
- void restore(const StringView &key,
- const StringView &val,
- long long ttl,
- bool replace = false);
- void restore(const StringView &key,
- const StringView &val,
- const std::chrono::milliseconds &ttl = std::chrono::milliseconds{0},
- bool replace = false);
- // TODO: sort
- template <typename Output>
- long long scan(long long cursor,
- const StringView &pattern,
- long long count,
- Output output);
- template <typename Output>
- long long scan(long long cursor,
- Output output);
- template <typename Output>
- long long scan(long long cursor,
- const StringView &pattern,
- Output output);
- template <typename Output>
- long long scan(long long cursor,
- long long count,
- Output output);
- long long touch(const StringView &key);
- template <typename Input>
- long long touch(Input first, Input last);
- template <typename T>
- long long touch(std::initializer_list<T> il) {
- return touch(il.begin(), il.end());
- }
- long long ttl(const StringView &key);
- std::string type(const StringView &key);
- long long unlink(const StringView &key);
- template <typename Input>
- long long unlink(Input first, Input last);
- template <typename T>
- long long unlink(std::initializer_list<T> il) {
- return unlink(il.begin(), il.end());
- }
- long long wait(long long numslaves, long long timeout);
- long long wait(long long numslaves, const std::chrono::milliseconds &timeout);
- // STRING commands.
- long long append(const StringView &key, const StringView &str);
- long long bitcount(const StringView &key, long long start = 0, long long end = -1);
- long long bitop(BitOp op, const StringView &destination, const StringView &key);
- template <typename Input>
- long long bitop(BitOp op, const StringView &destination, Input first, Input last);
- template <typename T>
- long long bitop(BitOp op, const StringView &destination, std::initializer_list<T> il) {
- return bitop(op, destination, il.begin(), il.end());
- }
- long long bitpos(const StringView &key,
- long long bit,
- long long start = 0,
- long long end = -1);
- long long decr(const StringView &key);
- long long decrby(const StringView &key, long long decrement);
- OptionalString get(const StringView &key);
- long long getbit(const StringView &key, long long offset);
- std::string getrange(const StringView &key, long long start, long long end);
- OptionalString getset(const StringView &key, const StringView &val);
- long long incr(const StringView &key);
- long long incrby(const StringView &key, long long increment);
- double incrbyfloat(const StringView &key, double increment);
- template <typename Input, typename Output>
- void mget(Input first, Input last, Output output);
- template <typename T, typename Output>
- void mget(std::initializer_list<T> il, Output output) {
- mget(il.begin(), il.end(), output);
- }
- template <typename Input>
- void mset(Input first, Input last);
- template <typename T>
- void mset(std::initializer_list<T> il) {
- mset(il.begin(), il.end());
- }
- template <typename Input>
- bool msetnx(Input first, Input last);
- template <typename T>
- bool msetnx(std::initializer_list<T> il) {
- return msetnx(il.begin(), il.end());
- }
- void psetex(const StringView &key,
- long long ttl,
- const StringView &val);
- void psetex(const StringView &key,
- const std::chrono::milliseconds &ttl,
- const StringView &val);
- bool set(const StringView &key,
- const StringView &val,
- const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0),
- UpdateType type = UpdateType::ALWAYS);
- void setex(const StringView &key,
- long long ttl,
- const StringView &val);
- void setex(const StringView &key,
- const std::chrono::seconds &ttl,
- const StringView &val);
- bool setnx(const StringView &key, const StringView &val);
- long long setrange(const StringView &key, long long offset, const StringView &val);
- long long strlen(const StringView &key);
- // LIST commands.
- OptionalStringPair blpop(const StringView &key, long long timeout);
- OptionalStringPair blpop(const StringView &key,
- const std::chrono::seconds &timeout = std::chrono::seconds{0});
- template <typename Input>
- OptionalStringPair blpop(Input first, Input last, long long timeout);
- template <typename T>
- OptionalStringPair blpop(std::initializer_list<T> il, long long timeout) {
- return blpop(il.begin(), il.end(), timeout);
- }
- template <typename Input>
- OptionalStringPair blpop(Input first,
- Input last,
- const std::chrono::seconds &timeout = std::chrono::seconds{0});
- template <typename T>
- OptionalStringPair blpop(std::initializer_list<T> il,
- const std::chrono::seconds &timeout = std::chrono::seconds{0}) {
- return blpop(il.begin(), il.end(), timeout);
- }
- OptionalStringPair brpop(const StringView &key, long long timeout);
- OptionalStringPair brpop(const StringView &key,
- const std::chrono::seconds &timeout = std::chrono::seconds{0});
- template <typename Input>
- OptionalStringPair brpop(Input first, Input last, long long timeout);
- template <typename T>
- OptionalStringPair brpop(std::initializer_list<T> il, long long timeout) {
- return brpop(il.begin(), il.end(), timeout);
- }
- template <typename Input>
- OptionalStringPair brpop(Input first,
- Input last,
- const std::chrono::seconds &timeout = std::chrono::seconds{0});
- template <typename T>
- OptionalStringPair brpop(std::initializer_list<T> il,
- const std::chrono::seconds &timeout = std::chrono::seconds{0}) {
- return brpop(il.begin(), il.end(), timeout);
- }
- OptionalString brpoplpush(const StringView &source,
- const StringView &destination,
- long long timeout);
- OptionalString brpoplpush(const StringView &source,
- const StringView &destination,
- const std::chrono::seconds &timeout = std::chrono::seconds{0});
- OptionalString lindex(const StringView &key, long long index);
- long long linsert(const StringView &key,
- InsertPosition position,
- const StringView &pivot,
- const StringView &val);
- long long llen(const StringView &key);
- OptionalString lpop(const StringView &key);
- long long lpush(const StringView &key, const StringView &val);
- template <typename Input>
- long long lpush(const StringView &key, Input first, Input last);
- template <typename T>
- long long lpush(const StringView &key, std::initializer_list<T> il) {
- return lpush(key, il.begin(), il.end());
- }
- long long lpushx(const StringView &key, const StringView &val);
- template <typename Output>
- void lrange(const StringView &key, long long start, long long stop, Output output);
- long long lrem(const StringView &key, long long count, const StringView &val);
- void lset(const StringView &key, long long index, const StringView &val);
- void ltrim(const StringView &key, long long start, long long stop);
- OptionalString rpop(const StringView &key);
- OptionalString rpoplpush(const StringView &source, const StringView &destination);
- long long rpush(const StringView &key, const StringView &val);
- template <typename Input>
- long long rpush(const StringView &key, Input first, Input last);
- template <typename T>
- long long rpush(const StringView &key, std::initializer_list<T> il) {
- return rpush(key, il.begin(), il.end());
- }
- long long rpushx(const StringView &key, const StringView &val);
- // HASH commands.
- long long hdel(const StringView &key, const StringView &field);
- template <typename Input>
- long long hdel(const StringView &key, Input first, Input last);
- template <typename T>
- long long hdel(const StringView &key, std::initializer_list<T> il) {
- return hdel(key, il.begin(), il.end());
- }
- bool hexists(const StringView &key, const StringView &field);
- OptionalString hget(const StringView &key, const StringView &field);
- template <typename Output>
- void hgetall(const StringView &key, Output output);
- long long hincrby(const StringView &key, const StringView &field, long long increment);
- double hincrbyfloat(const StringView &key, const StringView &field, double increment);
- template <typename Output>
- void hkeys(const StringView &key, Output output);
- long long hlen(const StringView &key);
- template <typename Input, typename Output>
- void hmget(const StringView &key, Input first, Input last, Output output);
- template <typename T, typename Output>
- void hmget(const StringView &key, std::initializer_list<T> il, Output output) {
- hmget(key, il.begin(), il.end(), output);
- }
- template <typename Input>
- void hmset(const StringView &key, Input first, Input last);
- template <typename T>
- void hmset(const StringView &key, std::initializer_list<T> il) {
- hmset(key, il.begin(), il.end());
- }
- template <typename Output>
- long long hscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- long long count,
- Output output);
- template <typename Output>
- long long hscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- Output output);
- template <typename Output>
- long long hscan(const StringView &key,
- long long cursor,
- long long count,
- Output output);
- template <typename Output>
- long long hscan(const StringView &key,
- long long cursor,
- Output output);
- bool hset(const StringView &key, const StringView &field, const StringView &val);
- bool hset(const StringView &key, const std::pair<StringView, StringView> &item);
- bool hsetnx(const StringView &key, const StringView &field, const StringView &val);
- bool hsetnx(const StringView &key, const std::pair<StringView, StringView> &item);
- long long hstrlen(const StringView &key, const StringView &field);
- template <typename Output>
- void hvals(const StringView &key, Output output);
- // SET commands.
- long long sadd(const StringView &key, const StringView &member);
- template <typename Input>
- long long sadd(const StringView &key, Input first, Input last);
- template <typename T>
- long long sadd(const StringView &key, std::initializer_list<T> il) {
- return sadd(key, il.begin(), il.end());
- }
- long long scard(const StringView &key);
- template <typename Input, typename Output>
- void sdiff(Input first, Input last, Output output);
- template <typename T, typename Output>
- void sdiff(std::initializer_list<T> il, Output output) {
- sdiff(il.begin(), il.end(), output);
- }
- long long sdiffstore(const StringView &destination, const StringView &key);
- template <typename Input>
- long long sdiffstore(const StringView &destination,
- Input first,
- Input last);
- template <typename T>
- long long sdiffstore(const StringView &destination,
- std::initializer_list<T> il) {
- return sdiffstore(destination, il.begin(), il.end());
- }
- template <typename Input, typename Output>
- void sinter(Input first, Input last, Output output);
- template <typename T, typename Output>
- void sinter(std::initializer_list<T> il, Output output) {
- sinter(il.begin(), il.end(), output);
- }
- long long sinterstore(const StringView &destination, const StringView &key);
- template <typename Input>
- long long sinterstore(const StringView &destination,
- Input first,
- Input last);
- template <typename T>
- long long sinterstore(const StringView &destination,
- std::initializer_list<T> il) {
- return sinterstore(destination, il.begin(), il.end());
- }
- bool sismember(const StringView &key, const StringView &member);
- template <typename Output>
- void smembers(const StringView &key, Output output);
- bool smove(const StringView &source,
- const StringView &destination,
- const StringView &member);
- OptionalString spop(const StringView &key);
- template <typename Output>
- void spop(const StringView &key, long long count, Output output);
- OptionalString srandmember(const StringView &key);
- template <typename Output>
- void srandmember(const StringView &key, long long count, Output output);
- long long srem(const StringView &key, const StringView &member);
- template <typename Input>
- long long srem(const StringView &key, Input first, Input last);
- template <typename T>
- long long srem(const StringView &key, std::initializer_list<T> il) {
- return srem(key, il.begin(), il.end());
- }
- template <typename Output>
- long long sscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- long long count,
- Output output);
- template <typename Output>
- long long sscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- Output output);
- template <typename Output>
- long long sscan(const StringView &key,
- long long cursor,
- long long count,
- Output output);
- template <typename Output>
- long long sscan(const StringView &key,
- long long cursor,
- Output output);
- template <typename Input, typename Output>
- void sunion(Input first, Input last, Output output);
- template <typename T, typename Output>
- void sunion(std::initializer_list<T> il, Output output) {
- sunion(il.begin(), il.end(), output);
- }
- long long sunionstore(const StringView &destination, const StringView &key);
- template <typename Input>
- long long sunionstore(const StringView &destination, Input first, Input last);
- template <typename T>
- long long sunionstore(const StringView &destination, std::initializer_list<T> il) {
- return sunionstore(destination, il.begin(), il.end());
- }
- // SORTED SET commands.
- auto bzpopmax(const StringView &key, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>>;
- auto bzpopmax(const StringView &key,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename Input>
- auto bzpopmax(Input first, Input last, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename Input>
- auto bzpopmax(Input first,
- Input last,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename T>
- auto bzpopmax(std::initializer_list<T> il, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>> {
- return bzpopmax(il.begin(), il.end(), timeout);
- }
- template <typename T>
- auto bzpopmax(std::initializer_list<T> il,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>> {
- return bzpopmax(il.begin(), il.end(), timeout);
- }
- auto bzpopmin(const StringView &key, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>>;
- auto bzpopmin(const StringView &key,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename Input>
- auto bzpopmin(Input first, Input last, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename Input>
- auto bzpopmin(Input first,
- Input last,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>>;
- template <typename T>
- auto bzpopmin(std::initializer_list<T> il, long long timeout)
- -> Optional<std::tuple<std::string, std::string, double>> {
- return bzpopmin(il.begin(), il.end(), timeout);
- }
- template <typename T>
- auto bzpopmin(std::initializer_list<T> il,
- const std::chrono::seconds &timeout = std::chrono::seconds{0})
- -> Optional<std::tuple<std::string, std::string, double>> {
- return bzpopmin(il.begin(), il.end(), timeout);
- }
- // We don't support the INCR option, since you can always use ZINCRBY instead.
- long long zadd(const StringView &key,
- const StringView &member,
- double score,
- UpdateType type = UpdateType::ALWAYS,
- bool changed = false);
- template <typename Input>
- long long zadd(const StringView &key,
- Input first,
- Input last,
- UpdateType type = UpdateType::ALWAYS,
- bool changed = false);
- template <typename T>
- long long zadd(const StringView &key,
- std::initializer_list<T> il,
- UpdateType type = UpdateType::ALWAYS,
- bool changed = false) {
- return zadd(key, il.begin(), il.end(), type, changed);
- }
- long long zcard(const StringView &key);
- template <typename Interval>
- long long zcount(const StringView &key, const Interval &interval);
- double zincrby(const StringView &key, double increment, const StringView &member);
- // There's no aggregation type parameter for single key overload, since these 3 types
- // have the same effect.
- long long zinterstore(const StringView &destination, const StringView &key, double weight);
- // If *Input* is an iterator of a container of string,
- // we use the default weight, i.e. 1, and send
- // *ZINTERSTORE destination numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]* command.
- // If *Input* is an iterator of a container of pair<string, double>, i.e. key-weight pair,
- // we send the command with the given weights:
- // *ZINTERSTORE destination numkeys key [key ...]
- // [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]*
- //
- // The following code use the default weight:
- //
- // vector<string> keys = {"k1", "k2", "k3"};
- // redis.zinterstore(destination, keys.begin(), keys.end());
- //
- // On the other hand, the following code use the given weights:
- //
- // vector<pair<string, double>> keys_with_weights = {{"k1", 1}, {"k2", 2}, {"k3", 3}};
- // redis.zinterstore(destination, keys_with_weights.begin(), keys_with_weights.end());
- //
- // NOTE: `keys_with_weights` can also be of type `unordered_map<string, double>`.
- // However, it will be slower than vector<pair<string, double>>, since we use
- // `distance(first, last)` to calculate the *numkeys* parameter.
- //
- // This also applies to *ZUNIONSTORE* command.
- template <typename Input>
- long long zinterstore(const StringView &destination,
- Input first,
- Input last,
- Aggregation type = Aggregation::SUM);
- template <typename T>
- long long zinterstore(const StringView &destination,
- std::initializer_list<T> il,
- Aggregation type = Aggregation::SUM) {
- return zinterstore(destination, il.begin(), il.end(), type);
- }
- template <typename Interval>
- long long zlexcount(const StringView &key, const Interval &interval);
- Optional<std::pair<std::string, double>> zpopmax(const StringView &key);
- template <typename Output>
- void zpopmax(const StringView &key, long long count, Output output);
- Optional<std::pair<std::string, double>> zpopmin(const StringView &key);
- template <typename Output>
- void zpopmin(const StringView &key, long long count, Output output);
- // If *output* is an iterator of a container of string,
- // we send *ZRANGE key start stop* command.
- // If it's an iterator of a container of pair<string, double>,
- // we send *ZRANGE key start stop WITHSCORES* command.
- //
- // The following code sends *ZRANGE* without the *WITHSCORES* option:
- //
- // vector<string> result;
- // redis.zrange("key", 0, -1, back_inserter(result));
- //
- // On the other hand, the following code sends command with *WITHSCORES* option:
- //
- // unordered_map<string, double> with_score;
- // redis.zrange("key", 0, -1, inserter(with_score, with_score.end()));
- //
- // This also applies to other commands with the *WITHSCORES* option,
- // e.g. *ZRANGEBYSCORE*, *ZREVRANGE*, *ZREVRANGEBYSCORE*.
- template <typename Output>
- void zrange(const StringView &key, long long start, long long stop, Output output);
- template <typename Interval, typename Output>
- void zrangebylex(const StringView &key, const Interval &interval, Output output);
- template <typename Interval, typename Output>
- void zrangebylex(const StringView &key,
- const Interval &interval,
- const LimitOptions &opts,
- Output output);
- // See *zrange* comment on how to send command with *WITHSCORES* option.
- template <typename Interval, typename Output>
- void zrangebyscore(const StringView &key, const Interval &interval, Output output);
- // See *zrange* comment on how to send command with *WITHSCORES* option.
- template <typename Interval, typename Output>
- void zrangebyscore(const StringView &key,
- const Interval &interval,
- const LimitOptions &opts,
- Output output);
- OptionalLongLong zrank(const StringView &key, const StringView &member);
- long long zrem(const StringView &key, const StringView &member);
- template <typename Input>
- long long zrem(const StringView &key, Input first, Input last);
- template <typename T>
- long long zrem(const StringView &key, std::initializer_list<T> il) {
- return zrem(key, il.begin(), il.end());
- }
- template <typename Interval>
- long long zremrangebylex(const StringView &key, const Interval &interval);
- long long zremrangebyrank(const StringView &key, long long start, long long stop);
- template <typename Interval>
- long long zremrangebyscore(const StringView &key, const Interval &interval);
- // See *zrange* comment on how to send command with *WITHSCORES* option.
- template <typename Output>
- void zrevrange(const StringView &key, long long start, long long stop, Output output);
- template <typename Interval, typename Output>
- void zrevrangebylex(const StringView &key, const Interval &interval, Output output);
- template <typename Interval, typename Output>
- void zrevrangebylex(const StringView &key,
- const Interval &interval,
- const LimitOptions &opts,
- Output output);
- // See *zrange* comment on how to send command with *WITHSCORES* option.
- template <typename Interval, typename Output>
- void zrevrangebyscore(const StringView &key, const Interval &interval, Output output);
- // See *zrange* comment on how to send command with *WITHSCORES* option.
- template <typename Interval, typename Output>
- void zrevrangebyscore(const StringView &key,
- const Interval &interval,
- const LimitOptions &opts,
- Output output);
- OptionalLongLong zrevrank(const StringView &key, const StringView &member);
- template <typename Output>
- long long zscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- long long count,
- Output output);
- template <typename Output>
- long long zscan(const StringView &key,
- long long cursor,
- const StringView &pattern,
- Output output);
- template <typename Output>
- long long zscan(const StringView &key,
- long long cursor,
- long long count,
- Output output);
- template <typename Output>
- long long zscan(const StringView &key,
- long long cursor,
- Output output);
- OptionalDouble zscore(const StringView &key, const StringView &member);
- // There's no aggregation type parameter for single key overload, since these 3 types
- // have the same effect.
- long long zunionstore(const StringView &destination, const StringView &key, double weight);
- // See *zinterstore* comment for how to use this method.
- template <typename Input>
- long long zunionstore(const StringView &destination,
- Input first,
- Input last,
- Aggregation type = Aggregation::SUM);
- template <typename T>
- long long zunionstore(const StringView &destination,
- std::initializer_list<T> il,
- Aggregation type = Aggregation::SUM) {
- return zunionstore(destination, il.begin(), il.end(), type);
- }
- // HYPERLOGLOG commands.
- bool pfadd(const StringView &key, const StringView &element);
- template <typename Input>
- bool pfadd(const StringView &key, Input first, Input last);
- template <typename T>
- bool pfadd(const StringView &key, std::initializer_list<T> il) {
- return pfadd(key, il.begin(), il.end());
- }
- long long pfcount(const StringView &key);
- template <typename Input>
- long long pfcount(Input first, Input last);
- template <typename T>
- long long pfcount(std::initializer_list<T> il) {
- return pfcount(il.begin(), il.end());
- }
- void pfmerge(const StringView &destination, const StringView &key);
- template <typename Input>
- void pfmerge(const StringView &destination, Input first, Input last);
- template <typename T>
- void pfmerge(const StringView &destination, std::initializer_list<T> il) {
- pfmerge(destination, il.begin(), il.end());
- }
- // GEO commands.
- long long geoadd(const StringView &key,
- const std::tuple<StringView, double, double> &member);
- template <typename Input>
- long long geoadd(const StringView &key,
- Input first,
- Input last);
- template <typename T>
- long long geoadd(const StringView &key,
- std::initializer_list<T> il) {
- return geoadd(key, il.begin(), il.end());
- }
- OptionalDouble geodist(const StringView &key,
- const StringView &member1,
- const StringView &member2,
- GeoUnit unit = GeoUnit::M);
- template <typename Input, typename Output>
- void geohash(const StringView &key, Input first, Input last, Output output);
- template <typename T, typename Output>
- void geohash(const StringView &key, std::initializer_list<T> il, Output output) {
- geohash(key, il.begin(), il.end(), output);
- }
- template <typename Input, typename Output>
- void geopos(const StringView &key, Input first, Input last, Output output);
- template <typename T, typename Output>
- void geopos(const StringView &key, std::initializer_list<T> il, Output output) {
- geopos(key, il.begin(), il.end(), output);
- }
- // TODO:
- // 1. since we have different overloads for georadius and georadius-store,
- // we might use the GEORADIUS_RO command in the future.
- // 2. there're too many parameters for this method, we might refactor it.
- OptionalLongLong georadius(const StringView &key,
- const std::pair<double, double> &loc,
- double radius,
- GeoUnit unit,
- const StringView &destination,
- bool store_dist,
- long long count);
- // If *output* is an iterator of a container of string, we send *GEORADIUS* command
- // without any options and only get the members in the specified geo range.
- // If *output* is an iterator of a container of a tuple, the type of the tuple decides
- // options we send with the *GEORADIUS* command. If the tuple has an element of type
- // double, we send the *WITHDIST* option. If it has an element of type string, we send
- // the *WITHHASH* option. If it has an element of type pair<double, double>, we send
- // the *WITHCOORD* option. For example:
- //
- // The following code only gets the members in range, i.e. without any option.
- //
- // vector<string> members;
- // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
- // back_inserter(members))
- //
- // The following code sends the command with *WITHDIST* option.
- //
- // vector<tuple<string, double>> with_dist;
- // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
- // back_inserter(with_dist))
- //
- // The following code sends the command with *WITHDIST* and *WITHHASH* options.
- //
- // vector<tuple<string, double, string>> with_dist_hash;
- // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
- // back_inserter(with_dist_hash))
- //
- // The following code sends the command with *WITHDIST*, *WITHCOORD* and *WITHHASH* options.
- //
- // vector<tuple<string, double, pair<double, double>, string>> with_dist_coord_hash;
- // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
- // back_inserter(with_dist_coord_hash))
- //
- // This also applies to *GEORADIUSBYMEMBER*.
- template <typename Output>
- void georadius(const StringView &key,
- const std::pair<double, double> &loc,
- double radius,
- GeoUnit unit,
- long long count,
- bool asc,
- Output output);
- OptionalLongLong georadiusbymember(const StringView &key,
- const StringView &member,
- double radius,
- GeoUnit unit,
- const StringView &destination,
- bool store_dist,
- long long count);
- // See comments on *GEORADIUS*.
- template <typename Output>
- void georadiusbymember(const StringView &key,
- const StringView &member,
- double radius,
- GeoUnit unit,
- long long count,
- bool asc,
- Output output);
- // SCRIPTING commands.
- template <typename Result>
- Result eval(const StringView &script,
- std::initializer_list<StringView> keys,
- std::initializer_list<StringView> args);
- template <typename Output>
- void eval(const StringView &script,
- std::initializer_list<StringView> keys,
- std::initializer_list<StringView> args,
- Output output);
- template <typename Result>
- Result evalsha(const StringView &script,
- std::initializer_list<StringView> keys,
- std::initializer_list<StringView> args);
- template <typename Output>
- void evalsha(const StringView &script,
- std::initializer_list<StringView> keys,
- std::initializer_list<StringView> args,
- Output output);
- template <typename Input, typename Output>
- void script_exists(Input first, Input last, Output output);
- template <typename T, typename Output>
- void script_exists(std::initializer_list<T> il, Output output) {
- script_exists(il.begin(), il.end(), output);
- }
- void script_flush();
- void script_kill();
- std::string script_load(const StringView &script);
- // PUBSUB commands.
- long long publish(const StringView &channel, const StringView &message);
- // Transaction commands.
- void watch(const StringView &key);
- template <typename Input>
- void watch(Input first, Input last);
- template <typename T>
- void watch(std::initializer_list<T> il) {
- watch(il.begin(), il.end());
- }
- // Stream commands.
- long long xack(const StringView &key, const StringView &group, const StringView &id);
- template <typename Input>
- long long xack(const StringView &key, const StringView &group, Input first, Input last);
- template <typename T>
- long long xack(const StringView &key, const StringView &group, std::initializer_list<T> il) {
- return xack(key, group, il.begin(), il.end());
- }
- template <typename Input>
- std::string xadd(const StringView &key, const StringView &id, Input first, Input last);
- template <typename T>
- std::string xadd(const StringView &key, const StringView &id, std::initializer_list<T> il) {
- return xadd(key, id, il.begin(), il.end());
- }
- template <typename Input>
- std::string xadd(const StringView &key,
- const StringView &id,
- Input first,
- Input last,
- long long count,
- bool approx = true);
- template <typename T>
- std::string xadd(const StringView &key,
- const StringView &id,
- std::initializer_list<T> il,
- long long count,
- bool approx = true) {
- return xadd(key, id, il.begin(), il.end(), count, approx);
- }
- template <typename Output>
- void xclaim(const StringView &key,
- const StringView &group,
- const StringView &consumer,
- const std::chrono::milliseconds &min_idle_time,
- const StringView &id,
- Output output);
- template <typename Input, typename Output>
- void xclaim(const StringView &key,
- const StringView &group,
- const StringView &consumer,
- const std::chrono::milliseconds &min_idle_time,
- Input first,
- Input last,
- Output output);
- template <typename T, typename Output>
- void xclaim(const StringView &key,
- const StringView &group,
- const StringView &consumer,
- const std::chrono::milliseconds &min_idle_time,
- std::initializer_list<T> il,
- Output output) {
- xclaim(key, group, consumer, min_idle_time, il.begin(), il.end(), output);
- }
- long long xdel(const StringView &key, const StringView &id);
- template <typename Input>
- long long xdel(const StringView &key, Input first, Input last);
- template <typename T>
- long long xdel(const StringView &key, std::initializer_list<T> il) {
- return xdel(key, il.begin(), il.end());
- }
- void xgroup_create(const StringView &key,
- const StringView &group,
- const StringView &id,
- bool mkstream = false);
- void xgroup_setid(const StringView &key, const StringView &group, const StringView &id);
- long long xgroup_destroy(const StringView &key, const StringView &group);
- long long xgroup_delconsumer(const StringView &key,
- const StringView &group,
- const StringView &consumer);
- long long xlen(const StringView &key);
- template <typename Output>
- auto xpending(const StringView &key, const StringView &group, Output output)
- -> std::tuple<long long, OptionalString, OptionalString>;
- template <typename Output>
- void xpending(const StringView &key,
- const StringView &group,
- const StringView &start,
- const StringView &end,
- long long count,
- Output output);
- template <typename Output>
- void xpending(const StringView &key,
- const StringView &group,
- const StringView &start,
- const StringView &end,
- long long count,
- const StringView &consumer,
- Output output);
- template <typename Output>
- void xrange(const StringView &key,
- const StringView &start,
- const StringView &end,
- Output output);
- template <typename Output>
- void xrange(const StringView &key,
- const StringView &start,
- const StringView &end,
- long long count,
- Output output);
- template <typename Output>
- void xread(const StringView &key,
- const StringView &id,
- long long count,
- Output output);
- template <typename Output>
- void xread(const StringView &key,
- const StringView &id,
- Output output) {
- xread(key, id, 0, output);
- }
- template <typename Input, typename Output>
- auto xread(Input first, Input last, long long count, Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
- template <typename Input, typename Output>
- auto xread(Input first, Input last, Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xread(first ,last, 0, output);
- }
- template <typename Output>
- void xread(const StringView &key,
- const StringView &id,
- const std::chrono::milliseconds &timeout,
- long long count,
- Output output);
- template <typename Output>
- void xread(const StringView &key,
- const StringView &id,
- const std::chrono::milliseconds &timeout,
- Output output) {
- xread(key, id, timeout, 0, output);
- }
- template <typename Input, typename Output>
- auto xread(Input first,
- Input last,
- const std::chrono::milliseconds &timeout,
- long long count,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
- template <typename Input, typename Output>
- auto xread(Input first,
- Input last,
- const std::chrono::milliseconds &timeout,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xread(first, last, timeout, 0, output);
- }
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- long long count,
- bool noack,
- Output output);
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- long long count,
- Output output) {
- xreadgroup(group, consumer, key, id, count, false, output);
- }
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- Output output) {
- xreadgroup(group, consumer, key, id, 0, false, output);
- }
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- long long count,
- bool noack,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- long long count,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xreadgroup(group, consumer, first ,last, count, false, output);
- }
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xreadgroup(group, consumer, first ,last, 0, false, output);
- }
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- const std::chrono::milliseconds &timeout,
- long long count,
- bool noack,
- Output output);
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- const std::chrono::milliseconds &timeout,
- long long count,
- Output output) {
- xreadgroup(group, consumer, key, id, timeout, count, false, output);
- }
- template <typename Output>
- void xreadgroup(const StringView &group,
- const StringView &consumer,
- const StringView &key,
- const StringView &id,
- const std::chrono::milliseconds &timeout,
- Output output) {
- xreadgroup(group, consumer, key, id, timeout, 0, false, output);
- }
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- const std::chrono::milliseconds &timeout,
- long long count,
- bool noack,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- const std::chrono::milliseconds &timeout,
- long long count,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xreadgroup(group, consumer, first, last, timeout, count, false, output);
- }
- template <typename Input, typename Output>
- auto xreadgroup(const StringView &group,
- const StringView &consumer,
- Input first,
- Input last,
- const std::chrono::milliseconds &timeout,
- Output output)
- -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
- xreadgroup(group, consumer, first, last, timeout, 0, false, output);
- }
- template <typename Output>
- void xrevrange(const StringView &key,
- const StringView &end,
- const StringView &start,
- Output output);
- template <typename Output>
- void xrevrange(const StringView &key,
- const StringView &end,
- const StringView &start,
- long long count,
- Output output);
- long long xtrim(const StringView &key, long long count, bool approx = true);
- private:
- class ConnectionPoolGuard {
- public:
- ConnectionPoolGuard(ConnectionPool &pool,
- Connection &connection) : _pool(pool), _connection(connection) {}
- ~ConnectionPoolGuard() {
- _pool.release(std::move(_connection));
- }
- private:
- ConnectionPool &_pool;
- Connection &_connection;
- };
- template <typename Impl>
- friend class QueuedRedis;
- friend class RedisCluster;
- // For internal use.
- explicit Redis(const ConnectionSPtr &connection);
- template <std::size_t ...Is, typename ...Args>
- ReplyUPtr _command(const StringView &cmd_name, const IndexSequence<Is...> &, Args &&...args) {
- return command(cmd_name, NthValue<Is>(std::forward<Args>(args)...)...);
- }
- template <typename Cmd, typename ...Args>
- ReplyUPtr _command(Connection &connection, Cmd cmd, Args &&...args);
- template <typename Cmd, typename ...Args>
- ReplyUPtr _score_command(std::true_type, Cmd cmd, Args &&... args);
- template <typename Cmd, typename ...Args>
- ReplyUPtr _score_command(std::false_type, Cmd cmd, Args &&... args);
- template <typename Output, typename Cmd, typename ...Args>
- ReplyUPtr _score_command(Cmd cmd, Args &&... args);
- // Pool Mode.
- // Public constructors create a *Redis* instance with a pool.
- // In this case, *_connection* is a null pointer, and is never used.
- ConnectionPool _pool;
- // Single Connection Mode.
- // Private constructor creats a *Redis* instance with a single connection.
- // This is used when we create Transaction, Pipeline and Subscriber.
- // In this case, *_pool* is empty, and is never used.
- ConnectionSPtr _connection;
- };
- }
- }
- #include "redis.hpp"
- #endif // end SEWENEW_REDISPLUSPLUS_REDIS_H
|