redis.h 164 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631
  1. /**************************************************************************
  2. Copyright (c) 2017 sewenew
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. *************************************************************************/
  13. #ifndef SEWENEW_REDISPLUSPLUS_REDIS_H
  14. #define SEWENEW_REDISPLUSPLUS_REDIS_H
  15. #include <string>
  16. #include <chrono>
  17. #include <memory>
  18. #include <initializer_list>
  19. #include <tuple>
  20. #include "connection_pool.h"
  21. #include "reply.h"
  22. #include "command_options.h"
  23. #include "utils.h"
  24. #include "subscriber.h"
  25. #include "pipeline.h"
  26. #include "transaction.h"
  27. #include "sentinel.h"
  28. namespace sw {
  29. namespace redis {
  30. template <typename Impl>
  31. class QueuedRedis;
  32. using Transaction = QueuedRedis<TransactionImpl>;
  33. using Pipeline = QueuedRedis<PipelineImpl>;
  34. class Redis {
  35. public:
  36. /// @brief Construct `Redis` instance with connection options and connection pool options.
  37. /// @param connection_opts Connection options.
  38. /// @param pool_opts Connection pool options.
  39. /// @see `ConnectionOptions`
  40. /// @see `ConnectionPoolOptions`
  41. /// @see https://github.com/sewenew/redis-plus-plus#connection
  42. explicit Redis(const ConnectionOptions &connection_opts,
  43. const ConnectionPoolOptions &pool_opts = {}) :
  44. _pool(std::make_shared<ConnectionPool>(pool_opts, connection_opts)) {}
  45. /// @brief Construct `Redis` instance with URI.
  46. /// @param uri URI, e.g. 'tcp://127.0.0.1', 'tcp://127.0.0.1:6379', or 'unix://path/to/socket'.
  47. /// Full URI scheme: 'tcp://[[username:]password@]host[:port][/db]' or
  48. /// unix://[[username:]password@]path-to-unix-domain-socket[/db]
  49. /// @see https://github.com/sewenew/redis-plus-plus/issues/37
  50. /// @see https://github.com/sewenew/redis-plus-plus#connection
  51. explicit Redis(const std::string &uri);
  52. /// @brief Construct `Redis` instance with Redis sentinel, i.e. get node info from sentinel.
  53. /// @param sentinel `Sentinel` instance.
  54. /// @param master_name Name of master node.
  55. /// @param role Connect to master node or slave node.
  56. /// - Role::MASTER: Connect to master node.
  57. /// - Role::SLAVE: Connect to slave node.
  58. /// @param connection_opts Connection options.
  59. /// @param pool_opts Connection pool options.
  60. /// @see `Sentinel`
  61. /// @see `Role`
  62. /// @see https://github.com/sewenew/redis-plus-plus#redis-sentinel
  63. Redis(const std::shared_ptr<Sentinel> &sentinel,
  64. const std::string &master_name,
  65. Role role,
  66. const ConnectionOptions &connection_opts,
  67. const ConnectionPoolOptions &pool_opts = {}) :
  68. _pool(std::make_shared<ConnectionPool>(SimpleSentinel(sentinel, master_name, role),
  69. pool_opts,
  70. connection_opts)) {}
  71. /// @brief `Redis` is not copyable.
  72. Redis(const Redis &) = delete;
  73. /// @brief `Redis` is not copyable.
  74. Redis& operator=(const Redis &) = delete;
  75. /// @brief `Redis` is movable.
  76. Redis(Redis &&) = default;
  77. /// @brief `Redis` is movable.
  78. Redis& operator=(Redis &&) = default;
  79. /// @brief Create a pipeline.
  80. /// @param new_connection Whether creating a `Pipeline` object in a new connection.
  81. /// @return The created pipeline.
  82. /// @note Instead of picking a connection from the underlying connection pool,
  83. /// this method will create a new connection to Redis. So it's not a cheap operation,
  84. /// and you'd better reuse the returned object as much as possible.
  85. /// @see https://github.com/sewenew/redis-plus-plus#pipeline
  86. Pipeline pipeline(bool new_connection = true);
  87. /// @brief Create a transaction.
  88. /// @param piped Whether commands in a transaction should be sent in a pipeline to reduce RTT.
  89. /// @param new_connection Whether creating a `Pipeline` object in a new connection.
  90. /// @return The created transaction.
  91. /// @note Instead of picking a connection from the underlying connection pool,
  92. /// this method will create a new connection to Redis. So it's not a cheap operation,
  93. /// and you'd better reuse the returned object as much as possible.
  94. /// @see https://github.com/sewenew/redis-plus-plus#transaction
  95. Transaction transaction(bool piped = false, bool new_connection = true);
  96. /// @brief Create a subscriber.
  97. /// @return The created subscriber.
  98. /// @note Instead of picking a connection from the underlying connection pool,
  99. /// this method will create a new connection to Redis. So it's not a cheap operation,
  100. /// and you'd better reuse the returned object as much as possible.
  101. /// @see https://github.com/sewenew/redis-plus-plus#publishsubscribe
  102. Subscriber subscriber();
  103. template <typename Cmd, typename ...Args>
  104. auto command(Cmd cmd, Args &&...args)
  105. -> typename std::enable_if<!std::is_convertible<Cmd, StringView>::value, ReplyUPtr>::type;
  106. template <typename ...Args>
  107. auto command(const StringView &cmd_name, Args &&...args)
  108. -> typename std::enable_if<!IsIter<typename LastType<Args...>::type>::value,
  109. ReplyUPtr>::type;
  110. template <typename ...Args>
  111. auto command(const StringView &cmd_name, Args &&...args)
  112. -> typename std::enable_if<IsIter<typename LastType<Args...>::type>::value, void>::type;
  113. template <typename Result, typename ...Args>
  114. Result command(const StringView &cmd_name, Args &&...args);
  115. template <typename Input>
  116. auto command(Input first, Input last)
  117. -> typename std::enable_if<IsIter<Input>::value, ReplyUPtr>::type;
  118. template <typename Result, typename Input>
  119. auto command(Input first, Input last)
  120. -> typename std::enable_if<IsIter<Input>::value, Result>::type;
  121. template <typename Input, typename Output>
  122. auto command(Input first, Input last, Output output)
  123. -> typename std::enable_if<IsIter<Input>::value, void>::type;
  124. // CONNECTION commands.
  125. /// @brief Send password to Redis.
  126. /// @param password Password.
  127. /// @note Normally, you should not call this method.
  128. /// Instead, you should set password with `ConnectionOptions` or URI.
  129. /// @see https://redis.io/commands/auth
  130. void auth(const StringView &password);
  131. /// @brief Send user and password to Redis.
  132. /// @param user User name.
  133. /// @param password Password.
  134. /// @note Normally, you should not call this method.
  135. /// Instead, you should set password with `ConnectionOptions` or URI.
  136. /// Also this overload only works with Redis 6.0 or later.
  137. /// @see https://redis.io/commands/auth
  138. void auth(const StringView &user, const StringView &password);
  139. /// @brief Ask Redis to return the given message.
  140. /// @param msg Message to be sent.
  141. /// @return Return the given message.
  142. /// @see https://redis.io/commands/echo
  143. std::string echo(const StringView &msg);
  144. /// @brief Test if the connection is alive.
  145. /// @return Always return *PONG*.
  146. /// @see https://redis.io/commands/ping
  147. std::string ping();
  148. /// @brief Test if the connection is alive.
  149. /// @param msg Message sent to Redis.
  150. /// @return Return the given message.
  151. /// @see https://redis.io/commands/ping
  152. std::string ping(const StringView &msg);
  153. // After sending QUIT, only the current connection will be close, while
  154. // other connections in the pool is still open. This is a strange behavior.
  155. // So we DO NOT support the QUIT command. If you want to quit connection to
  156. // server, just destroy the Redis object.
  157. //
  158. // void quit();
  159. // We get a connection from the pool, and send the SELECT command to switch
  160. // to a specified DB. However, when we try to send other commands to the
  161. // given DB, we might get a different connection from the pool, and these
  162. // commands, in fact, work on other DB. e.g.
  163. //
  164. // redis.select(1); // get a connection from the pool and switch to the 1th DB
  165. // redis.get("key"); // might get another connection from the pool,
  166. // // and try to get 'key' on the default DB
  167. //
  168. // Obviously, this is NOT what we expect. So we DO NOT support SELECT command.
  169. // In order to select a DB, we can specify the DB index with the ConnectionOptions.
  170. //
  171. // However, since Pipeline and Transaction always send multiple commands on a
  172. // single connection, these two classes have a *select* method.
  173. //
  174. // void select(long long idx);
  175. /// @brief Swap two Redis databases.
  176. /// @param idx1 The index of the first database.
  177. /// @param idx2 The index of the second database.
  178. /// @see https://redis.io/commands/swapdb
  179. void swapdb(long long idx1, long long idx2);
  180. // SERVER commands.
  181. /// @brief Rewrite AOF in the background.
  182. /// @see https://redis.io/commands/bgrewriteaof
  183. void bgrewriteaof();
  184. /// @brief Save database in the background.
  185. /// @see https://redis.io/commands/bgsave
  186. void bgsave();
  187. /// @brief Get the size of the currently selected database.
  188. /// @return Number of keys in currently selected database.
  189. /// @see https://redis.io/commands/dbsize
  190. long long dbsize();
  191. /// @brief Remove keys of all databases.
  192. /// @param async Whether flushing databases asynchronously, i.e. without blocking the server.
  193. /// @see https://redis.io/commands/flushall
  194. void flushall(bool async = false);
  195. /// @brief Remove keys of current databases.
  196. /// @param async Whether flushing databases asynchronously, i.e. without blocking the server.
  197. /// @see https://redis.io/commands/flushdb
  198. void flushdb(bool async = false);
  199. /// @brief Get the info about the server.
  200. /// @return Server info.
  201. /// @see https://redis.io/commands/info
  202. std::string info();
  203. /// @brief Get the info about the server on the given section.
  204. /// @param section Section.
  205. /// @return Server info.
  206. /// @see https://redis.io/commands/info
  207. std::string info(const StringView &section);
  208. /// @brief Get the UNIX timestamp in seconds, at which the database was saved successfully.
  209. /// @return The last saving time.
  210. /// @see https://redis.io/commands/lastsave
  211. long long lastsave();
  212. /// @brief Save databases into RDB file **synchronously**, i.e. block the server during saving.
  213. /// @see https://redis.io/commands/save
  214. void save();
  215. // KEY commands.
  216. /// @brief Delete the given key.
  217. /// @param key Key.
  218. /// @return Number of keys removed.
  219. /// @retval 1 If the key exists, and has been removed.
  220. /// @retval 0 If the key does not exist.
  221. /// @see https://redis.io/commands/del
  222. long long del(const StringView &key);
  223. /// @brief Delete the given list of keys.
  224. /// @param first Iterator to the first key in the range.
  225. /// @param last Off-the-end iterator to the given range.
  226. /// @return Number of keys removed.
  227. /// @see https://redis.io/commands/del
  228. template <typename Input>
  229. long long del(Input first, Input last);
  230. /// @brief Delete the given list of keys.
  231. /// @param il Initializer list of keys to be deleted.
  232. /// @return Number of keys removed.
  233. /// @see https://redis.io/commands/del
  234. template <typename T>
  235. long long del(std::initializer_list<T> il) {
  236. return del(il.begin(), il.end());
  237. }
  238. /// @brief Get the serialized valued stored at key.
  239. /// @param key Key.
  240. /// @return The serialized value.
  241. /// @note If key does not exist, `dump` returns `OptionalString{}` (`std::nullopt`).
  242. /// @see https://redis.io/commands/dump
  243. OptionalString dump(const StringView &key);
  244. /// @brief Check if the given key exists.
  245. /// @param key Key.
  246. /// @return Whether the given key exists.
  247. /// @retval 1 If key exists.
  248. /// @retval 0 If key does not exist.
  249. /// @see https://redis.io/commands/exists
  250. long long exists(const StringView &key);
  251. /// @brief Check if the given keys exist.
  252. /// @param first Iterator to the first key.
  253. /// @param last Off-the-end iterator to the given range.
  254. /// @return Number of keys existing.
  255. /// @see https://redis.io/commands/exists
  256. template <typename Input>
  257. long long exists(Input first, Input last);
  258. /// @brief Check if the given keys exist.
  259. /// @param il Initializer list of keys to be checked.
  260. /// @return Number of keys existing.
  261. /// @see https://redis.io/commands/exists
  262. template <typename T>
  263. long long exists(std::initializer_list<T> il) {
  264. return exists(il.begin(), il.end());
  265. }
  266. /// @brief Set a timeout on key.
  267. /// @param key Key.
  268. /// @param timeout Timeout in seconds.
  269. /// @return Whether timeout has been set.
  270. /// @retval true If timeout has been set.
  271. /// @retval false If key does not exist.
  272. /// @see https://redis.io/commands/expire
  273. bool expire(const StringView &key, long long timeout);
  274. /// @brief Set a timeout on key.
  275. /// @param key Key.
  276. /// @param timeout Timeout in seconds.
  277. /// @return Whether timeout has been set.
  278. /// @retval true If timeout has been set.
  279. /// @retval false If key does not exist.
  280. /// @see https://redis.io/commands/expire
  281. bool expire(const StringView &key, const std::chrono::seconds &timeout);
  282. /// @brief Set a timeout on key, i.e. expire the key at a future time point.
  283. /// @param key Key.
  284. /// @param timestamp Time in seconds since UNIX epoch.
  285. /// @return Whether timeout has been set.
  286. /// @retval true If timeout has been set.
  287. /// @retval false If key does not exist.
  288. /// @see https://redis.io/commands/expireat
  289. bool expireat(const StringView &key, long long timestamp);
  290. /// @brief Set a timeout on key, i.e. expire the key at a future time point.
  291. /// @param key Key.
  292. /// @param timestamp Time in seconds since UNIX epoch.
  293. /// @return Whether timeout has been set.
  294. /// @retval true If timeout has been set.
  295. /// @retval false If key does not exist.
  296. /// @see https://redis.io/commands/expireat
  297. bool expireat(const StringView &key,
  298. const std::chrono::time_point<std::chrono::system_clock,
  299. std::chrono::seconds> &tp);
  300. /// @brief Get keys matching the given pattern.
  301. /// @param pattern Pattern.
  302. /// @param output Output iterator to the destination where the returned keys are stored.
  303. /// @note It's always a bad idea to call `keys`, since it might block Redis for a long time,
  304. /// especially when the data set is very big.
  305. /// @see `Redis::scan`
  306. /// @see https://redis.io/commands/keys
  307. template <typename Output>
  308. void keys(const StringView &pattern, Output output);
  309. /// @brief Move a key to the given database.
  310. /// @param key Key.
  311. /// @param db The destination database.
  312. /// @return Whether key has been moved.
  313. /// @retval true If key has been moved.
  314. /// @retval false If key was not moved.
  315. /// @see https://redis.io/commands/move
  316. bool move(const StringView &key, long long db);
  317. /// @brief Remove timeout on key.
  318. /// @param key Key.
  319. /// @return Whether timeout has been removed.
  320. /// @retval true If timeout has been removed.
  321. /// @retval false If key does not exist, or does not have an associated timeout.
  322. /// @see https://redis.io/commands/persist
  323. bool persist(const StringView &key);
  324. /// @brief Set a timeout on key.
  325. /// @param key Key.
  326. /// @param timeout Timeout in milliseconds.
  327. /// @return Whether timeout has been set.
  328. /// @retval true If timeout has been set.
  329. /// @retval false If key does not exist.
  330. /// @see https://redis.io/commands/pexpire
  331. bool pexpire(const StringView &key, long long timeout);
  332. /// @brief Set a timeout on key.
  333. /// @param key Key.
  334. /// @param timeout Timeout in milliseconds.
  335. /// @return Whether timeout has been set.
  336. /// @retval true If timeout has been set.
  337. /// @retval false If key does not exist.
  338. /// @see https://redis.io/commands/pexpire
  339. bool pexpire(const StringView &key, const std::chrono::milliseconds &timeout);
  340. /// @brief Set a timeout on key, i.e. expire the key at a future time point.
  341. /// @param key Key.
  342. /// @param timestamp Time in milliseconds since UNIX epoch.
  343. /// @return Whether timeout has been set.
  344. /// @retval true If timeout has been set.
  345. /// @retval false If key does not exist.
  346. /// @see https://redis.io/commands/pexpireat
  347. bool pexpireat(const StringView &key, long long timestamp);
  348. /// @brief Set a timeout on key, i.e. expire the key at a future time point.
  349. /// @param key Key.
  350. /// @param timestamp Time in milliseconds since UNIX epoch.
  351. /// @return Whether timeout has been set.
  352. /// @retval true If timeout has been set.
  353. /// @retval false If key does not exist.
  354. /// @see https://redis.io/commands/pexpireat
  355. bool pexpireat(const StringView &key,
  356. const std::chrono::time_point<std::chrono::system_clock,
  357. std::chrono::milliseconds> &tp);
  358. /// @brief Get the TTL of a key in milliseconds.
  359. /// @param key Key.
  360. /// @return TTL of the key in milliseconds.
  361. /// @see https://redis.io/commands/pttl
  362. long long pttl(const StringView &key);
  363. /// @brief Get a random key from current database.
  364. /// @return A random key.
  365. /// @note If the database is empty, `randomkey` returns `OptionalString{}` (`std::nullopt`).
  366. /// @see https://redis.io/commands/randomkey
  367. OptionalString randomkey();
  368. /// @brief Rename `key` to `newkey`.
  369. /// @param key Key to be renamed.
  370. /// @param newkey The new name of the key.
  371. /// @see https://redis.io/commands/rename
  372. void rename(const StringView &key, const StringView &newkey);
  373. /// @brief Rename `key` to `newkey` if `newkey` does not exist.
  374. /// @param key Key to be renamed.
  375. /// @param newkey The new name of the key.
  376. /// @return Whether key has been renamed.
  377. /// @retval true If key has been renamed.
  378. /// @retval false If newkey already exists.
  379. /// @see https://redis.io/commands/renamenx
  380. bool renamenx(const StringView &key, const StringView &newkey);
  381. /// @brief Create a key with the value obtained by `Redis::dump`.
  382. /// @param key Key.
  383. /// @param val Value obtained by `Redis::dump`.
  384. /// @param ttl Timeout of the created key in milliseconds. If `ttl` is 0, set no timeout.
  385. /// @param replace Whether to overwrite an existing key.
  386. /// If `replace` is `true` and key already exists, throw an exception.
  387. /// @see https://redis.io/commands/restore
  388. void restore(const StringView &key,
  389. const StringView &val,
  390. long long ttl,
  391. bool replace = false);
  392. /// @brief Create a key with the value obtained by `Redis::dump`.
  393. /// @param key Key.
  394. /// @param val Value obtained by `Redis::dump`.
  395. /// @param ttl Timeout of the created key in milliseconds. If `ttl` is 0, set no timeout.
  396. /// @param replace Whether to overwrite an existing key.
  397. /// If `replace` is `true` and key already exists, throw an exception.
  398. /// @see https://redis.io/commands/restore
  399. void restore(const StringView &key,
  400. const StringView &val,
  401. const std::chrono::milliseconds &ttl = std::chrono::milliseconds{0},
  402. bool replace = false);
  403. // TODO: sort
  404. /// @brief Scan keys of the database matching the given pattern.
  405. ///
  406. /// Example:
  407. /// @code{.cpp}
  408. /// auto cursor = 0LL;
  409. /// std::unordered_set<std::string> keys;
  410. /// while (true) {
  411. /// cursor = redis.scan(cursor, "pattern:*", 10, std::inserter(keys, keys.begin()));
  412. /// if (cursor == 0) {
  413. /// break;
  414. /// }
  415. /// }
  416. /// @endcode
  417. /// @param cursor Cursor.
  418. /// @param pattern Pattern of the keys to be scanned.
  419. /// @param count A hint for how many keys to be scanned.
  420. /// @param output Output iterator to the destination where the returned keys are stored.
  421. /// @return The cursor to be used for the next scan operation.
  422. /// @see https://redis.io/commands/scan
  423. /// TODO: support the TYPE option for Redis 6.0.
  424. template <typename Output>
  425. long long scan(long long cursor,
  426. const StringView &pattern,
  427. long long count,
  428. Output output);
  429. /// @brief Scan all keys of the database.
  430. /// @param cursor Cursor.
  431. /// @param output Output iterator to the destination where the returned keys are stored.
  432. /// @return The cursor to be used for the next scan operation.
  433. /// @see https://redis.io/commands/scan
  434. template <typename Output>
  435. long long scan(long long cursor,
  436. Output output);
  437. /// @brief Scan keys of the database matching the given pattern.
  438. /// @param cursor Cursor.
  439. /// @param pattern Pattern of the keys to be scanned.
  440. /// @param output Output iterator to the destination where the returned keys are stored.
  441. /// @return The cursor to be used for the next scan operation.
  442. /// @see https://redis.io/commands/scan
  443. template <typename Output>
  444. long long scan(long long cursor,
  445. const StringView &pattern,
  446. Output output);
  447. /// @brief Scan keys of the database matching the given pattern.
  448. /// @param cursor Cursor.
  449. /// @param count A hint for how many keys to be scanned.
  450. /// @param output Output iterator to the destination where the returned keys are stored.
  451. /// @return The cursor to be used for the next scan operation.
  452. /// @see https://redis.io/commands/scan
  453. template <typename Output>
  454. long long scan(long long cursor,
  455. long long count,
  456. Output output);
  457. /// @brief Update the last access time of the given key.
  458. /// @param key Key.
  459. /// @return Whether last access time of the key has been updated.
  460. /// @retval 1 If key exists, and last access time has been updated.
  461. /// @retval 0 If key does not exist.
  462. /// @see https://redis.io/commands/touch
  463. long long touch(const StringView &key);
  464. /// @brief Update the last access time of the given key.
  465. /// @param first Iterator to the first key to be touched.
  466. /// @param last Off-the-end iterator to the given range.
  467. /// @return Whether last access time of the key has been updated.
  468. /// @retval 1 If key exists, and last access time has been updated.
  469. /// @retval 0 If key does not exist.
  470. /// @see https://redis.io/commands/touch
  471. template <typename Input>
  472. long long touch(Input first, Input last);
  473. /// @brief Update the last access time of the given key.
  474. /// @param il Initializer list of keys to be touched.
  475. /// @return Whether last access time of the key has been updated.
  476. /// @retval 1 If key exists, and last access time has been updated.
  477. /// @retval 0 If key does not exist.
  478. /// @see https://redis.io/commands/touch
  479. template <typename T>
  480. long long touch(std::initializer_list<T> il) {
  481. return touch(il.begin(), il.end());
  482. }
  483. /// @brief Get the remaining Time-To-Live of a key.
  484. /// @param key Key.
  485. /// @return TTL in seconds.
  486. /// @retval TTL If the key has a timeout.
  487. /// @retval -1 If the key exists but does not have a timeout.
  488. /// @retval -2 If the key does not exist.
  489. /// @note In Redis 2.6 or older, `ttl` returns -1 if the key does not exist,
  490. /// or if the key exists but does not have a timeout.
  491. /// @see https://redis.io/commands/ttl
  492. long long ttl(const StringView &key);
  493. /// @brief Get the type of the value stored at key.
  494. /// @param key Key.
  495. /// @return The type of the value.
  496. /// @see https://redis.io/commands/type
  497. std::string type(const StringView &key);
  498. /// @brief Remove the given key asynchronously, i.e. without blocking Redis.
  499. /// @param key Key.
  500. /// @return Whether the key has been removed.
  501. /// @retval 1 If key exists, and has been removed.
  502. /// @retval 0 If key does not exist.
  503. /// @see https://redis.io/commands/unlink
  504. long long unlink(const StringView &key);
  505. /// @brief Remove the given keys asynchronously, i.e. without blocking Redis.
  506. /// @param first Iterator to the first key in the given range.
  507. /// @param last Off-the-end iterator to the given range.
  508. /// @return Number of keys that have been removed.
  509. /// @see https://redis.io/commands/unlink
  510. template <typename Input>
  511. long long unlink(Input first, Input last);
  512. /// @brief Remove the given keys asynchronously, i.e. without blocking Redis.
  513. /// @param il Initializer list of keys to be unlinked.
  514. /// @return Number of keys that have been removed.
  515. /// @see https://redis.io/commands/unlink
  516. template <typename T>
  517. long long unlink(std::initializer_list<T> il) {
  518. return unlink(il.begin(), il.end());
  519. }
  520. /// @brief Wait until previous write commands are successfully replicated to at
  521. /// least the specified number of replicas or the given timeout has been reached.
  522. /// @param numslaves Number of replicas.
  523. /// @param timeout Timeout in milliseconds. If timeout is 0ms, wait forever.
  524. /// @return Number of replicas that have been successfully replicated these write commands.
  525. /// @note The return value might be less than `numslaves`, because timeout has been reached.
  526. /// @see https://redis.io/commands/wait
  527. long long wait(long long numslaves, long long timeout);
  528. /// @brief Wait until previous write commands are successfully replicated to at
  529. /// least the specified number of replicas or the given timeout has been reached.
  530. /// @param numslaves Number of replicas.
  531. /// @param timeout Timeout in milliseconds. If timeout is 0ms, wait forever.
  532. /// @return Number of replicas that have been successfully replicated these write commands.
  533. /// @note The return value might be less than `numslaves`, because timeout has been reached.
  534. /// @see https://redis.io/commands/wait
  535. /// TODO: Support default parameter for `timeout` to wait forever.
  536. long long wait(long long numslaves, const std::chrono::milliseconds &timeout);
  537. // STRING commands.
  538. /// @brief Append the given string to the string stored at key.
  539. /// @param key Key.
  540. /// @param str String to be appended.
  541. /// @return The length of the string after the append operation.
  542. /// @see https://redis.io/commands/append
  543. long long append(const StringView &key, const StringView &str);
  544. /// @brief Get the number of bits that have been set for the given range of the string.
  545. /// @param key Key.
  546. /// @param start Start index (inclusive) of the range. 0 means the beginning of the string.
  547. /// @param end End index (inclusive) of the range. -1 means the end of the string.
  548. /// @return Number of bits that have been set.
  549. /// @note The index can be negative to index from the end of the string.
  550. /// @see https://redis.io/commands/bitcount
  551. long long bitcount(const StringView &key, long long start = 0, long long end = -1);
  552. /// @brief Do bit operation on the string stored at `key`, and save the result to `destination`.
  553. /// @param op Bit operations.
  554. /// @param destination The destination key where the result is saved.
  555. /// @param key The key where the string to be operated is stored.
  556. /// @return The length of the string saved at `destination`.
  557. /// @see https://redis.io/commands/bitop
  558. /// @see `BitOp`
  559. long long bitop(BitOp op, const StringView &destination, const StringView &key);
  560. /// @brief Do bit operations on the strings stored at the given keys,
  561. /// and save the result to `destination`.
  562. /// @param op Bit operations.
  563. /// @param destination The destination key where the result is saved.
  564. /// @param first Iterator to the first key where the string to be operated is stored.
  565. /// @param last Off-the-end iterator to the given range of keys.
  566. /// @return The length of the string saved at `destination`.
  567. /// @see https://redis.io/commands/bitop
  568. /// @see `BitOp`
  569. template <typename Input>
  570. long long bitop(BitOp op, const StringView &destination, Input first, Input last);
  571. /// @brief Do bit operations on the strings stored at the given keys,
  572. /// and save the result to `destination`.
  573. /// @param op Bit operations.
  574. /// @param destination The destination key where the result is saved.
  575. /// @param il Initializer list of keys where the strings are operated.
  576. /// @return The length of the string saved at `destination`.
  577. /// @see https://redis.io/commands/bitop
  578. /// @see `BitOp`
  579. template <typename T>
  580. long long bitop(BitOp op, const StringView &destination, std::initializer_list<T> il) {
  581. return bitop(op, destination, il.begin(), il.end());
  582. }
  583. /// @brief Get the position of the first bit set to 0 or 1 in the given range of the string.
  584. /// @param key Key.
  585. /// @param bit 0 or 1.
  586. /// @param start Start index (inclusive) of the range. 0 means the beginning of the string.
  587. /// @param end End index (inclusive) of the range. -1 means the end of the string.
  588. /// @return The position of the first bit set to 0 or 1.
  589. /// @see https://redis.io/commands/bitpos
  590. long long bitpos(const StringView &key,
  591. long long bit,
  592. long long start = 0,
  593. long long end = -1);
  594. /// @brief Decrement the integer stored at key by 1.
  595. /// @param key Key.
  596. /// @return The value after the decrement.
  597. /// @see https://redis.io/commands/decr
  598. long long decr(const StringView &key);
  599. /// @brief Decrement the integer stored at key by `decrement`.
  600. /// @param key Key.
  601. /// @param decrement Decrement.
  602. /// @return The value after the decrement.
  603. /// @see https://redis.io/commands/decrby
  604. long long decrby(const StringView &key, long long decrement);
  605. /// @brief Get the string value stored at key.
  606. ///
  607. /// Example:
  608. /// @code{.cpp}
  609. /// auto val = redis.get("key");
  610. /// if (val)
  611. /// std::cout << *val << std::endl;
  612. /// else
  613. /// std::cout << "key not exist" << std::endl;
  614. /// @endcode
  615. /// @param key Key.
  616. /// @return The value stored at key.
  617. /// @note If key does not exist, `get` returns `OptionalString{}` (`std::nullopt`).
  618. /// @see https://redis.io/commands/get
  619. OptionalString get(const StringView &key);
  620. /// @brief Get the bit value at offset in the string.
  621. /// @param key Key.
  622. /// @param offset Offset.
  623. /// @return The bit value.
  624. /// @see https://redis.io/commands/getbit
  625. long long getbit(const StringView &key, long long offset);
  626. /// @brief Get the substring of the string stored at key.
  627. /// @param key Key.
  628. /// @param start Start index (inclusive) of the range. 0 means the beginning of the string.
  629. /// @param end End index (inclusive) of the range. -1 means the end of the string.
  630. /// @return The substring in range [start, end]. If key does not exist, return an empty string.
  631. /// @see https://redis.io/commands/getrange
  632. std::string getrange(const StringView &key, long long start, long long end);
  633. /// @brief Atomically set the string stored at `key` to `val`, and return the old value.
  634. /// @param key Key.
  635. /// @param val Value to be set.
  636. /// @return The old value stored at key.
  637. /// @note If key does not exist, `getset` returns `OptionalString{}` (`std::nullopt`).
  638. /// @see https://redis.io/commands/getset
  639. /// @see `OptionalString`
  640. OptionalString getset(const StringView &key, const StringView &val);
  641. /// @brief Increment the integer stored at key by 1.
  642. /// @param key Key.
  643. /// @return The value after the increment.
  644. /// @see https://redis.io/commands/incr
  645. long long incr(const StringView &key);
  646. /// @brief Increment the integer stored at key by `increment`.
  647. /// @param key Key.
  648. /// @param increment Increment.
  649. /// @return The value after the increment.
  650. /// @see https://redis.io/commands/incrby
  651. long long incrby(const StringView &key, long long increment);
  652. /// @brief Increment the floating point number stored at key by `increment`.
  653. /// @param key Key.
  654. /// @param increment Increment.
  655. /// @return The value after the increment.
  656. /// @see https://redis.io/commands/incrbyfloat
  657. double incrbyfloat(const StringView &key, double increment);
  658. /// @brief Get the values of multiple keys atomically.
  659. ///
  660. /// Example:
  661. /// @code{.cpp}
  662. /// std::vector<std::string> keys = {"k1", "k2", "k3"};
  663. /// std::vector<OptionalString> vals;
  664. /// redis.mget(keys.begin(), keys.end(), std::back_inserter(vals));
  665. /// for (const auto &val : vals) {
  666. /// if (val)
  667. /// std::cout << *val << std::endl;
  668. /// else
  669. /// std::cout << "key does not exist" << std::endl;
  670. /// }
  671. /// @endcode
  672. /// @param first Iterator to the first key of the given range.
  673. /// @param last Off-the-end iterator to the given range.
  674. /// @param output Output iterator to the destination where the values are stored.
  675. /// @note The destination should be a container of `OptionalString` type,
  676. /// since the given key might not exist (in this case, the value of the corresponding
  677. /// key is `OptionalString{}` (`std::nullopt`)).
  678. /// @see https://redis.io/commands/mget
  679. template <typename Input, typename Output>
  680. void mget(Input first, Input last, Output output);
  681. /// @brief Get the values of multiple keys atomically.
  682. ///
  683. /// Example:
  684. /// @code{.cpp}
  685. /// std::vector<OptionalString> vals;
  686. /// redis.mget({"k1", "k2", "k3"}, std::back_inserter(vals));
  687. /// for (const auto &val : vals) {
  688. /// if (val)
  689. /// std::cout << *val << std::endl;
  690. /// else
  691. /// std::cout << "key does not exist" << std::endl;
  692. /// }
  693. /// @endcode
  694. /// @param il Initializer list of keys.
  695. /// @param output Output iterator to the destination where the values are stored.
  696. /// @note The destination should be a container of `OptionalString` type,
  697. /// since the given key might not exist (in this case, the value of the corresponding
  698. /// key is `OptionalString{}` (`std::nullopt`)).
  699. /// @see https://redis.io/commands/mget
  700. template <typename T, typename Output>
  701. void mget(std::initializer_list<T> il, Output output) {
  702. mget(il.begin(), il.end(), output);
  703. }
  704. /// @brief Set multiple key-value pairs.
  705. ///
  706. /// Example:
  707. /// @code{.cpp}
  708. /// std::vector<std::pair<std::string, std::string>> kvs1 = {{"k1", "v1"}, {"k2", "v2"}};
  709. /// redis.mset(kvs1.begin(), kvs1.end());
  710. /// std::unordered_map<std::string, std::string> kvs2 = {{"k3", "v3"}, {"k4", "v4"}};
  711. /// redis.mset(kvs2.begin(), kvs2.end());
  712. /// @endcode
  713. /// @param first Iterator to the first key-value pair.
  714. /// @param last Off-the-end iterator to the given range.
  715. /// @see https://redis.io/commands/mset
  716. template <typename Input>
  717. void mset(Input first, Input last);
  718. /// @brief Set multiple key-value pairs.
  719. ///
  720. /// Example:
  721. /// @code{.cpp}
  722. /// redis.mset({std::make_pair("k1", "v1"), std::make_pair("k2", "v2")});
  723. /// @endcode
  724. /// @param il Initializer list of key-value pairs.
  725. /// @see https://redis.io/commands/mset
  726. template <typename T>
  727. void mset(std::initializer_list<T> il) {
  728. mset(il.begin(), il.end());
  729. }
  730. /// @brief Set the given key-value pairs if all specified keys do not exist.
  731. ///
  732. /// Example:
  733. /// @code{.cpp}
  734. /// std::vector<std::pair<std::string, std::string>> kvs1;
  735. /// redis.msetnx(kvs1.begin(), kvs1.end());
  736. /// std::unordered_map<std::string, std::string> kvs2;
  737. /// redis.msetnx(kvs2.begin(), kvs2.end());
  738. /// @endcode
  739. /// @param first Iterator to the first key-value pair.
  740. /// @param last Off-the-end iterator of the given range.
  741. /// @return Whether all keys have been set.
  742. /// @retval true If all keys have been set.
  743. /// @retval false If no key was set, i.e. at least one key already exist.
  744. /// @see https://redis.io/commands/msetnx
  745. template <typename Input>
  746. bool msetnx(Input first, Input last);
  747. /// @brief Set the given key-value pairs if all specified keys do not exist.
  748. ///
  749. /// Example:
  750. /// @code{.cpp}
  751. /// redis.msetnx({make_pair("k1", "v1"), make_pair("k2", "v2")});
  752. /// @endcode
  753. /// @param il Initializer list of key-value pairs.
  754. /// @return Whether all keys have been set.
  755. /// @retval true If all keys have been set.
  756. /// @retval false If no key was set, i.e. at least one key already exist.
  757. /// @see https://redis.io/commands/msetnx
  758. template <typename T>
  759. bool msetnx(std::initializer_list<T> il) {
  760. return msetnx(il.begin(), il.end());
  761. }
  762. /// @brief Set key-value pair with the given timeout in milliseconds.
  763. /// @param key Key.
  764. /// @param ttl Time-To-Live in milliseconds.
  765. /// @param val Value.
  766. /// @see https://redis.io/commands/psetex
  767. void psetex(const StringView &key,
  768. long long ttl,
  769. const StringView &val);
  770. /// @brief Set key-value pair with the given timeout in milliseconds.
  771. /// @param key Key.
  772. /// @param ttl Time-To-Live in milliseconds.
  773. /// @param val Value.
  774. /// @see https://redis.io/commands/psetex
  775. void psetex(const StringView &key,
  776. const std::chrono::milliseconds &ttl,
  777. const StringView &val);
  778. /// @brief Set a key-value pair.
  779. ///
  780. /// Example:
  781. /// @code{.cpp}
  782. /// // Set a key-value pair.
  783. /// redis.set("key", "value");
  784. /// // Set a key-value pair, and expire it after 10 seconds.
  785. /// redis.set("key", "value", std::chrono::seconds(10));
  786. /// // Set a key-value pair with a timeout, only if the key already exists.
  787. /// if (redis.set("key", "value", std::chrono::seconds(10), UpdateType::EXIST))
  788. /// std::cout << "OK" << std::endl;
  789. /// else
  790. /// std::cout << "key does not exist" << std::endl;
  791. /// @endcode
  792. /// @param key Key.
  793. /// @param val Value.
  794. /// @param ttl Timeout on the key. If `ttl` is 0ms, do not set timeout.
  795. /// @param type Options for set command:
  796. /// - UpdateType::EXIST: Set the key only if it already exists.
  797. /// - UpdateType::NOT_EXIST: Set the key only if it does not exist.
  798. /// - UpdateType::ALWAYS: Always set the key no matter whether it exists.
  799. /// @return Whether the key has been set.
  800. /// @retval true If the key has been set.
  801. /// @retval false If the key was not set, because of the given option.
  802. /// @see https://redis.io/commands/set
  803. // TODO: Support KEEPTTL option for Redis 6.0
  804. bool set(const StringView &key,
  805. const StringView &val,
  806. const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0),
  807. UpdateType type = UpdateType::ALWAYS);
  808. // TODO: add SETBIT command.
  809. /// @brief Set key-value pair with the given timeout in seconds.
  810. /// @param key Key.
  811. /// @param ttl Time-To-Live in seconds.
  812. /// @param val Value.
  813. /// @see https://redis.io/commands/setex
  814. void setex(const StringView &key,
  815. long long ttl,
  816. const StringView &val);
  817. /// @brief Set key-value pair with the given timeout in seconds.
  818. /// @param key Key.
  819. /// @param ttl Time-To-Live in seconds.
  820. /// @param val Value.
  821. /// @see https://redis.io/commands/setex
  822. void setex(const StringView &key,
  823. const std::chrono::seconds &ttl,
  824. const StringView &val);
  825. /// @brief Set the key if it does not exist.
  826. /// @param key Key.
  827. /// @param val Value.
  828. /// @return Whether the key has been set.
  829. /// @retval true If the key has been set.
  830. /// @retval false If the key was not set, i.e. the key already exists.
  831. /// @see https://redis.io/commands/setnx
  832. bool setnx(const StringView &key, const StringView &val);
  833. /// @brief Set the substring starting from `offset` to the given value.
  834. /// @param key Key.
  835. /// @param offset Offset.
  836. /// @param val Value.
  837. /// @return The length of the string after this operation.
  838. /// @see https://redis.io/commands/setrange
  839. long long setrange(const StringView &key, long long offset, const StringView &val);
  840. /// @brief Get the length of the string stored at key.
  841. /// @param key Key.
  842. /// @return The length of the string.
  843. /// @note If key does not exist, `strlen` returns 0.
  844. /// @see https://redis.io/commands/strlen
  845. long long strlen(const StringView &key);
  846. // LIST commands.
  847. /// @brief Pop the first element of the list in a blocking way.
  848. /// @param key Key where the list is stored.
  849. /// @param timeout Timeout in seconds. 0 means block forever.
  850. /// @return Key-element pair.
  851. /// @note If list is empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  852. /// @see `Redis::lpop`
  853. /// @see https://redis.io/commands/blpop
  854. OptionalStringPair blpop(const StringView &key, long long timeout);
  855. /// @brief Pop the first element of the list in a blocking way.
  856. /// @param key Key where the list is stored.
  857. /// @param timeout Timeout in seconds. 0 means block forever.
  858. /// @return Key-element pair.
  859. /// @note If list is empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  860. /// @see `Redis::lpop`
  861. /// @see https://redis.io/commands/blpop
  862. OptionalStringPair blpop(const StringView &key,
  863. const std::chrono::seconds &timeout = std::chrono::seconds{0});
  864. /// @brief Pop the first element of multiple lists in a blocking way.
  865. /// @param first Iterator to the first key.
  866. /// @param last Off-the-end iterator to the key range.
  867. /// @param timeout Timeout in seconds. 0 means block forever.
  868. /// @return Key-element pair.
  869. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  870. /// @see `Redis::lpop`
  871. /// @see https://redis.io/commands/blpop
  872. template <typename Input>
  873. OptionalStringPair blpop(Input first, Input last, long long timeout);
  874. /// @brief Pop the first element of multiple lists in a blocking way.
  875. /// @param il Initializer list of keys.
  876. /// @param timeout Timeout in seconds. 0 means block forever.
  877. /// @return Key-element pair.
  878. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  879. /// @see `Redis::lpop`
  880. /// @see https://redis.io/commands/blpop
  881. template <typename T>
  882. OptionalStringPair blpop(std::initializer_list<T> il, long long timeout) {
  883. return blpop(il.begin(), il.end(), timeout);
  884. }
  885. /// @brief Pop the first element of multiple lists in a blocking way.
  886. /// @param first Iterator to the first key.
  887. /// @param last Off-the-end iterator to the key range.
  888. /// @param timeout Timeout in seconds. 0 means block forever.
  889. /// @return Key-element pair.
  890. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  891. /// @see `Redis::lpop`
  892. /// @see https://redis.io/commands/blpop
  893. template <typename Input>
  894. OptionalStringPair blpop(Input first,
  895. Input last,
  896. const std::chrono::seconds &timeout = std::chrono::seconds{0});
  897. /// @brief Pop the first element of multiple lists in a blocking way.
  898. /// @param il Initializer list of keys.
  899. /// @param timeout Timeout in seconds. 0 means block forever.
  900. /// @return Key-element pair.
  901. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  902. /// @see `Redis::lpop`
  903. /// @see https://redis.io/commands/blpop
  904. template <typename T>
  905. OptionalStringPair blpop(std::initializer_list<T> il,
  906. const std::chrono::seconds &timeout = std::chrono::seconds{0}) {
  907. return blpop(il.begin(), il.end(), timeout);
  908. }
  909. /// @brief Pop the last element of the list in a blocking way.
  910. /// @param key Key where the list is stored.
  911. /// @param timeout Timeout in seconds. 0 means block forever.
  912. /// @return Key-element pair.
  913. /// @note If list is empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  914. /// @see `Redis::rpop`
  915. /// @see https://redis.io/commands/brpop
  916. OptionalStringPair brpop(const StringView &key, long long timeout);
  917. /// @brief Pop the last element of the list in a blocking way.
  918. /// @param key Key where the list is stored.
  919. /// @param timeout Timeout in seconds. 0 means block forever.
  920. /// @return Key-element pair.
  921. /// @note If list is empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  922. /// @see `Redis::rpop`
  923. /// @see https://redis.io/commands/brpop
  924. OptionalStringPair brpop(const StringView &key,
  925. const std::chrono::seconds &timeout = std::chrono::seconds{0});
  926. /// @brief Pop the last element of multiple lists in a blocking way.
  927. /// @param first Iterator to the first key.
  928. /// @param last Off-the-end iterator to the key range.
  929. /// @param timeout Timeout in seconds. 0 means block forever.
  930. /// @return Key-element pair.
  931. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  932. /// @see `Redis::rpop`
  933. /// @see https://redis.io/commands/brpop
  934. template <typename Input>
  935. OptionalStringPair brpop(Input first, Input last, long long timeout);
  936. /// @brief Pop the last element of multiple lists in a blocking way.
  937. /// @param il Initializer list of lists.
  938. /// @param timeout Timeout in seconds. 0 means block forever.
  939. /// @return Key-element pair.
  940. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  941. /// @see `Redis::rpop`
  942. /// @see https://redis.io/commands/brpop
  943. template <typename T>
  944. OptionalStringPair brpop(std::initializer_list<T> il, long long timeout) {
  945. return brpop(il.begin(), il.end(), timeout);
  946. }
  947. /// @brief Pop the last element of multiple lists in a blocking way.
  948. /// @param first Iterator to the first list.
  949. /// @param last Off-the-end iterator to the list range.
  950. /// @param timeout Timeout in seconds. 0 means block forever.
  951. /// @return Key-element pair.
  952. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  953. /// @see `Redis::rpop`
  954. /// @see https://redis.io/commands/brpop
  955. template <typename Input>
  956. OptionalStringPair brpop(Input first,
  957. Input last,
  958. const std::chrono::seconds &timeout = std::chrono::seconds{0});
  959. /// @brief Pop the last element of multiple lists in a blocking way.
  960. /// @param il Initializer list of list keys.
  961. /// @param timeout Timeout in seconds. 0 means block forever.
  962. /// @return Key-element pair.
  963. /// @note If all lists are empty and timeout reaches, return `OptionalStringPair{}` (`std::nullopt`).
  964. /// @see `Redis::rpop`
  965. /// @see https://redis.io/commands/brpop
  966. template <typename T>
  967. OptionalStringPair brpop(std::initializer_list<T> il,
  968. const std::chrono::seconds &timeout = std::chrono::seconds{0}) {
  969. return brpop(il.begin(), il.end(), timeout);
  970. }
  971. /// @brief Pop last element of one list and push it to the left of another list in blocking way.
  972. /// @param source Key of the source list.
  973. /// @param destination Key of the destination list.
  974. /// @param timeout Timeout. 0 means block forever.
  975. /// @return The popped element.
  976. /// @note If the source list does not exist, `brpoplpush` returns `OptionalString{}` (`std::nullopt`).
  977. /// @see `Redis::rpoplpush`
  978. /// @see https://redis.io/commands/brpoplpush
  979. OptionalString brpoplpush(const StringView &source,
  980. const StringView &destination,
  981. long long timeout);
  982. /// @brief Pop last element of one list and push it to the left of another list in blocking way.
  983. /// @param source Key of the source list.
  984. /// @param destination Key of the destination list.
  985. /// @param timeout Timeout. 0 means block forever.
  986. /// @return The popped element.
  987. /// @note If the source list does not exist, `brpoplpush` returns `OptionalString{}` (`std::nullopt`).
  988. /// @see `Redis::rpoplpush`
  989. /// @see https://redis.io/commands/brpoplpush
  990. OptionalString brpoplpush(const StringView &source,
  991. const StringView &destination,
  992. const std::chrono::seconds &timeout = std::chrono::seconds{0});
  993. /// @brief Get the element at the given index of the list.
  994. /// @param key Key where the list is stored.
  995. /// @param index Zero-base index, and -1 means the last element.
  996. /// @return The element at the given index.
  997. /// @see https://redis.io/commands/lindex
  998. OptionalString lindex(const StringView &key, long long index);
  999. /// @brief Insert an element to a list before or after the pivot element.
  1000. ///
  1001. /// Example:
  1002. /// @code{.cpp}
  1003. /// // Insert 'hello' before 'world'
  1004. /// auto len = redis.linsert("list", InsertPosition::BEFORE, "world", "hello");
  1005. /// if (len == -1)
  1006. /// std::cout << "there's no 'world' in the list" << std::endl;
  1007. /// else
  1008. /// std::cout << "after the operation, the length of the list is " << len << std::endl;
  1009. /// @endcode
  1010. /// @param key Key where the list is stored.
  1011. /// @param position Before or after the pivot element.
  1012. /// @param pivot The pivot value. The `pivot` is the value of the element, not the index.
  1013. /// @param val Element to be inserted.
  1014. /// @return The length of the list after the operation.
  1015. /// @note If the pivot value is not found, `linsert` returns -1.
  1016. /// @see `InsertPosition`
  1017. /// @see https://redis.io/commands/linsert
  1018. long long linsert(const StringView &key,
  1019. InsertPosition position,
  1020. const StringView &pivot,
  1021. const StringView &val);
  1022. /// @brief Get the length of the list.
  1023. /// @param key Key where the list is stored.
  1024. /// @return The length of the list.
  1025. /// @see https://redis.io/commands/llen
  1026. long long llen(const StringView &key);
  1027. /// @brief Pop the first element of the list.
  1028. ///
  1029. /// Example:
  1030. /// @code{.cpp}
  1031. /// auto element = redis.lpop("list");
  1032. /// if (element)
  1033. /// std::cout << *element << std::endl;
  1034. /// else
  1035. /// std::cout << "list is empty, i.e. list does not exist" << std::endl;
  1036. /// @endcode
  1037. /// @param key Key where the list is stored.
  1038. /// @return The popped element.
  1039. /// @note If list is empty, i.e. key does not exist, return `OptionalString{}` (`std::nullopt`).
  1040. /// @see https://redis.io/commands/lpop
  1041. OptionalString lpop(const StringView &key);
  1042. /// @brief Push an element to the beginning of the list.
  1043. /// @param key Key where the list is stored.
  1044. /// @param val Element to be pushed.
  1045. /// @return The length of the list after the operation.
  1046. /// @see https://redis.io/commands/lpush
  1047. long long lpush(const StringView &key, const StringView &val);
  1048. /// @brief Push multiple elements to the beginning of the list.
  1049. ///
  1050. /// Example:
  1051. /// @code{.cpp}
  1052. /// std::vector<std::string> elements = {"e1", "e2", "e3"};
  1053. /// redis.lpush("list", elements.begin(), elements.end());
  1054. /// @endcode
  1055. /// @param key Key where the list is stored.
  1056. /// @param first Iterator to the first element to be pushed.
  1057. /// @param last Off-the-end iterator to the given element range.
  1058. /// @return The length of the list after the operation.
  1059. /// @see https://redis.io/commands/lpush
  1060. template <typename Input>
  1061. long long lpush(const StringView &key, Input first, Input last);
  1062. /// @brief Push multiple elements to the beginning of the list.
  1063. ///
  1064. /// Example:
  1065. /// @code{.cpp}
  1066. /// redis.lpush("list", {"e1", "e2", "e3"});
  1067. /// @endcode
  1068. /// @param key Key where the list is stored.
  1069. /// @param il Initializer list of elements.
  1070. /// @return The length of the list after the operation.
  1071. /// @see https://redis.io/commands/lpush
  1072. template <typename T>
  1073. long long lpush(const StringView &key, std::initializer_list<T> il) {
  1074. return lpush(key, il.begin(), il.end());
  1075. }
  1076. /// @brief Push an element to the beginning of the list, only if the list already exists.
  1077. /// @param key Key where the list is stored.
  1078. /// @param val Element to be pushed.
  1079. /// @return The length of the list after the operation.
  1080. /// @see https://redis.io/commands/lpushx
  1081. // TODO: add a multiple elements overload.
  1082. long long lpushx(const StringView &key, const StringView &val);
  1083. /// @brief Get elements in the given range of the given list.
  1084. ///
  1085. /// Example:
  1086. /// @code{.cpp}
  1087. /// std::vector<std::string> elements;
  1088. /// // Save all elements of a Redis list to a vector of string.
  1089. /// redis.lrange("list", 0, -1, std::back_inserter(elements));
  1090. /// @endcode
  1091. /// @param key Key where the list is stored.
  1092. /// @param start Start index of the range. Index can be negative, which mean index from the end.
  1093. /// @param stop End index of the range.
  1094. /// @param output Output iterator to the destination where the results are saved.
  1095. /// @see https://redis.io/commands/lrange
  1096. template <typename Output>
  1097. void lrange(const StringView &key, long long start, long long stop, Output output);
  1098. /// @brief Remove the first `count` occurrences of elements equal to `val`.
  1099. /// @param key Key where the list is stored.
  1100. /// @param count Number of occurrences to be removed.
  1101. /// @param val Value.
  1102. /// @return Number of elements removed.
  1103. /// @note `count` can be positive, negative and 0. Check the reference for detail.
  1104. /// @see https://redis.io/commands/lrem
  1105. long long lrem(const StringView &key, long long count, const StringView &val);
  1106. /// @brief Set the element at the given index to the specified value.
  1107. /// @param key Key where the list is stored.
  1108. /// @param index Index of the element to be set.
  1109. /// @param val Value.
  1110. /// @see https://redis.io/commands/lset
  1111. void lset(const StringView &key, long long index, const StringView &val);
  1112. /// @brief Trim a list to keep only element in the given range.
  1113. /// @param key Key where the key is stored.
  1114. /// @param start Start of the index.
  1115. /// @param stop End of the index.
  1116. /// @see https://redis.io/commands/ltrim
  1117. void ltrim(const StringView &key, long long start, long long stop);
  1118. /// @brief Pop the last element of a list.
  1119. /// @param key Key where the list is stored.
  1120. /// @return The popped element.
  1121. /// @note If the list is empty, i.e. key does not exist, `rpop` returns `OptionalString{}` (`std::nullopt`).
  1122. /// @see https://redis.io/commands/rpop
  1123. OptionalString rpop(const StringView &key);
  1124. /// @brief Pop last element of one list and push it to the left of another list.
  1125. /// @param source Key of the source list.
  1126. /// @param destination Key of the destination list.
  1127. /// @return The popped element.
  1128. /// @note If the source list does not exist, `rpoplpush` returns `OptionalString{}` (`std::nullopt`).
  1129. /// @see https://redis.io/commands/brpoplpush
  1130. OptionalString rpoplpush(const StringView &source, const StringView &destination);
  1131. /// @brief Push an element to the end of the list.
  1132. /// @param key Key where the list is stored.
  1133. /// @param val Element to be pushed.
  1134. /// @return The length of the list after the operation.
  1135. /// @see https://redis.io/commands/rpush
  1136. long long rpush(const StringView &key, const StringView &val);
  1137. /// @brief Push multiple elements to the end of the list.
  1138. /// @param key Key where the list is stored.
  1139. /// @param first Iterator to the first element to be pushed.
  1140. /// @param last Off-the-end iterator to the given element range.
  1141. /// @return The length of the list after the operation.
  1142. /// @see https://redis.io/commands/rpush
  1143. template <typename Input>
  1144. long long rpush(const StringView &key, Input first, Input last);
  1145. /// @brief Push multiple elements to the end of the list.
  1146. /// @param key Key where the list is stored.
  1147. /// @param il Initializer list of elements to be pushed.
  1148. /// @return The length of the list after the operation.
  1149. /// @see https://redis.io/commands/rpush
  1150. template <typename T>
  1151. long long rpush(const StringView &key, std::initializer_list<T> il) {
  1152. return rpush(key, il.begin(), il.end());
  1153. }
  1154. /// @brief Push an element to the end of the list, only if the list already exists.
  1155. /// @param key Key where the list is stored.
  1156. /// @param val Element to be pushed.
  1157. /// @return The length of the list after the operation.
  1158. /// @see https://redis.io/commands/rpushx
  1159. long long rpushx(const StringView &key, const StringView &val);
  1160. // HASH commands.
  1161. /// @brief Remove the given field from hash.
  1162. /// @param key Key where the hash is stored.
  1163. /// @param field Field to be removed.
  1164. /// @return Whether the field has been removed.
  1165. /// @retval 1 If the field exists, and has been removed.
  1166. /// @retval 0 If the field does not exist.
  1167. /// @see https://redis.io/commands/hdel
  1168. long long hdel(const StringView &key, const StringView &field);
  1169. /// @brief Remove multiple fields from hash.
  1170. /// @param key Key where the hash is stored.
  1171. /// @param first Iterator to the first field to be removed.
  1172. /// @param last Off-the-end iterator to the given field range.
  1173. /// @return Number of fields that has been removed.
  1174. /// @see https://redis.io/commands/hdel
  1175. template <typename Input>
  1176. long long hdel(const StringView &key, Input first, Input last);
  1177. /// @brief Remove multiple fields from hash.
  1178. /// @param key Key where the hash is stored.
  1179. /// @param il Initializer list of fields.
  1180. /// @return Number of fields that has been removed.
  1181. /// @see https://redis.io/commands/hdel
  1182. template <typename T>
  1183. long long hdel(const StringView &key, std::initializer_list<T> il) {
  1184. return hdel(key, il.begin(), il.end());
  1185. }
  1186. /// @brief Check if the given field exists in hash.
  1187. /// @param key Key where the hash is stored.
  1188. /// @param field Field.
  1189. /// @return Whether the field exists.
  1190. /// @retval true If the field exists in hash.
  1191. /// @retval false If the field does not exist.
  1192. /// @see https://redis.io/commands/hexists
  1193. bool hexists(const StringView &key, const StringView &field);
  1194. /// @brief Get the value of the given field.
  1195. /// @param key Key where the hash is stored.
  1196. /// @param field Field.
  1197. /// @return Value of the given field.
  1198. /// @note If field does not exist, `hget` returns `OptionalString{}` (`std::nullopt`).
  1199. /// @see https://redis.io/commands/hget
  1200. OptionalString hget(const StringView &key, const StringView &field);
  1201. /// @brief Get all field-value pairs of the given hash.
  1202. ///
  1203. /// Example:
  1204. /// @code{.cpp}
  1205. /// std::unordered_map<std::string, std::string> results;
  1206. /// // Save all field-value pairs of a Redis hash to an unordered_map<string, string>.
  1207. /// redis.hgetall("hash", std::inserter(results, results.begin()));
  1208. /// @endcode
  1209. /// @param key Key where the hash is stored.
  1210. /// @param output Output iterator to the destination where the result is saved.
  1211. /// @note It's always a bad idea to call `hgetall` on a large hash, since it will block Redis.
  1212. /// @see `Redis::hscan`
  1213. /// @see https://redis.io/commands/hgetall
  1214. template <typename Output>
  1215. void hgetall(const StringView &key, Output output);
  1216. /// @brief Increment the integer stored at the given field.
  1217. /// @param key Key where the hash is stored.
  1218. /// @param field Field.
  1219. /// @param increment Increment.
  1220. /// @return The value of the field after the increment.
  1221. /// @see https://redis.io/commands/hincrby
  1222. long long hincrby(const StringView &key, const StringView &field, long long increment);
  1223. /// @brief Increment the floating point number stored at the given field.
  1224. /// @param key Key where the hash is stored.
  1225. /// @param field Field.
  1226. /// @param increment Increment.
  1227. /// @return The value of the field after the increment.
  1228. /// @see https://redis.io/commands/hincrbyfloat
  1229. double hincrbyfloat(const StringView &key, const StringView &field, double increment);
  1230. /// @brief Get all fields of the given hash.
  1231. /// @param key Key where the hash is stored.
  1232. /// @param output Output iterator to the destination where the result is saved.
  1233. /// @note It's always a bad idea to call `hkeys` on a large hash, since it will block Redis.
  1234. /// @see `Redis::hscan`
  1235. /// @see https://redis.io/commands/hkeys
  1236. template <typename Output>
  1237. void hkeys(const StringView &key, Output output);
  1238. /// @brief Get the number of fields of the given hash.
  1239. /// @param key Key where the hash is stored.
  1240. /// @return Number of fields.
  1241. /// @see https://redis.io/commands/hlen
  1242. long long hlen(const StringView &key);
  1243. /// @brief Get values of multiple fields.
  1244. ///
  1245. /// Example:
  1246. /// @code{.cpp}
  1247. /// std::vector<std::string> fields = {"f1", "f2"};
  1248. /// std::vector<OptionalString> vals;
  1249. /// redis.hmget("hash", fields.begin(), fields.end(), std::back_inserter(vals));
  1250. /// for (const auto &val : vals) {
  1251. /// if (val)
  1252. /// std::cout << *val << std::endl;
  1253. /// else
  1254. /// std::cout << "field not exist" << std::endl;
  1255. /// }
  1256. /// @endcode
  1257. /// @param key Key where the hash is stored.
  1258. /// @param first Iterator to the first field.
  1259. /// @param last Off-the-end iterator to the given field range.
  1260. /// @param output Output iterator to the destination where the result is saved.
  1261. /// @note The destination should be a container of `OptionalString` type,
  1262. /// since the given field might not exist (in this case, the value of the corresponding
  1263. /// field is `OptionalString{}` (`std::nullopt`)).
  1264. /// @see https://redis.io/commands/hmget
  1265. template <typename Input, typename Output>
  1266. void hmget(const StringView &key, Input first, Input last, Output output);
  1267. /// @brief Get values of multiple fields.
  1268. ///
  1269. /// Example:
  1270. /// @code{.cpp}
  1271. /// std::vector<OptionalString> vals;
  1272. /// redis.hmget("hash", {"f1", "f2"}, std::back_inserter(vals));
  1273. /// for (const auto &val : vals) {
  1274. /// if (val)
  1275. /// std::cout << *val << std::endl;
  1276. /// else
  1277. /// std::cout << "field not exist" << std::endl;
  1278. /// }
  1279. /// @endcode
  1280. /// @param key Key where the hash is stored.
  1281. /// @param il Initializer list of fields.
  1282. /// @param output Output iterator to the destination where the result is saved.
  1283. /// @note The destination should be a container of `OptionalString` type,
  1284. /// since the given field might not exist (in this case, the value of the corresponding
  1285. /// field is `OptionalString{}` (`std::nullopt`)).
  1286. /// @see https://redis.io/commands/hmget
  1287. template <typename T, typename Output>
  1288. void hmget(const StringView &key, std::initializer_list<T> il, Output output) {
  1289. hmget(key, il.begin(), il.end(), output);
  1290. }
  1291. /// @brief Set multiple field-value pairs of the given hash.
  1292. ///
  1293. /// Example:
  1294. /// @code{.cpp}
  1295. /// std::unordered_map<std::string, std::string> m = {{"f1", "v1"}, {"f2", "v2"}};
  1296. /// redis.hmset("hash", m.begin(), m.end());
  1297. /// @endcode
  1298. /// @param key Key where the hash is stored.
  1299. /// @param first Iterator to the first field-value pair.
  1300. /// @param last Off-the-end iterator to the range.
  1301. /// @see https://redis.io/commands/hmset
  1302. template <typename Input>
  1303. void hmset(const StringView &key, Input first, Input last);
  1304. /// @brief Set multiple field-value pairs of the given hash.
  1305. ///
  1306. /// Example:
  1307. /// @code{.cpp}
  1308. /// redis.hmset("hash", {std::make_pair("f1", "v1"), std::make_pair("f2", "v2")});
  1309. /// @endcode
  1310. /// @param key Key where the hash is stored.
  1311. /// @param il Initializer list of field-value pairs.
  1312. /// @see https://redis.io/commands/hmset
  1313. template <typename T>
  1314. void hmset(const StringView &key, std::initializer_list<T> il) {
  1315. hmset(key, il.begin(), il.end());
  1316. }
  1317. /// @brief Scan fields of the given hash matching the given pattern.
  1318. ///
  1319. /// Example:
  1320. /// @code{.cpp}
  1321. /// auto cursor = 0LL;
  1322. /// std::unordered_map<std::string, std::string> kvs;
  1323. /// while (true) {
  1324. /// cursor = redis.hscan("hash", cursor, "pattern:*", 10, std::inserter(kvs, kvs.begin()));
  1325. /// if (cursor == 0) {
  1326. /// break;
  1327. /// }
  1328. /// }
  1329. /// @endcode
  1330. /// @param key Key where the hash is stored.
  1331. /// @param cursor Cursor.
  1332. /// @param pattern Pattern of fields to be scanned.
  1333. /// @param count A hint for how many fields to be scanned.
  1334. /// @param output Output iterator to the destination where the result is saved.
  1335. /// @return The cursor to be used for the next scan operation.
  1336. /// @see https://redis.io/commands/hscan
  1337. template <typename Output>
  1338. long long hscan(const StringView &key,
  1339. long long cursor,
  1340. const StringView &pattern,
  1341. long long count,
  1342. Output output);
  1343. /// @brief Scan fields of the given hash matching the given pattern.
  1344. /// @param key Key where the hash is stored.
  1345. /// @param cursor Cursor.
  1346. /// @param pattern Pattern of fields to be scanned.
  1347. /// @param output Output iterator to the destination where the result is saved.
  1348. /// @return The cursor to be used for the next scan operation.
  1349. /// @see https://redis.io/commands/hscan
  1350. template <typename Output>
  1351. long long hscan(const StringView &key,
  1352. long long cursor,
  1353. const StringView &pattern,
  1354. Output output);
  1355. /// @brief Scan all fields of the given hash.
  1356. /// @param key Key where the hash is stored.
  1357. /// @param cursor Cursor.
  1358. /// @param count A hint for how many fields to be scanned.
  1359. /// @param output Output iterator to the destination where the result is saved.
  1360. /// @return The cursor to be used for the next scan operation.
  1361. /// @see https://redis.io/commands/hscan
  1362. template <typename Output>
  1363. long long hscan(const StringView &key,
  1364. long long cursor,
  1365. long long count,
  1366. Output output);
  1367. /// @brief Scan all fields of the given hash.
  1368. /// @param key Key where the hash is stored.
  1369. /// @param cursor Cursor.
  1370. /// @param output Output iterator to the destination where the result is saved.
  1371. /// @return The cursor to be used for the next scan operation.
  1372. /// @see https://redis.io/commands/hscan
  1373. template <typename Output>
  1374. long long hscan(const StringView &key,
  1375. long long cursor,
  1376. Output output);
  1377. /// @brief Set hash field to value.
  1378. /// @param key Key where the hash is stored.
  1379. /// @param field Field.
  1380. /// @param val Value.
  1381. /// @return Whether the given field is a new field.
  1382. /// @retval true If the given field didn't exist, and a new field has been added.
  1383. /// @retval false If the given field already exists, and its value has been overwritten.
  1384. /// @note When `hset` returns false, it does not mean that the method failed to set the field.
  1385. /// Instead, it means that the field already exists, and we've overwritten its value.
  1386. /// If `hset` fails, it will throw an exception of `Exception` type.
  1387. /// @see https://github.com/sewenew/redis-plus-plus/issues/9
  1388. /// @see https://redis.io/commands/hset
  1389. bool hset(const StringView &key, const StringView &field, const StringView &val);
  1390. /// @brief Set hash field to value.
  1391. /// @param key Key where the hash is stored.
  1392. /// @param item The field-value pair to be set.
  1393. /// @return Whether the given field is a new field.
  1394. /// @retval true If the given field didn't exist, and a new field has been added.
  1395. /// @retval false If the given field already exists, and its value has been overwritten.
  1396. /// @note When `hset` returns false, it does not mean that the method failed to set the field.
  1397. /// Instead, it means that the field already exists, and we've overwritten its value.
  1398. /// If `hset` fails, it will throw an exception of `Exception` type.
  1399. /// @see https://github.com/sewenew/redis-plus-plus/issues/9
  1400. /// @see https://redis.io/commands/hset
  1401. bool hset(const StringView &key, const std::pair<StringView, StringView> &item);
  1402. /// @brief Set multiple fields of the given hash.
  1403. ///
  1404. /// Example:
  1405. /// @code{.cpp}
  1406. /// std::unordered_map<std::string, std::string> m = {{"f1", "v1"}, {"f2", "v2"}};
  1407. /// redis.hset("hash", m.begin(), m.end());
  1408. /// @endcode
  1409. /// @param key Key where the hash is stored.
  1410. /// @param first Iterator to the first field to be set.
  1411. /// @param last Off-the-end iterator to the given range.
  1412. /// @return Number of fields that have been added, i.e. fields that not existed before.
  1413. /// @see https://redis.io/commands/hset
  1414. template <typename Input>
  1415. auto hset(const StringView &key, Input first, Input last)
  1416. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value, long long>::type;
  1417. /// @brief Set multiple fields of the given hash.
  1418. ///
  1419. /// Example:
  1420. /// @code{.cpp}
  1421. /// redis.hset("hash", {std::make_pair("f1", "v1"), std::make_pair("f2", "v2")});
  1422. /// @endcode
  1423. /// @param key Key where the hash is stored.
  1424. /// @param il Initializer list of field-value pairs.
  1425. /// @return Number of fields that have been added, i.e. fields that not existed before.
  1426. /// @see https://redis.io/commands/hset
  1427. template <typename T>
  1428. long long hset(const StringView &key, std::initializer_list<T> il) {
  1429. return hset(key, il.begin(), il.end());
  1430. }
  1431. /// @brief Set hash field to value, only if the given field does not exist.
  1432. /// @param key Key where the hash is stored.
  1433. /// @param field Field.
  1434. /// @param val Value.
  1435. /// @return Whether the field has been set.
  1436. /// @retval true If the field has been set.
  1437. /// @retval false If failed to set the field, i.e. the field already exists.
  1438. /// @see https://redis.io/commands/hsetnx
  1439. bool hsetnx(const StringView &key, const StringView &field, const StringView &val);
  1440. /// @brief Set hash field to value, only if the given field does not exist.
  1441. /// @param key Key where the hash is stored.
  1442. /// @param item The field-value pair to be set.
  1443. /// @return Whether the field has been set.
  1444. /// @retval true If the field has been set.
  1445. /// @retval false If failed to set the field, i.e. the field already exists.
  1446. /// @see https://redis.io/commands/hsetnx
  1447. bool hsetnx(const StringView &key, const std::pair<StringView, StringView> &item);
  1448. /// @brief Get the length of the string stored at the given field.
  1449. /// @param key Key where the hash is stored.
  1450. /// @param field Field.
  1451. /// @return Length of the string.
  1452. /// @see https://redis.io/commands/hstrlen
  1453. long long hstrlen(const StringView &key, const StringView &field);
  1454. /// @brief Get values of all fields stored at the given hash.
  1455. /// @param key Key where the hash is stored.
  1456. /// @param output Output iterator to the destination where the result is saved.
  1457. /// @note It's always a bad idea to call `hvals` on a large hash, since it might block Redis.
  1458. /// @see `Redis::hscan`
  1459. /// @see https://redis.io/commands/hvals
  1460. template <typename Output>
  1461. void hvals(const StringView &key, Output output);
  1462. // SET commands.
  1463. /// @brief Add a member to the given set.
  1464. /// @param key Key where the set is stored.
  1465. /// @param member Member to be added.
  1466. /// @return Whether the given member is a new member.
  1467. /// @retval 1 The member did not exist before, and it has been added now.
  1468. /// @retval 0 The member already exists before this operation.
  1469. /// @see https://redis.io/commands/sadd
  1470. long long sadd(const StringView &key, const StringView &member);
  1471. /// @brief Add multiple members to the given set.
  1472. /// @param key Key where the set is stored.
  1473. /// @param first Iterator to the first member to be added.
  1474. /// @param last Off-the-end iterator to the member range.
  1475. /// @return Number of new members that have been added, i.e. members did not exist before.
  1476. /// @see https://redis.io/commands/sadd
  1477. template <typename Input>
  1478. long long sadd(const StringView &key, Input first, Input last);
  1479. /// @brief Add multiple members to the given set.
  1480. /// @param key Key where the set is stored.
  1481. /// @param il Initializer list of members to be added.
  1482. /// @return Number of new members that have been added, i.e. members did not exist before.
  1483. /// @see https://redis.io/commands/sadd
  1484. template <typename T>
  1485. long long sadd(const StringView &key, std::initializer_list<T> il) {
  1486. return sadd(key, il.begin(), il.end());
  1487. }
  1488. /// @brief Get the number of members in the set.
  1489. /// @param key Key where the set is stored.
  1490. /// @return Number of members.
  1491. /// @see https://redis.io/commands/scard
  1492. long long scard(const StringView &key);
  1493. /// @brief Get the difference between the first set and all successive sets.
  1494. /// @param first Iterator to the first set.
  1495. /// @param last Off-the-end iterator to the range.
  1496. /// @param output Output iterator to the destination where the result is saved.
  1497. /// @see https://redis.io/commands/sdiff
  1498. // TODO: `void sdiff(const StringView &key, Input first, Input last, Output output)` is better.
  1499. template <typename Input, typename Output>
  1500. void sdiff(Input first, Input last, Output output);
  1501. /// @brief Get the difference between the first set and all successive sets.
  1502. /// @param il Initializer list of sets.
  1503. /// @param output Output iterator to the destination where the result is saved.
  1504. /// @see https://redis.io/commands/sdiff
  1505. template <typename T, typename Output>
  1506. void sdiff(std::initializer_list<T> il, Output output) {
  1507. sdiff(il.begin(), il.end(), output);
  1508. }
  1509. /// @brief Copy set stored at `key` to `destination`.
  1510. /// @param destination Key of the destination set.
  1511. /// @param key Key of the source set.
  1512. /// @return Number of members of the set.
  1513. /// @see https://redis.io/commands/sdiffstore
  1514. long long sdiffstore(const StringView &destination, const StringView &key);
  1515. /// @brief Same as `sdiff`, except that it stores the result to another set.
  1516. /// @param destination Key of the destination set.
  1517. /// @param first Iterator to the first set.
  1518. /// @param last Off-the-end iterator to set range.
  1519. /// @return Number of members in the resulting set.
  1520. /// @see https://redis.io/commands/sdiffstore
  1521. template <typename Input>
  1522. long long sdiffstore(const StringView &destination,
  1523. Input first,
  1524. Input last);
  1525. /// @brief Same as `sdiff`, except that it stores the result to another set.
  1526. /// @param destination Key of the destination set.
  1527. /// @param il Initializer list of sets.
  1528. /// @return Number of members in the resulting set.
  1529. /// @see https://redis.io/commands/sdiffstore
  1530. template <typename T>
  1531. long long sdiffstore(const StringView &destination,
  1532. std::initializer_list<T> il) {
  1533. return sdiffstore(destination, il.begin(), il.end());
  1534. }
  1535. /// @brief Get the intersection between the first set and all successive sets.
  1536. /// @param first Iterator to the first set.
  1537. /// @param last Off-the-end iterator to the range.
  1538. /// @param output Output iterator to the destination where the result is saved.
  1539. /// @see https://redis.io/commands/sinter
  1540. // TODO: `void sinter(const StringView &key, Input first, Input last, Output output)` is better.
  1541. template <typename Input, typename Output>
  1542. void sinter(Input first, Input last, Output output);
  1543. /// @brief Get the intersection between the first set and all successive sets.
  1544. /// @param il Initializer list of sets.
  1545. /// @param output Output iterator to the destination where the result is saved.
  1546. /// @see https://redis.io/commands/sinter
  1547. template <typename T, typename Output>
  1548. void sinter(std::initializer_list<T> il, Output output) {
  1549. sinter(il.begin(), il.end(), output);
  1550. }
  1551. /// @brief Copy set stored at `key` to `destination`.
  1552. /// @param destination Key of the destination set.
  1553. /// @param key Key of the source set.
  1554. /// @return Number of members of the set.
  1555. /// @see https://redis.io/commands/sinter
  1556. long long sinterstore(const StringView &destination, const StringView &key);
  1557. /// @brief Same as `sinter`, except that it stores the result to another set.
  1558. /// @param destination Key of the destination set.
  1559. /// @param first Iterator to the first set.
  1560. /// @param last Off-the-end iterator to set range.
  1561. /// @return Number of members in the resulting set.
  1562. /// @see https://redis.io/commands/sinter
  1563. template <typename Input>
  1564. long long sinterstore(const StringView &destination,
  1565. Input first,
  1566. Input last);
  1567. /// @brief Same as `sinter`, except that it stores the result to another set.
  1568. /// @param destination Key of the destination set.
  1569. /// @param il Initializer list of sets.
  1570. /// @return Number of members in the resulting set.
  1571. /// @see https://redis.io/commands/sinter
  1572. template <typename T>
  1573. long long sinterstore(const StringView &destination,
  1574. std::initializer_list<T> il) {
  1575. return sinterstore(destination, il.begin(), il.end());
  1576. }
  1577. /// @brief Test if `member` exists in the set stored at key.
  1578. /// @param key Key where the set is stored.
  1579. /// @param member Member to be checked.
  1580. /// @return Whether `member` exists in the set.
  1581. /// @retval true If it exists in the set.
  1582. /// @retval false If it does not exist in the set, or the given key does not exist.
  1583. /// @see https://redis.io/commands/sismember
  1584. bool sismember(const StringView &key, const StringView &member);
  1585. /// @brief Get all members in the given set.
  1586. ///
  1587. /// Example:
  1588. /// @code{.cpp}
  1589. /// std::unordered_set<std::string> members1;
  1590. /// redis.smembers("set", std::inserter(members1, members1.begin()));
  1591. /// std::vector<std::string> members2;
  1592. /// redis.smembers("set", std::back_inserter(members2));
  1593. /// @endcode
  1594. /// @param key Key where the set is stored.
  1595. /// @param output Iterator to the destination where the result is saved.
  1596. /// @see https://redis.io/commands/smembers
  1597. template <typename Output>
  1598. void smembers(const StringView &key, Output output);
  1599. /// @brief Move `member` from one set to another.
  1600. /// @param source Key of the set in which the member currently exists.
  1601. /// @param destination Key of the destination set.
  1602. /// @return Whether the member has been moved.
  1603. /// @retval true If the member has been moved.
  1604. /// @retval false If `member` does not exist in `source`.
  1605. /// @see https://redis.io/commands/smove
  1606. bool smove(const StringView &source,
  1607. const StringView &destination,
  1608. const StringView &member);
  1609. /// @brief Remove a random member from the set.
  1610. /// @param key Key where the set is stored.
  1611. /// @return The popped member.
  1612. /// @note If the set is empty, `spop` returns `OptionalString{}` (`std::nullopt`).
  1613. /// @see `Redis::srandmember`
  1614. /// @see https://redis.io/commands/spop
  1615. OptionalString spop(const StringView &key);
  1616. /// @brief Remove multiple random members from the set.
  1617. ///
  1618. /// Example:
  1619. /// @code{.cpp}
  1620. /// std::vector<std::string> members;
  1621. /// redis.spop("set", 10, std::back_inserter(members));
  1622. /// @endcode
  1623. /// @param key Key where the set is stored.
  1624. /// @param count Number of members to be popped.
  1625. /// @param output Output iterator to the destination where the result is saved.
  1626. /// @note The number of popped members might be less than `count`.
  1627. /// @see `Redis::srandmember`
  1628. /// @see https://redis.io/commands/spop
  1629. template <typename Output>
  1630. void spop(const StringView &key, long long count, Output output);
  1631. /// @brief Get a random member of the given set.
  1632. /// @param key Key where the set is stored.
  1633. /// @return A random member.
  1634. /// @note If the set is empty, `srandmember` returns `OptionalString{}` (`std::nullopt`).
  1635. /// @note This method won't remove the member from the set.
  1636. /// @see `Redis::spop`
  1637. /// @see https://redis.io/commands/srandmember
  1638. OptionalString srandmember(const StringView &key);
  1639. /// @brief Get multiple random members of the given set.
  1640. /// @param key Key where the set is stored.
  1641. /// @param count Number of members to be returned.
  1642. /// @param output Output iterator to the destination where the result is saved.
  1643. /// @note This method won't remove members from the set.
  1644. /// @see `Redis::spop`
  1645. /// @see https://redis.io/commands/srandmember
  1646. template <typename Output>
  1647. void srandmember(const StringView &key, long long count, Output output);
  1648. /// @brief Remove a member from set.
  1649. /// @param key Key where the set is stored.
  1650. /// @param member Member to be removed.
  1651. /// @return Whether the member has been removed.
  1652. /// @retval 1 If the given member exists, and has been removed.
  1653. /// @retval 0 If the given member does not exist.
  1654. /// @see https://redis.io/commands/srem
  1655. long long srem(const StringView &key, const StringView &member);
  1656. /// @brief Remove multiple members from set.
  1657. /// @param key Key where the set is stored.
  1658. /// @param first Iterator to the first member to be removed.
  1659. /// @param last Off-the-end iterator to the range.
  1660. /// @return Number of members that have been removed.
  1661. /// @see https://redis.io/commands/srem
  1662. template <typename Input>
  1663. long long srem(const StringView &key, Input first, Input last);
  1664. /// @brief Remove multiple members from set.
  1665. /// @param key Key where the set is stored.
  1666. /// @param il Initializer list of members to be removed.
  1667. /// @return Number of members that have been removed.
  1668. /// @see https://redis.io/commands/srem
  1669. template <typename T>
  1670. long long srem(const StringView &key, std::initializer_list<T> il) {
  1671. return srem(key, il.begin(), il.end());
  1672. }
  1673. /// @brief Scan members of the set matching the given pattern.
  1674. ///
  1675. /// Example:
  1676. /// @code{.cpp}
  1677. /// auto cursor = 0LL;
  1678. /// std::unordered_set<std::string> members;
  1679. /// while (true) {
  1680. /// cursor = redis.sscan("set", cursor, "pattern:*",
  1681. /// 10, std::inserter(members, members.begin()));
  1682. /// if (cursor == 0) {
  1683. /// break;
  1684. /// }
  1685. /// }
  1686. /// @endcode
  1687. /// @param key Key where the set is stored.
  1688. /// @param cursor Cursor.
  1689. /// @param pattern Pattern of fields to be scanned.
  1690. /// @param count A hint for how many fields to be scanned.
  1691. /// @param output Output iterator to the destination where the result is saved.
  1692. /// @return The cursor to be used for the next scan operation.
  1693. /// @see https://redis.io/commands/sscan
  1694. template <typename Output>
  1695. long long sscan(const StringView &key,
  1696. long long cursor,
  1697. const StringView &pattern,
  1698. long long count,
  1699. Output output);
  1700. /// @brief Scan members of the set matching the given pattern.
  1701. /// @param key Key where the set is stored.
  1702. /// @param cursor Cursor.
  1703. /// @param pattern Pattern of fields to be scanned.
  1704. /// @param output Output iterator to the destination where the result is saved.
  1705. /// @return The cursor to be used for the next scan operation.
  1706. /// @see https://redis.io/commands/sscan
  1707. template <typename Output>
  1708. long long sscan(const StringView &key,
  1709. long long cursor,
  1710. const StringView &pattern,
  1711. Output output);
  1712. /// @brief Scan all members of the given set.
  1713. /// @param key Key where the set is stored.
  1714. /// @param cursor Cursor.
  1715. /// @param count A hint for how many fields to be scanned.
  1716. /// @param output Output iterator to the destination where the result is saved.
  1717. /// @return The cursor to be used for the next scan operation.
  1718. /// @see https://redis.io/commands/sscan
  1719. template <typename Output>
  1720. long long sscan(const StringView &key,
  1721. long long cursor,
  1722. long long count,
  1723. Output output);
  1724. /// @brief Scan all members of the given set.
  1725. /// @param key Key where the set is stored.
  1726. /// @param cursor Cursor.
  1727. /// @param output Output iterator to the destination where the result is saved.
  1728. /// @return The cursor to be used for the next scan operation.
  1729. /// @see https://redis.io/commands/sscan
  1730. template <typename Output>
  1731. long long sscan(const StringView &key,
  1732. long long cursor,
  1733. Output output);
  1734. /// @brief Get the union between the first set and all successive sets.
  1735. /// @param first Iterator to the first set.
  1736. /// @param last Off-the-end iterator to the range.
  1737. /// @param output Output iterator to the destination where the result is saved.
  1738. /// @see https://redis.io/commands/sunion
  1739. // TODO: `void sunion(const StringView &key, Input first, Input last, Output output)` is better.
  1740. template <typename Input, typename Output>
  1741. void sunion(Input first, Input last, Output output);
  1742. /// @brief Get the union between the first set and all successive sets.
  1743. /// @param il Initializer list of sets.
  1744. /// @param output Output iterator to the destination where the result is saved.
  1745. /// @see https://redis.io/commands/sunion
  1746. template <typename T, typename Output>
  1747. void sunion(std::initializer_list<T> il, Output output) {
  1748. sunion(il.begin(), il.end(), output);
  1749. }
  1750. /// @brief Copy set stored at `key` to `destination`.
  1751. /// @param destination Key of the destination set.
  1752. /// @param key Key of the source set.
  1753. /// @return Number of members of the set.
  1754. /// @see https://redis.io/commands/sunionstore
  1755. long long sunionstore(const StringView &destination, const StringView &key);
  1756. /// @brief Same as `sunion`, except that it stores the result to another set.
  1757. /// @param destination Key of the destination set.
  1758. /// @param first Iterator to the first set.
  1759. /// @param last Off-the-end iterator to set range.
  1760. /// @return Number of members in the resulting set.
  1761. /// @see https://redis.io/commands/sunionstore
  1762. template <typename Input>
  1763. long long sunionstore(const StringView &destination, Input first, Input last);
  1764. /// @brief Same as `sunion`, except that it stores the result to another set.
  1765. /// @param destination Key of the destination set.
  1766. /// @param il Initializer list of sets.
  1767. /// @return Number of members in the resulting set.
  1768. /// @see https://redis.io/commands/sunionstore
  1769. template <typename T>
  1770. long long sunionstore(const StringView &destination, std::initializer_list<T> il) {
  1771. return sunionstore(destination, il.begin(), il.end());
  1772. }
  1773. // SORTED SET commands.
  1774. /// @brief Pop the member with highest score from sorted set in a blocking way.
  1775. /// @param key Key where the sorted set is stored.
  1776. /// @param timeout Timeout in seconds. 0 means block forever.
  1777. /// @return Key-member-score tuple with the highest score.
  1778. /// @note If sorted set is empty and timeout reaches, `bzpopmax` returns
  1779. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1780. /// @see `Redis::zpopmax`
  1781. /// @see https://redis.io/commands/bzpopmax
  1782. auto bzpopmax(const StringView &key, long long timeout)
  1783. -> Optional<std::tuple<std::string, std::string, double>>;
  1784. /// @brief Pop the member with highest score from sorted set in a blocking way.
  1785. /// @param key Key where the sorted set is stored.
  1786. /// @param timeout Timeout in seconds. 0 means block forever.
  1787. /// @return Key-member-score tuple with the highest score.
  1788. /// @note If sorted set is empty and timeout reaches, `bzpopmax` returns
  1789. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1790. /// @see `Redis::zpopmax`
  1791. /// @see https://redis.io/commands/bzpopmax
  1792. auto bzpopmax(const StringView &key,
  1793. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1794. -> Optional<std::tuple<std::string, std::string, double>>;
  1795. /// @brief Pop the member with highest score from multiple sorted set in a blocking way.
  1796. /// @param first Iterator to the first key.
  1797. /// @param last Off-the-end iterator to the key range.
  1798. /// @param timeout Timeout in seconds. 0 means block forever.
  1799. /// @return Key-member-score tuple with the higest score.
  1800. /// @note If all lists are empty and timeout reaches, `bzpopmax` returns
  1801. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1802. /// @see `Redis::zpopmax`
  1803. /// @see https://redis.io/commands/bzpopmax
  1804. template <typename Input>
  1805. auto bzpopmax(Input first, Input last, long long timeout)
  1806. -> Optional<std::tuple<std::string, std::string, double>>;
  1807. /// @brief Pop the member with highest score from multiple sorted set in a blocking way.
  1808. /// @param first Iterator to the first key.
  1809. /// @param last Off-the-end iterator to the key range.
  1810. /// @param timeout Timeout in seconds. 0 means block forever.
  1811. /// @return Key-member-score tuple with the higest score.
  1812. /// @note If all lists are empty and timeout reaches, `bzpopmax` returns
  1813. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1814. /// @see `Redis::zpopmax`
  1815. /// @see https://redis.io/commands/bzpopmax
  1816. template <typename Input>
  1817. auto bzpopmax(Input first,
  1818. Input last,
  1819. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1820. -> Optional<std::tuple<std::string, std::string, double>>;
  1821. /// @brief Pop the member with highest score from multiple sorted set in a blocking way.
  1822. /// @param il Initializer list of sorted sets.
  1823. /// @param timeout Timeout in seconds. 0 means block forever.
  1824. /// @return Key-member-score tuple with the higest score.
  1825. /// @note If all lists are empty and timeout reaches, `bzpopmax` returns
  1826. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1827. /// @see `Redis::zpopmax`
  1828. /// @see https://redis.io/commands/bzpopmax
  1829. template <typename T>
  1830. auto bzpopmax(std::initializer_list<T> il, long long timeout)
  1831. -> Optional<std::tuple<std::string, std::string, double>> {
  1832. return bzpopmax(il.begin(), il.end(), timeout);
  1833. }
  1834. /// @brief Pop the member with highest score from multiple sorted set in a blocking way.
  1835. /// @param il Initializer list of sorted sets.
  1836. /// @param timeout Timeout in seconds. 0 means block forever.
  1837. /// @return Key-member-score tuple with the higest score.
  1838. /// @note If all lists are empty and timeout reaches, `bzpopmax` returns
  1839. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1840. /// @see `Redis::zpopmax`
  1841. /// @see https://redis.io/commands/bzpopmax
  1842. template <typename T>
  1843. auto bzpopmax(std::initializer_list<T> il,
  1844. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1845. -> Optional<std::tuple<std::string, std::string, double>> {
  1846. return bzpopmax(il.begin(), il.end(), timeout);
  1847. }
  1848. /// @brief Pop the member with lowest score from sorted set in a blocking way.
  1849. /// @param key Key where the sorted set is stored.
  1850. /// @param timeout Timeout in seconds. 0 means block forever.
  1851. /// @return Key-member-score tuple with the lowest score.
  1852. /// @note If sorted set is empty and timeout reaches, `bzpopmin` returns
  1853. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1854. /// @see `Redis::zpopmin`
  1855. /// @see https://redis.io/commands/bzpopmin
  1856. auto bzpopmin(const StringView &key, long long timeout)
  1857. -> Optional<std::tuple<std::string, std::string, double>>;
  1858. /// @brief Pop the member with lowest score from sorted set in a blocking way.
  1859. /// @param key Key where the sorted set is stored.
  1860. /// @param timeout Timeout in seconds. 0 means block forever.
  1861. /// @return Key-member-score tuple with the lowest score.
  1862. /// @note If sorted set is empty and timeout reaches, `bzpopmin` returns
  1863. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1864. /// @see `Redis::zpopmin`
  1865. /// @see https://redis.io/commands/bzpopmin
  1866. auto bzpopmin(const StringView &key,
  1867. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1868. -> Optional<std::tuple<std::string, std::string, double>>;
  1869. /// @brief Pop the member with lowest score from multiple sorted set in a blocking way.
  1870. /// @param first Iterator to the first key.
  1871. /// @param last Off-the-end iterator to the key range.
  1872. /// @param timeout Timeout in seconds. 0 means block forever.
  1873. /// @return Key-member-score tuple with the lowest score.
  1874. /// @note If all lists are empty and timeout reaches, `bzpopmin` returns
  1875. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1876. /// @see `Redis::zpopmin`
  1877. /// @see https://redis.io/commands/bzpopmin
  1878. template <typename Input>
  1879. auto bzpopmin(Input first, Input last, long long timeout)
  1880. -> Optional<std::tuple<std::string, std::string, double>>;
  1881. /// @brief Pop the member with lowest score from multiple sorted set in a blocking way.
  1882. /// @param first Iterator to the first key.
  1883. /// @param last Off-the-end iterator to the key range.
  1884. /// @param timeout Timeout in seconds. 0 means block forever.
  1885. /// @return Key-member-score tuple with the lowest score.
  1886. /// @note If all lists are empty and timeout reaches, `bzpopmin` returns
  1887. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1888. /// @see `Redis::zpopmin`
  1889. /// @see https://redis.io/commands/bzpopmin
  1890. template <typename Input>
  1891. auto bzpopmin(Input first,
  1892. Input last,
  1893. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1894. -> Optional<std::tuple<std::string, std::string, double>>;
  1895. /// @brief Pop the member with lowest score from multiple sorted set in a blocking way.
  1896. /// @param il Initializer list of sorted sets.
  1897. /// @param timeout Timeout in seconds. 0 means block forever.
  1898. /// @return Key-member-score tuple with the lowest score.
  1899. /// @note If all lists are empty and timeout reaches, `bzpopmin` returns
  1900. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1901. /// @see `Redis::zpopmin`
  1902. /// @see https://redis.io/commands/bzpopmin
  1903. template <typename T>
  1904. auto bzpopmin(std::initializer_list<T> il, long long timeout)
  1905. -> Optional<std::tuple<std::string, std::string, double>> {
  1906. return bzpopmin(il.begin(), il.end(), timeout);
  1907. }
  1908. /// @brief Pop the member with lowest score from multiple sorted set in a blocking way.
  1909. /// @param il Initializer list of sorted sets.
  1910. /// @param timeout Timeout in seconds. 0 means block forever.
  1911. /// @return Key-member-score tuple with the lowest score.
  1912. /// @note If all lists are empty and timeout reaches, `bzpopmin` returns
  1913. /// `Optional<std::tuple<std::string, std::string, double>>{}` (`std::nullopt`).
  1914. /// @see `Redis::zpopmin`
  1915. /// @see https://redis.io/commands/bzpopmin
  1916. template <typename T>
  1917. auto bzpopmin(std::initializer_list<T> il,
  1918. const std::chrono::seconds &timeout = std::chrono::seconds{0})
  1919. -> Optional<std::tuple<std::string, std::string, double>> {
  1920. return bzpopmin(il.begin(), il.end(), timeout);
  1921. }
  1922. /// @brief Add or update a member with score to sorted set.
  1923. /// @param key Key where the sorted set is stored.
  1924. /// @param member Member to be added.
  1925. /// @param score Score of the member.
  1926. /// @param type Options for zadd command:
  1927. /// - UpdateType::EXIST: Add the member only if it already exists.
  1928. /// - UpdateType::NOT_EXIST: Add the member only if it does not exist.
  1929. /// - UpdateType::ALWAYS: Always add the member no matter whether it exists.
  1930. /// @param changed Whether change the return value from number of newly added member to
  1931. /// number of members changed (i.e. added and updated).
  1932. /// @return Number of added members or number of added and updated members depends on `changed`.
  1933. /// @note We don't support the INCR option, because in this case, the return value of zadd
  1934. /// command is NOT of type long long. However, you can always use the generic interface
  1935. /// to send zadd command with INCR option:
  1936. /// `auto score = redis.command<OptionalDouble>("ZADD", "key", "XX", "INCR", 10, "mem");`
  1937. /// @see `UpdateType`
  1938. /// @see https://redis.io/commands/zadd
  1939. long long zadd(const StringView &key,
  1940. const StringView &member,
  1941. double score,
  1942. UpdateType type = UpdateType::ALWAYS,
  1943. bool changed = false);
  1944. /// @brief Add or update multiple members with score to sorted set.
  1945. ///
  1946. /// Example:
  1947. /// @code{.cpp}
  1948. /// std::unordered_map<std::string, double> m = {{"m1", 1.2}, {"m2", 2.3}};
  1949. /// redis.zadd("zset", m.begin(), m.end());
  1950. /// @endcode
  1951. /// @param key Key where the sorted set is stored.
  1952. /// @param first Iterator to the first member-score pair.
  1953. /// @param last Off-the-end iterator to the member-score pairs range.
  1954. /// @param type Options for zadd command:
  1955. /// - UpdateType::EXIST: Add the member only if it already exists.
  1956. /// - UpdateType::NOT_EXIST: Add the member only if it does not exist.
  1957. /// - UpdateType::ALWAYS: Always add the member no matter whether it exists.
  1958. /// @param changed Whether change the return value from number of newly added member to
  1959. /// number of members changed (i.e. added and updated).
  1960. /// @return Number of added members or number of added and updated members depends on `changed`.
  1961. /// @note We don't support the INCR option, because in this case, the return value of zadd
  1962. /// command is NOT of type long long. However, you can always use the generic interface
  1963. /// to send zadd command with INCR option:
  1964. /// `auto score = redis.command<OptionalDouble>("ZADD", "key", "XX", "INCR", 10, "mem");`
  1965. /// @see `UpdateType`
  1966. /// @see https://redis.io/commands/zadd
  1967. template <typename Input>
  1968. long long zadd(const StringView &key,
  1969. Input first,
  1970. Input last,
  1971. UpdateType type = UpdateType::ALWAYS,
  1972. bool changed = false);
  1973. /// @brief Add or update multiple members with score to sorted set.
  1974. ///
  1975. /// Example:
  1976. /// @code{.cpp}
  1977. /// redis.zadd("zset", {std::make_pair("m1", 1.4), std::make_pair("m2", 2.3)});
  1978. /// @endcode
  1979. /// @param key Key where the sorted set is stored.
  1980. /// @param first Iterator to the first member-score pair.
  1981. /// @param last Off-the-end iterator to the member-score pairs range.
  1982. /// @param type Options for zadd command:
  1983. /// - UpdateType::EXIST: Add the member only if it already exists.
  1984. /// - UpdateType::NOT_EXIST: Add the member only if it does not exist.
  1985. /// - UpdateType::ALWAYS: Always add the member no matter whether it exists.
  1986. /// @param changed Whether change the return value from number of newly added member to
  1987. /// number of members changed (i.e. added and updated).
  1988. /// @return Number of added members or number of added and updated members depends on `changed`.
  1989. /// @note We don't support the INCR option, because in this case, the return value of zadd
  1990. /// command is NOT of type long long. However, you can always use the generic interface
  1991. /// to send zadd command with INCR option:
  1992. /// `auto score = redis.command<OptionalDouble>("ZADD", "key", "XX", "INCR", 10, "mem");`
  1993. /// @see `UpdateType`
  1994. /// @see https://redis.io/commands/zadd
  1995. template <typename T>
  1996. long long zadd(const StringView &key,
  1997. std::initializer_list<T> il,
  1998. UpdateType type = UpdateType::ALWAYS,
  1999. bool changed = false) {
  2000. return zadd(key, il.begin(), il.end(), type, changed);
  2001. }
  2002. /// @brief Get the number of members in the sorted set.
  2003. /// @param key Key where the sorted set is stored.
  2004. /// @return Number of members in the sorted set.
  2005. /// @see https://redis.io/commands/zcard
  2006. long long zcard(const StringView &key);
  2007. /// @brief Get the number of members with score between a min-max score range.
  2008. ///
  2009. /// Example:
  2010. /// @code{.cpp}
  2011. /// // Count members with score between (2.3, 5]
  2012. /// redis.zcount("zset", BoundedInterval<double>(2.3, 5, BoundType::LEFT_OPEN));
  2013. /// // Count members with score between [2.3, 5)
  2014. /// redis.zcount("zset", BoundedInterval<double>(2.3, 5, BoundType::RIGHT_OPEN));
  2015. /// // Count members with score between (2.3, 5)
  2016. /// redis.zcount("zset", BoundedInterval<double>(2.3, 5, BoundType::OPEN));
  2017. /// // Count members with score between [2.3, 5]
  2018. /// redis.zcount("zset", BoundedInterval<double>(2.3, 5, BoundType::CLOSED));
  2019. /// // Count members with score between [2.3, +inf)
  2020. /// redis.zcount("zset", LeftBoundedInterval<double>(2.3, BoundType::RIGHT_OPEN));
  2021. /// // Count members with score between (2.3, +inf)
  2022. /// redis.zcount("zset", LeftBoundedInterval<double>(2.3, BoundType::OPEN));
  2023. /// // Count members with score between (-inf, 5]
  2024. /// redis.zcount("zset", RightBoundedInterval<double>(5, BoundType::LEFT_OPEN));
  2025. /// // Count members with score between (-inf, 5)
  2026. /// redis.zcount("zset", RightBoundedInterval<double>(5, BoundType::OPEN));
  2027. /// // Count members with score between (-inf, +inf)
  2028. /// redis.zcount("zset", UnboundedInterval<double>{});
  2029. /// @endcode
  2030. /// @param key Key where the sorted set is stored.
  2031. /// @param interval The min-max score range.
  2032. /// @return Number of members with score between a min-max score range.
  2033. /// @see `BoundedInterval`
  2034. /// @see `LeftBoundedInterval`
  2035. /// @see `RightBoundedInterval`
  2036. /// @see `UnboundedInterval`
  2037. /// @see `BoundType`
  2038. /// @see https://redis.io/commands/zcount
  2039. // TODO: add a string version of Interval: zcount("key", "(2.3", "5").
  2040. template <typename Interval>
  2041. long long zcount(const StringView &key, const Interval &interval);
  2042. /// @brief Increment the score of given member.
  2043. /// @param key Key where the sorted set is stored.
  2044. /// @param increment Increment.
  2045. /// @param member Member.
  2046. /// @return The score of the member after the operation.
  2047. /// @see https://redis.io/commands/zincrby
  2048. double zincrby(const StringView &key, double increment, const StringView &member);
  2049. /// @brief Copy a sorted set to another one with the scores being multiplied by a factor.
  2050. /// @param destination Key of the destination sorted set.
  2051. /// @param key Key of the source sorted set.
  2052. /// @param weight Weight to be multiplied to the score of each member.
  2053. /// @return The number of members in the sorted set.
  2054. /// @note There's no aggregation type parameter for single key overload, since these 3 types
  2055. /// have the same effect.
  2056. /// @see `Redis::zunionstore`
  2057. /// @see https://redis.io/commands/zinterstore
  2058. long long zinterstore(const StringView &destination, const StringView &key, double weight);
  2059. /// @brief Get intersection of multiple sorted sets, and store the result to another one.
  2060. ///
  2061. /// Example:
  2062. /// @code{.cpp}
  2063. /// // Use the default weight, i.e. 1,
  2064. /// // and use the sum of the all scores as the score of the result:
  2065. /// std::vector<std::string> keys = {"k1", "k2", "k3"};
  2066. /// redis.zinterstore("destination", keys.begin(), keys.end());
  2067. /// // Each sorted set has a different weight,
  2068. /// // and the score of the result is the min of all scores.
  2069. /// std::vector<std::pair<std::string, double>> keys_with_weights = {{"k1", 1}, {"k2", 2}};
  2070. /// redis.zinterstore("destination", keys_with_weights.begin(),
  2071. /// keys_with_weights.end(), Aggregation::MIN);
  2072. /// // NOTE: `keys_with_weights` can also be of type `std::unordered_map<std::string, double>`.
  2073. /// // However, it will be slower than std::vector<std::pair<std::string, double>>, since we use
  2074. /// // `std::distance(first, last)` to calculate the *numkeys* parameter.
  2075. /// @endcode
  2076. /// @param destination Key of the destination sorted set.
  2077. /// @param first Iterator to the first sorted set (might with weight).
  2078. /// @param last Off-the-end iterator to the sorted set range.
  2079. /// @param type How the scores are aggregated.
  2080. /// - Aggregation::SUM: Score of a member is the sum of all scores.
  2081. /// - Aggregation::MIN: Score of a member is the min of all scores.
  2082. /// - Aggregation::MAX: Score of a member is the max of all scores.
  2083. /// @return The number of members in the resulting sorted set.
  2084. /// @note The score of each member can be multiplied by a factor, i.e. weight. If `Input` is an
  2085. /// iterator to a container of `std::string`, we use the default weight, i.e. 1, and send
  2086. /// *ZINTERSTORE dest numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]* command.
  2087. /// If `Input` is an iterator to a container of `std::pair<std::string, double>`,
  2088. /// i.e. key-weight pair, we send the command with the given weights:
  2089. /// *ZINTERSTORE dest numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]*.
  2090. /// See the *Example* part for examples on how to use this command.
  2091. /// @see `Redis::zunionstore`
  2092. /// @see https://redis.io/commands/zinterstore
  2093. template <typename Input>
  2094. long long zinterstore(const StringView &destination,
  2095. Input first,
  2096. Input last,
  2097. Aggregation type = Aggregation::SUM);
  2098. /// @brief Get intersection of multiple sorted sets, and store the result to another one.
  2099. ///
  2100. /// Example:
  2101. /// @code{.cpp}
  2102. /// // Use the default weight, i.e. 1,
  2103. /// // and use the sum of the all scores as the score of the result:
  2104. /// redis.zinterstore("destination", {"k1", "k2"});
  2105. /// // Each sorted set has a different weight,
  2106. /// // and the score of the result is the min of all scores.
  2107. /// redis.zinterstore("destination",
  2108. /// {std::make_pair("k1", 1), std::make_pair("k2", 2)}, Aggregation::MIN);
  2109. /// @endcode
  2110. /// @param destination Key of the destination sorted set.
  2111. /// @param il Initializer list of sorted set.
  2112. /// @param type How the scores are aggregated.
  2113. /// - Aggregation::SUM: Score of a member is the sum of all scores.
  2114. /// - Aggregation::MIN: Score of a member is the min of all scores.
  2115. /// - Aggregation::MAX: Score of a member is the max of all scores.
  2116. /// @return The number of members in the resulting sorted set.
  2117. /// @note The score of each member can be multiplied by a factor, i.e. weight. If `T` is
  2118. /// of type `std::string`, we use the default weight, i.e. 1, and send
  2119. /// *ZINTERSTORE dest numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]* command.
  2120. /// If `T` is of type `std::pair<std::string, double>`, i.e. key-weight pair,
  2121. /// we send the command with the given weights:
  2122. /// *ZINTERSTORE dest numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]*.
  2123. /// See the *Example* part for examples on how to use this command.
  2124. /// @see `Redis::zunionstore`
  2125. /// @see https://redis.io/commands/zinterstore
  2126. template <typename T>
  2127. long long zinterstore(const StringView &destination,
  2128. std::initializer_list<T> il,
  2129. Aggregation type = Aggregation::SUM) {
  2130. return zinterstore(destination, il.begin(), il.end(), type);
  2131. }
  2132. /// @brief Get the number of members between a min-max range in lexicographical order.
  2133. ///
  2134. /// Example:
  2135. /// @code{.cpp}
  2136. /// // Count members between (abc, abd]
  2137. /// redis.zlexcount("zset", BoundedInterval<std::string>("abc", "abd", BoundType::LEFT_OPEN));
  2138. /// // Count members between [abc, abd)
  2139. /// redis.zlexcount("zset", BoundedInterval<std::string>("abc", "abd", BoundType::RIGHT_OPEN));
  2140. /// // Count members between (abc, abd)
  2141. /// redis.zlexcount("zset", BoundedInterval<std::string>("abc", "abd", BoundType::OPEN));
  2142. /// // Count members between [abc, abd]
  2143. /// redis.zlexcount("zset", BoundedInterval<std::string>("abc", "abd", BoundType::CLOSED));
  2144. /// // Count members between [abc, +inf)
  2145. /// redis.zlexcount("zset", LeftBoundedInterval<std::string>("abc", BoundType::RIGHT_OPEN));
  2146. /// // Count members between (abc, +inf)
  2147. /// redis.zlexcount("zset", LeftBoundedInterval<std::string>("abc", BoundType::OPEN));
  2148. /// // Count members between (-inf, "abd"]
  2149. /// redis.zlexcount("zset", RightBoundedInterval<std::string>("abd", BoundType::LEFT_OPEN));
  2150. /// // Count members between (-inf, "abd")
  2151. /// redis.zlexcount("zset", RightBoundedInterval<std::string>("abd", BoundType::OPEN));
  2152. /// // Count members between (-inf, +inf)
  2153. /// redis.zlexcount("zset", UnboundedInterval<std::string>{});
  2154. /// @endcode
  2155. /// @param key Key where the sorted set is stored.
  2156. /// @param interval The min-max range in lexicographical order.
  2157. /// @return Number of members between a min-max range in lexicographical order.
  2158. /// @see `BoundedInterval`
  2159. /// @see `LeftBoundedInterval`
  2160. /// @see `RightBoundedInterval`
  2161. /// @see `UnboundedInterval`
  2162. /// @see `BoundType`
  2163. /// @see https://redis.io/commands/zlexcount
  2164. // TODO: add a string version of Interval: zlexcount("key", "(abc", "abd").
  2165. template <typename Interval>
  2166. long long zlexcount(const StringView &key, const Interval &interval);
  2167. /// @brief Pop the member with highest score from sorted set.
  2168. /// @param key Key where the sorted set is stored.
  2169. /// @return Member-score pair with the highest score.
  2170. /// @note If sorted set is empty `zpopmax` returns
  2171. /// `Optional<std::pair<std::string, double>>{}` (`std::nullopt`).
  2172. /// @see `Redis::bzpopmax`
  2173. /// @see https://redis.io/commands/zpopmax
  2174. Optional<std::pair<std::string, double>> zpopmax(const StringView &key);
  2175. /// @brief Pop multiple members with highest score from sorted set.
  2176. /// @param key Key where the sorted set is stored.
  2177. /// @param count Number of members to be popped.
  2178. /// @param output Output iterator to the destination where the result is saved.
  2179. /// @note The number of returned members might be less than `count`.
  2180. /// @see `Redis::bzpopmax`
  2181. /// @see https://redis.io/commands/zpopmax
  2182. template <typename Output>
  2183. void zpopmax(const StringView &key, long long count, Output output);
  2184. /// @brief Pop the member with lowest score from sorted set.
  2185. /// @param key Key where the sorted set is stored.
  2186. /// @return Member-score pair with the lowest score.
  2187. /// @note If sorted set is empty `zpopmin` returns
  2188. /// `Optional<std::pair<std::string, double>>{}` (`std::nullopt`).
  2189. /// @see `Redis::bzpopmin`
  2190. /// @see https://redis.io/commands/zpopmin
  2191. Optional<std::pair<std::string, double>> zpopmin(const StringView &key);
  2192. /// @brief Pop multiple members with lowest score from sorted set.
  2193. /// @param key Key where the sorted set is stored.
  2194. /// @param count Number of members to be popped.
  2195. /// @param output Output iterator to the destination where the result is saved.
  2196. /// @note The number of returned members might be less than `count`.
  2197. /// @see `Redis::bzpopmin`
  2198. /// @see https://redis.io/commands/zpopmin
  2199. template <typename Output>
  2200. void zpopmin(const StringView &key, long long count, Output output);
  2201. /// @brief Get a range of members by rank (ordered from lowest to highest).
  2202. ///
  2203. /// Example:
  2204. /// @code{.cpp}
  2205. /// // send *ZRANGE* command without the *WITHSCORES* option:
  2206. /// std::vector<std::string> result;
  2207. /// redis.zrange("zset", 0, -1, std::back_inserter(result));
  2208. /// // send command with *WITHSCORES* option:
  2209. /// std::vector<std::pair<std::string, double>> with_score;
  2210. /// redis.zrange("zset", 0, -1, std::back_inserter(with_score));
  2211. /// @endcode
  2212. /// @param key Key where the sorted set is stored.
  2213. /// @param start Start rank. Inclusive and can be negative.
  2214. /// @param stop Stop rank. Inclusive and can be negative.
  2215. /// @param output Output iterator to the destination where the result is saved.
  2216. /// @note This method can also return the score of each member. If `output` is an iterator
  2217. /// to a container of `std::string`, we send *ZRANGE key start stop* command.
  2218. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2219. /// we send *ZRANGE key start stop WITHSCORES* command. See the *Example* part on
  2220. /// how to use this method.
  2221. /// @see `Redis::zrevrange`
  2222. /// @see https://redis.io/commands/zrange
  2223. template <typename Output>
  2224. void zrange(const StringView &key, long long start, long long stop, Output output);
  2225. /// @brief Get a range of members by lexicographical order (from lowest to highest).
  2226. ///
  2227. /// Example:
  2228. /// @code{.cpp}
  2229. /// std::vector<std::string> result;
  2230. /// // Get members between [abc, abd].
  2231. /// redis.zrangebylex("zset", BoundedInterval<std::string>("abc", "abd", BoundType::CLOSED),
  2232. /// std::back_inserter(result));
  2233. /// @endcode
  2234. /// @param key Key where the sorted set is stored.
  2235. /// @param interval the min-max range by lexicographical order.
  2236. /// @param output Output iterator to the destination where the result is saved.
  2237. /// @note See `Redis::zlexcount`'s *Example* part for how to set `interval` parameter.
  2238. /// @see `Redis::zlexcount`
  2239. /// @see `BoundedInterval`
  2240. /// @see `LeftBoundedInterval`
  2241. /// @see `RightBoundedInterval`
  2242. /// @see `UnboundedInterval`
  2243. /// @see `BoundType`
  2244. /// @see `Redis::zrevrangebylex`
  2245. /// @see https://redis.io/commands/zrangebylex
  2246. template <typename Interval, typename Output>
  2247. void zrangebylex(const StringView &key, const Interval &interval, Output output);
  2248. /// @brief Get a range of members by lexicographical order (from lowest to highest).
  2249. ///
  2250. /// Example:
  2251. /// @code{.cpp}
  2252. /// std::vector<std::string> result;
  2253. /// // Limit the result to at most 5 members starting from 10.
  2254. /// LimitOptions opts;
  2255. /// opts.offset = 10;
  2256. /// opts.count = 5;
  2257. /// // Get members between [abc, abd].
  2258. /// redis.zrangebylex("zset", BoundedInterval<std::string>("abc", "abd", BoundType::CLOSED),
  2259. /// opts, std::back_inserter(result));
  2260. /// @endcode
  2261. /// @param key Key where the sorted set is stored.
  2262. /// @param interval the min-max range by lexicographical order.
  2263. /// @param opts Options to do pagination, i.e. *LIMIT offset count*.
  2264. /// @param output Output iterator to the destination where the result is saved.
  2265. /// @note See `Redis::zlexcount`'s *Example* part for how to set `interval` parameter.
  2266. /// @see `Redis::zlexcount`
  2267. /// @see `BoundedInterval`
  2268. /// @see `LeftBoundedInterval`
  2269. /// @see `RightBoundedInterval`
  2270. /// @see `UnboundedInterval`
  2271. /// @see `BoundType`
  2272. /// @see `LimitOptions`
  2273. /// @see `Redis::zrevrangebylex`
  2274. /// @see https://redis.io/commands/zrangebylex
  2275. template <typename Interval, typename Output>
  2276. void zrangebylex(const StringView &key,
  2277. const Interval &interval,
  2278. const LimitOptions &opts,
  2279. Output output);
  2280. /// @brief Get a range of members by score (ordered from lowest to highest).
  2281. ///
  2282. /// Example:
  2283. /// @code{.cpp}
  2284. /// // Send *ZRANGEBYSCORE* command without the *WITHSCORES* option:
  2285. /// std::vector<std::string> result;
  2286. /// // Get members whose score between (3, 6).
  2287. /// redis.zrangebyscore("zset", BoundedInterval<double>(3, 6, BoundType::OPEN),
  2288. /// std::back_inserter(result));
  2289. /// // Send command with *WITHSCORES* option:
  2290. /// std::vector<std::pair<std::string, double>> with_score;
  2291. /// // Get members whose score between [3, +inf).
  2292. /// redis.zrangebyscore("zset", LeftBoundedInterval<double>(3, BoundType::RIGHT_OPEN),
  2293. /// std::back_inserter(with_score));
  2294. /// @endcode
  2295. /// @param key Key where the sorted set is stored.
  2296. /// @param interval the min-max range by score.
  2297. /// @param output Output iterator to the destination where the result is saved.
  2298. /// @note This method can also return the score of each member. If `output` is an iterator
  2299. /// to a container of `std::string`, we send *ZRANGEBYSCORE key min max* command.
  2300. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2301. /// we send *ZRANGEBYSCORE key min max WITHSCORES* command. See the *Example* part on
  2302. /// how to use this method.
  2303. /// @note See `Redis::zcount`'s *Example* part for how to set the `interval` parameter.
  2304. /// @see `Redis::zrevrangebyscore`
  2305. /// @see https://redis.io/commands/zrangebyscore
  2306. template <typename Interval, typename Output>
  2307. void zrangebyscore(const StringView &key, const Interval &interval, Output output);
  2308. /// @brief Get a range of members by score (ordered from lowest to highest).
  2309. ///
  2310. /// Example:
  2311. /// @code{.cpp}
  2312. /// // Send *ZRANGEBYSCORE* command without the *WITHSCORES* option:
  2313. /// std::vector<std::string> result;
  2314. /// // Only return at most 5 members starting from 10.
  2315. /// LimitOptions opts;
  2316. /// opts.offset = 10;
  2317. /// opts.count = 5;
  2318. /// // Get members whose score between (3, 6).
  2319. /// redis.zrangebyscore("zset", BoundedInterval<double>(3, 6, BoundType::OPEN),
  2320. /// opts, std::back_inserter(result));
  2321. /// // Send command with *WITHSCORES* option:
  2322. /// std::vector<std::pair<std::string, double>> with_score;
  2323. /// // Get members whose score between [3, +inf).
  2324. /// redis.zrangebyscore("zset", LeftBoundedInterval<double>(3, BoundType::RIGHT_OPEN),
  2325. /// opts, std::back_inserter(with_score));
  2326. /// @endcode
  2327. /// @param key Key where the sorted set is stored.
  2328. /// @param interval the min-max range by score.
  2329. /// @param opts Options to do pagination, i.e. *LIMIT offset count*.
  2330. /// @param output Output iterator to the destination where the result is saved.
  2331. /// @note This method can also return the score of each member. If `output` is an iterator
  2332. /// to a container of `std::string`, we send *ZRANGEBYSCORE key min max* command.
  2333. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2334. /// we send *ZRANGEBYSCORE key min max WITHSCORES* command. See the *Example* part on
  2335. /// how to use this method.
  2336. /// @note See `Redis::zcount`'s *Example* part for how to set the `interval` parameter.
  2337. /// @see `Redis::zrevrangebyscore`
  2338. /// @see https://redis.io/commands/zrangebyscore
  2339. template <typename Interval, typename Output>
  2340. void zrangebyscore(const StringView &key,
  2341. const Interval &interval,
  2342. const LimitOptions &opts,
  2343. Output output);
  2344. /// @brief Get the rank (from low to high) of the given member in the sorted set.
  2345. /// @param key Key where the sorted set is stored.
  2346. /// @param member Member.
  2347. /// @return The rank of the given member.
  2348. /// @note If the member does not exist, `zrank` returns `OptionalLongLong{}` (`std::nullopt`).
  2349. /// @see https://redis.io/commands/zrank
  2350. OptionalLongLong zrank(const StringView &key, const StringView &member);
  2351. /// @brief Remove the given member from sorted set.
  2352. /// @param key Key where the sorted set is stored.
  2353. /// @param member Member to be removed.
  2354. /// @return Whether the member has been removed.
  2355. /// @retval 1 If the member exists, and has been removed.
  2356. /// @retval 0 If the member does not exist.
  2357. /// @see https://redis.io/commands/zrem
  2358. long long zrem(const StringView &key, const StringView &member);
  2359. /// @brief Remove multiple members from sorted set.
  2360. /// @param key Key where the sorted set is stored.
  2361. /// @param first Iterator to the first member.
  2362. /// @param last Off-the-end iterator to the given range.
  2363. /// @return Number of members that have been removed.
  2364. /// @see https://redis.io/commands/zrem
  2365. template <typename Input>
  2366. long long zrem(const StringView &key, Input first, Input last);
  2367. /// @brief Remove multiple members from sorted set.
  2368. /// @param key Key where the sorted set is stored.
  2369. /// @param il Initializer list of members to be removed.
  2370. /// @return Number of members that have been removed.
  2371. /// @see https://redis.io/commands/zrem
  2372. template <typename T>
  2373. long long zrem(const StringView &key, std::initializer_list<T> il) {
  2374. return zrem(key, il.begin(), il.end());
  2375. }
  2376. /// @brief Remove members in the given range of lexicographical order.
  2377. /// @param key Key where the sorted set is stored.
  2378. /// @param interval the min-max range by lexicographical order.
  2379. /// @note See `Redis::zlexcount`'s *Example* part for how to set `interval` parameter.
  2380. /// @return Number of members removed.
  2381. /// @see `Redis::zlexcount`
  2382. /// @see `BoundedInterval`
  2383. /// @see `LeftBoundedInterval`
  2384. /// @see `RightBoundedInterval`
  2385. /// @see `UnboundedInterval`
  2386. /// @see `BoundType`
  2387. /// @see https://redis.io/commands/zremrangebylex
  2388. template <typename Interval>
  2389. long long zremrangebylex(const StringView &key, const Interval &interval);
  2390. /// @brief Remove members in the given range ordered by rank.
  2391. /// @param key Key where the sorted set is stored.
  2392. /// @param start Start rank.
  2393. /// @param stop Stop rank.
  2394. /// @return Number of members removed.
  2395. /// @see https://redis.io/commands/zremrangebyrank
  2396. long long zremrangebyrank(const StringView &key, long long start, long long stop);
  2397. /// @brief Remove members in the given range ordered by score.
  2398. /// @param key Key where the sorted set is stored.
  2399. /// @param interval the min-max range by score.
  2400. /// @return Number of members removed.
  2401. /// @note See `Redis::zcount`'s *Example* part for how to set the `interval` parameter.
  2402. /// @see https://redis.io/commands/zremrangebyscore
  2403. template <typename Interval>
  2404. long long zremrangebyscore(const StringView &key, const Interval &interval);
  2405. /// @brief Get a range of members by rank (ordered from highest to lowest).
  2406. ///
  2407. /// Example:
  2408. /// @code{.cpp}
  2409. /// // send *ZREVRANGE* command without the *WITHSCORES* option:
  2410. /// std::vector<std::string> result;
  2411. /// redis.zrevrange("key", 0, -1, std::back_inserter(result));
  2412. /// // send command with *WITHSCORES* option:
  2413. /// std::vector<std::pair<std::string, double>> with_score;
  2414. /// redis.zrevrange("key", 0, -1, std::back_inserter(with_score));
  2415. /// @endcode
  2416. /// @param key Key where the sorted set is stored.
  2417. /// @param start Start rank. Inclusive and can be negative.
  2418. /// @param stop Stop rank. Inclusive and can be negative.
  2419. /// @param output Output iterator to the destination where the result is saved.
  2420. /// @note This method can also return the score of each member. If `output` is an iterator
  2421. /// to a container of `std::string`, we send *ZREVRANGE key start stop* command.
  2422. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2423. /// we send *ZREVRANGE key start stop WITHSCORES* command. See the *Example* part on
  2424. /// how to use this method.
  2425. /// @see `Redis::zrange`
  2426. /// @see https://redis.io/commands/zrevrange
  2427. template <typename Output>
  2428. void zrevrange(const StringView &key, long long start, long long stop, Output output);
  2429. /// @brief Get a range of members by lexicographical order (from highest to lowest).
  2430. ///
  2431. /// Example:
  2432. /// @code{.cpp}
  2433. /// std::vector<std::string> result;
  2434. /// // Get members between [abc, abd] in reverse order.
  2435. /// redis.zrevrangebylex("zset", BoundedInterval<std::string>("abc", "abd", BoundType::CLOSED),
  2436. /// std::back_inserter(result));
  2437. /// @endcode
  2438. /// @param key Key where the sorted set is stored.
  2439. /// @param interval the min-max range by lexicographical order.
  2440. /// @param output Output iterator to the destination where the result is saved.
  2441. /// @note See `Redis::zlexcount`'s *Example* part for how to set `interval` parameter.
  2442. /// @see `Redis::zlexcount`
  2443. /// @see `BoundedInterval`
  2444. /// @see `LeftBoundedInterval`
  2445. /// @see `RightBoundedInterval`
  2446. /// @see `UnboundedInterval`
  2447. /// @see `BoundType`
  2448. /// @see `Redis::zrangebylex`
  2449. /// @see https://redis.io/commands/zrevrangebylex
  2450. template <typename Interval, typename Output>
  2451. void zrevrangebylex(const StringView &key, const Interval &interval, Output output);
  2452. /// @brief Get a range of members by lexicographical order (from highest to lowest).
  2453. ///
  2454. /// Example:
  2455. /// @code{.cpp}
  2456. /// std::vector<std::string> result;
  2457. /// // Limit the result to at most 5 members starting from 10.
  2458. /// LimitOptions opts;
  2459. /// opts.offset = 10;
  2460. /// opts.count = 5;
  2461. /// // Get members between [abc, abd] in reverse order.
  2462. /// redis.zrevrangebylex("zset", BoundedInterval<std::string>("abc", "abd", BoundType::CLOSED),
  2463. /// opts, std::back_inserter(result));
  2464. /// @endcode
  2465. /// @param key Key where the sorted set is stored.
  2466. /// @param interval the min-max range by lexicographical order.
  2467. /// @param opts Options to do pagination, i.e. *LIMIT offset count*.
  2468. /// @param output Output iterator to the destination where the result is saved.
  2469. /// @note See `Redis::zlexcount`'s *Example* part for how to set `interval` parameter.
  2470. /// @see `Redis::zlexcount`
  2471. /// @see `BoundedInterval`
  2472. /// @see `LeftBoundedInterval`
  2473. /// @see `RightBoundedInterval`
  2474. /// @see `UnboundedInterval`
  2475. /// @see `BoundType`
  2476. /// @see `LimitOptions`
  2477. /// @see `Redis::zrangebylex`
  2478. /// @see https://redis.io/commands/zrevrangebylex
  2479. template <typename Interval, typename Output>
  2480. void zrevrangebylex(const StringView &key,
  2481. const Interval &interval,
  2482. const LimitOptions &opts,
  2483. Output output);
  2484. /// @brief Get a range of members by score (ordered from highest to lowest).
  2485. ///
  2486. /// Example:
  2487. /// @code{.cpp}
  2488. /// // Send *ZREVRANGEBYSCORE* command without the *WITHSCORES* option:
  2489. /// std::vector<std::string> result;
  2490. /// // Get members whose score between (3, 6) in reverse order.
  2491. /// redis.zrevrangebyscore("zset", BoundedInterval<double>(3, 6, BoundType::OPEN),
  2492. /// std::back_inserter(result));
  2493. /// // Send command with *WITHSCORES* option:
  2494. /// std::vector<std::pair<std::string, double>> with_score;
  2495. /// // Get members whose score between [3, +inf) in reverse order.
  2496. /// redis.zrevrangebyscore("zset", LeftBoundedInterval<double>(3, BoundType::RIGHT_OPEN),
  2497. /// std::back_inserter(with_score));
  2498. /// @endcode
  2499. /// @param key Key where the sorted set is stored.
  2500. /// @param interval the min-max range by score.
  2501. /// @param output Output iterator to the destination where the result is saved.
  2502. /// @note This method can also return the score of each member. If `output` is an iterator
  2503. /// to a container of `std::string`, we send *ZREVRANGEBYSCORE key min max* command.
  2504. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2505. /// we send *ZREVRANGEBYSCORE key min max WITHSCORES* command. See the *Example* part on
  2506. /// how to use this method.
  2507. /// @note See `Redis::zcount`'s *Example* part for how to set the `interval` parameter.
  2508. /// @see `Redis::zrangebyscore`
  2509. /// @see https://redis.io/commands/zrevrangebyscore
  2510. template <typename Interval, typename Output>
  2511. void zrevrangebyscore(const StringView &key, const Interval &interval, Output output);
  2512. /// @brief Get a range of members by score (ordered from highest to lowest).
  2513. ///
  2514. /// Example:
  2515. /// @code{.cpp}
  2516. /// // Send *ZREVRANGEBYSCORE* command without the *WITHSCORES* option:
  2517. /// std::vector<std::string> result;
  2518. /// // Only return at most 5 members starting from 10.
  2519. /// LimitOptions opts;
  2520. /// opts.offset = 10;
  2521. /// opts.count = 5;
  2522. /// // Get members whose score between (3, 6) in reverse order.
  2523. /// redis.zrevrangebyscore("zset", BoundedInterval<double>(3, 6, BoundType::OPEN),
  2524. /// opts, std::back_inserter(result));
  2525. /// // Send command with *WITHSCORES* option:
  2526. /// std::vector<std::pair<std::string, double>> with_score;
  2527. /// // Get members whose score between [3, +inf) in reverse order.
  2528. /// redis.zrevrangebyscore("zset", LeftBoundedInterval<double>(3, BoundType::RIGHT_OPEN),
  2529. /// opts, std::back_inserter(with_score));
  2530. /// @endcode
  2531. /// @param key Key where the sorted set is stored.
  2532. /// @param interval the min-max range by score.
  2533. /// @param opts Options to do pagination, i.e. *LIMIT offset count*.
  2534. /// @param output Output iterator to the destination where the result is saved.
  2535. /// @note This method can also return the score of each member. If `output` is an iterator
  2536. /// to a container of `std::string`, we send *ZREVRANGEBYSCORE key min max* command.
  2537. /// If it's an iterator to a container of `std::pair<std::string, double>`,
  2538. /// we send *ZREVRANGEBYSCORE key min max WITHSCORES* command. See the *Example* part on
  2539. /// how to use this method.
  2540. /// @note See `Redis::zcount`'s *Example* part for how to set the `interval` parameter.
  2541. /// @see `Redis::zrangebyscore`
  2542. /// @see https://redis.io/commands/zrevrangebyscore
  2543. template <typename Interval, typename Output>
  2544. void zrevrangebyscore(const StringView &key,
  2545. const Interval &interval,
  2546. const LimitOptions &opts,
  2547. Output output);
  2548. /// @brief Get the rank (from high to low) of the given member in the sorted set.
  2549. /// @param key Key where the sorted set is stored.
  2550. /// @param member Member.
  2551. /// @return The rank of the given member.
  2552. /// @note If the member does not exist, `zrevrank` returns `OptionalLongLong{}` (`std::nullopt`).
  2553. /// @see https://redis.io/commands/zrevrank
  2554. OptionalLongLong zrevrank(const StringView &key, const StringView &member);
  2555. /// @brief Scan members of the given sorted set matching the given pattern.
  2556. ///
  2557. /// Example:
  2558. /// @code{.cpp}
  2559. /// auto cursor = 0LL;
  2560. /// std::vector<std::pair<std::string, double>> members;
  2561. /// while (true) {
  2562. /// cursor = redis.zscan("zset", cursor, "pattern:*",
  2563. /// 10, std::back_inserter(members));
  2564. /// if (cursor == 0) {
  2565. /// break;
  2566. /// }
  2567. /// }
  2568. /// @endcode
  2569. /// @param key Key where the sorted set is stored.
  2570. /// @param cursor Cursor.
  2571. /// @param pattern Pattern of members to be scanned.
  2572. /// @param count A hint for how many members to be scanned.
  2573. /// @param output Output iterator to the destination where the result is saved.
  2574. /// @return The cursor to be used for the next scan operation.
  2575. /// @see https://redis.io/commands/zscan
  2576. template <typename Output>
  2577. long long zscan(const StringView &key,
  2578. long long cursor,
  2579. const StringView &pattern,
  2580. long long count,
  2581. Output output);
  2582. /// @brief Scan members of the given sorted set matching the given pattern.
  2583. /// @param key Key where the sorted set is stored.
  2584. /// @param cursor Cursor.
  2585. /// @param pattern Pattern of members to be scanned.
  2586. /// @param output Output iterator to the destination where the result is saved.
  2587. /// @return The cursor to be used for the next scan operation.
  2588. /// @see https://redis.io/commands/zscan
  2589. template <typename Output>
  2590. long long zscan(const StringView &key,
  2591. long long cursor,
  2592. const StringView &pattern,
  2593. Output output);
  2594. /// @brief Scan all members of the given sorted set.
  2595. /// @param key Key where the sorted set is stored.
  2596. /// @param cursor Cursor.
  2597. /// @param count A hint for how many members to be scanned.
  2598. /// @param output Output iterator to the destination where the result is saved.
  2599. /// @return The cursor to be used for the next scan operation.
  2600. /// @see https://redis.io/commands/zscan
  2601. template <typename Output>
  2602. long long zscan(const StringView &key,
  2603. long long cursor,
  2604. long long count,
  2605. Output output);
  2606. /// @brief Scan all members of the given sorted set.
  2607. /// @param key Key where the sorted set is stored.
  2608. /// @param cursor Cursor.
  2609. /// @param output Output iterator to the destination where the result is saved.
  2610. /// @return The cursor to be used for the next scan operation.
  2611. /// @see https://redis.io/commands/zscan
  2612. template <typename Output>
  2613. long long zscan(const StringView &key,
  2614. long long cursor,
  2615. Output output);
  2616. /// @brief Get the score of the given member.
  2617. /// @param key Key where the sorted set is stored.
  2618. /// @param member Member.
  2619. /// @return The score of the member.
  2620. /// @note If member does not exist, `zscore` returns `OptionalDouble{}` (`std::nullopt`).
  2621. /// @see https://redis.io/commands/zscore
  2622. OptionalDouble zscore(const StringView &key, const StringView &member);
  2623. /// @brief Copy a sorted set to another one with the scores being multiplied by a factor.
  2624. /// @param destination Key of the destination sorted set.
  2625. /// @param key Key of the source sorted set.
  2626. /// @param weight Weight to be multiplied to the score of each member.
  2627. /// @return The number of members in the sorted set.
  2628. /// @note There's no aggregation type parameter for single key overload, since these 3 types
  2629. /// have the same effect.
  2630. /// @see `Redis::zinterstore`
  2631. /// @see https://redis.io/commands/zinterstore
  2632. long long zunionstore(const StringView &destination, const StringView &key, double weight);
  2633. /// @brief Get union of multiple sorted sets, and store the result to another one.
  2634. ///
  2635. /// Example:
  2636. /// @code{.cpp}
  2637. /// // Use the default weight, i.e. 1,
  2638. /// // and use the sum of the all scores as the score of the result:
  2639. /// std::vector<std::string> keys = {"k1", "k2", "k3"};
  2640. /// redis.zunionstore("destination", keys.begin(), keys.end());
  2641. /// // Each sorted set has a different weight,
  2642. /// // and the score of the result is the min of all scores.
  2643. /// std::vector<std::pair<std::string, double>> keys_with_weights = {{"k1", 1}, {"k2", 2}};
  2644. /// redis.zunionstore("destination", keys_with_weights.begin(),
  2645. /// keys_with_weights.end(), Aggregation::MIN);
  2646. /// // NOTE: `keys_with_weights` can also be of type `std::unordered_map<std::string, double>`.
  2647. /// // However, it will be slower than std::vector<std::pair<std::string, double>>, since we use
  2648. /// // `std::distance(first, last)` to calculate the *numkeys* parameter.
  2649. /// @endcode
  2650. /// @param destination Key of the destination sorted set.
  2651. /// @param first Iterator to the first sorted set (might with weight).
  2652. /// @param last Off-the-end iterator to the sorted set range.
  2653. /// @param type How the scores are aggregated.
  2654. /// - Aggregation::SUM: Score of a member is the sum of all scores.
  2655. /// - Aggregation::MIN: Score of a member is the min of all scores.
  2656. /// - Aggregation::MAX: Score of a member is the max of all scores.
  2657. /// @return The number of members in the resulting sorted set.
  2658. /// @note The score of each member can be multiplied by a factor, i.e. weight. If `Input` is an
  2659. /// iterator to a container of `std::string`, we use the default weight, i.e. 1, and send
  2660. /// *ZUNIONSTORE dest numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]* command.
  2661. /// If `Input` is an iterator to a container of `std::pair<std::string, double>`,
  2662. /// i.e. key-weight pair, we send the command with the given weights:
  2663. /// *ZUNIONSTORE dest numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]*.
  2664. /// See the *Example* part for examples on how to use this command.
  2665. /// @see `Redis::zinterstore`
  2666. /// @see https://redis.io/commands/zunionstore
  2667. template <typename Input>
  2668. long long zunionstore(const StringView &destination,
  2669. Input first,
  2670. Input last,
  2671. Aggregation type = Aggregation::SUM);
  2672. /// @brief Get union of multiple sorted sets, and store the result to another one.
  2673. ///
  2674. /// Example:
  2675. /// @code{.cpp}
  2676. /// // Use the default weight, i.e. 1,
  2677. /// // and use the sum of the all scores as the score of the result:
  2678. /// redis.zunionstore("destination", {"k1", "k2"});
  2679. /// // Each sorted set has a different weight,
  2680. /// // and the score of the result is the min of all scores.
  2681. /// redis.zunionstore("destination",
  2682. /// {std::make_pair("k1", 1), std::make_pair("k2", 2)}, Aggregation::MIN);
  2683. /// @endcode
  2684. /// @param destination Key of the destination sorted set.
  2685. /// @param il Initializer list of sorted set.
  2686. /// @param type How the scores are aggregated.
  2687. /// - Aggregation::SUM: Score of a member is the sum of all scores.
  2688. /// - Aggregation::MIN: Score of a member is the min of all scores.
  2689. /// - Aggregation::MAX: Score of a member is the max of all scores.
  2690. /// @return The number of members in the resulting sorted set.
  2691. /// @note The score of each member can be multiplied by a factor, i.e. weight. If `T` is
  2692. /// of type `std::string`, we use the default weight, i.e. 1, and send
  2693. /// *ZUNIONSTORE dest numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]* command.
  2694. /// If `T` is of type `std::pair<std::string, double>`, i.e. key-weight pair,
  2695. /// we send the command with the given weights:
  2696. /// *ZUNIONSTORE dest numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]*.
  2697. /// See the *Example* part for examples on how to use this command.
  2698. /// @see `Redis::zinterstore`
  2699. /// @see https://redis.io/commands/zunionstore
  2700. template <typename T>
  2701. long long zunionstore(const StringView &destination,
  2702. std::initializer_list<T> il,
  2703. Aggregation type = Aggregation::SUM) {
  2704. return zunionstore(destination, il.begin(), il.end(), type);
  2705. }
  2706. // HYPERLOGLOG commands.
  2707. /// @brief Add the given element to a hyperloglog.
  2708. /// @param key Key of the hyperloglog.
  2709. /// @param element Element to be added.
  2710. /// @return Whether any of hyperloglog's internal register has been altered.
  2711. /// @retval true If at least one internal register has been altered.
  2712. /// @retval false If none of internal registers has been altered.
  2713. /// @note When `pfadd` returns false, it does not mean that this method failed to add
  2714. /// an element to the hyperloglog. Instead it means that the internal registers
  2715. /// were not altered. If `pfadd` fails, it will throw an exception of `Exception` type.
  2716. /// @see https://redis.io/commands/pfadd
  2717. bool pfadd(const StringView &key, const StringView &element);
  2718. /// @brief Add the given elements to a hyperloglog.
  2719. /// @param key Key of the hyperloglog.
  2720. /// @param first Iterator to the first element.
  2721. /// @param last Off-the-end iterator to the given range.
  2722. /// @return Whether any of hyperloglog's internal register has been altered.
  2723. /// @retval true If at least one internal register has been altered.
  2724. /// @retval false If none of internal registers has been altered.
  2725. /// @note When `pfadd` returns false, it does not mean that this method failed to add
  2726. /// an element to the hyperloglog. Instead it means that the internal registers
  2727. /// were not altered. If `pfadd` fails, it will throw an exception of `Exception` type.
  2728. /// @see https://redis.io/commands/pfadd
  2729. template <typename Input>
  2730. bool pfadd(const StringView &key, Input first, Input last);
  2731. /// @brief Add the given elements to a hyperloglog.
  2732. /// @param key Key of the hyperloglog.
  2733. /// @param il Initializer list of elements to be added.
  2734. /// @return Whether any of hyperloglog's internal register has been altered.
  2735. /// @retval true If at least one internal register has been altered.
  2736. /// @retval false If none of internal registers has been altered.
  2737. /// @note When `pfadd` returns false, it does not mean that this method failed to add
  2738. /// an element to the hyperloglog. Instead it means that the internal registers
  2739. /// were not altered. If `pfadd` fails, it will throw an exception of `Exception` type.
  2740. /// @see https://redis.io/commands/pfadd
  2741. template <typename T>
  2742. bool pfadd(const StringView &key, std::initializer_list<T> il) {
  2743. return pfadd(key, il.begin(), il.end());
  2744. }
  2745. long long pfcount(const StringView &key);
  2746. template <typename Input>
  2747. long long pfcount(Input first, Input last);
  2748. template <typename T>
  2749. long long pfcount(std::initializer_list<T> il) {
  2750. return pfcount(il.begin(), il.end());
  2751. }
  2752. void pfmerge(const StringView &destination, const StringView &key);
  2753. template <typename Input>
  2754. void pfmerge(const StringView &destination, Input first, Input last);
  2755. template <typename T>
  2756. void pfmerge(const StringView &destination, std::initializer_list<T> il) {
  2757. pfmerge(destination, il.begin(), il.end());
  2758. }
  2759. // GEO commands.
  2760. long long geoadd(const StringView &key,
  2761. const std::tuple<StringView, double, double> &member);
  2762. template <typename Input>
  2763. long long geoadd(const StringView &key,
  2764. Input first,
  2765. Input last);
  2766. template <typename T>
  2767. long long geoadd(const StringView &key,
  2768. std::initializer_list<T> il) {
  2769. return geoadd(key, il.begin(), il.end());
  2770. }
  2771. OptionalDouble geodist(const StringView &key,
  2772. const StringView &member1,
  2773. const StringView &member2,
  2774. GeoUnit unit = GeoUnit::M);
  2775. OptionalString geohash(const StringView &key, const StringView &member);
  2776. template <typename Input, typename Output>
  2777. void geohash(const StringView &key, Input first, Input last, Output output);
  2778. template <typename T, typename Output>
  2779. void geohash(const StringView &key, std::initializer_list<T> il, Output output) {
  2780. geohash(key, il.begin(), il.end(), output);
  2781. }
  2782. Optional<std::pair<double, double>> geopos(const StringView &key, const StringView &member);
  2783. template <typename Input, typename Output>
  2784. void geopos(const StringView &key, Input first, Input last, Output output);
  2785. template <typename T, typename Output>
  2786. void geopos(const StringView &key, std::initializer_list<T> il, Output output) {
  2787. geopos(key, il.begin(), il.end(), output);
  2788. }
  2789. // TODO:
  2790. // 1. since we have different overloads for georadius and georadius-store,
  2791. // we might use the GEORADIUS_RO command in the future.
  2792. // 2. there're too many parameters for this method, we might refactor it.
  2793. /// @brief Get members in geo range, i.e. a circle, and store them in a sorted set.
  2794. /// @param key Key of the GEO set.
  2795. /// @param loc Location encoded with <longitude, latitude> pair.
  2796. /// @param radius Radius of the range.
  2797. /// @param unit Radius unit.
  2798. /// @param destination Key of the destination sorted set.
  2799. /// @param store_dist Whether store distance info instead of geo info to destination.
  2800. /// @param count Limit the first N members.
  2801. /// @return Number of members stored in destination.
  2802. /// @note Before Redis 6.2.6, if key does not exist, returns `OptionalLongLong{}` (`std::nullopt`).
  2803. /// Since Redis 6.2.6, if key does not exist, returns 0.
  2804. /// @see `GeoUnit`
  2805. /// @see `Redis::georadiusbymember`
  2806. /// @see https://redis.io/commands/georadius
  2807. OptionalLongLong georadius(const StringView &key,
  2808. const std::pair<double, double> &loc,
  2809. double radius,
  2810. GeoUnit unit,
  2811. const StringView &destination,
  2812. bool store_dist,
  2813. long long count);
  2814. // If *output* is an iterator of a container of string, we send *GEORADIUS* command
  2815. // without any options and only get the members in the specified geo range.
  2816. // If *output* is an iterator of a container of a tuple, the type of the tuple decides
  2817. // options we send with the *GEORADIUS* command. If the tuple has an element of type
  2818. // double, we send the *WITHDIST* option. If it has an element of type string, we send
  2819. // the *WITHHASH* option. If it has an element of type pair<double, double>, we send
  2820. // the *WITHCOORD* option. For example:
  2821. //
  2822. // The following code only gets the members in range, i.e. without any option.
  2823. //
  2824. // vector<string> members;
  2825. // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
  2826. // back_inserter(members))
  2827. //
  2828. // The following code sends the command with *WITHDIST* option.
  2829. //
  2830. // vector<tuple<string, double>> with_dist;
  2831. // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
  2832. // back_inserter(with_dist))
  2833. //
  2834. // The following code sends the command with *WITHDIST* and *WITHHASH* options.
  2835. //
  2836. // vector<tuple<string, double, string>> with_dist_hash;
  2837. // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
  2838. // back_inserter(with_dist_hash))
  2839. //
  2840. // The following code sends the command with *WITHDIST*, *WITHCOORD* and *WITHHASH* options.
  2841. //
  2842. // vector<tuple<string, double, pair<double, double>, string>> with_dist_coord_hash;
  2843. // redis.georadius("key", make_pair(10.1, 10.2), 10, GeoUnit::KM, 10, true,
  2844. // back_inserter(with_dist_coord_hash))
  2845. //
  2846. // This also applies to *GEORADIUSBYMEMBER*.
  2847. template <typename Output>
  2848. void georadius(const StringView &key,
  2849. const std::pair<double, double> &loc,
  2850. double radius,
  2851. GeoUnit unit,
  2852. long long count,
  2853. bool asc,
  2854. Output output);
  2855. /// @brief Get members in geo range, i.e. a circle, and store them in a sorted set.
  2856. /// @param key Key of the GEO set.
  2857. /// @param member Member which is the center of the circle.
  2858. /// @param radius Radius of the range.
  2859. /// @param unit Radius unit.
  2860. /// @param destination Key of the destination sorted set.
  2861. /// @param store_dist Whether store distance info instead of geo info to destination.
  2862. /// @param count Limit the first N members.
  2863. /// @return Number of members stored in destination.
  2864. /// @note Before Redis 6.2.6, if key does not exist, returns `OptionalLongLong{}` (`std::nullopt`).
  2865. /// Since Redis 6.2.6, if key does not exist, returns 0.
  2866. /// @note If member does not exist, throw an `ReplyError`.
  2867. /// @see `GeoUnit`
  2868. /// @see `Redis::georadius`
  2869. /// @see https://redis.io/commands/georadiusbymember
  2870. OptionalLongLong georadiusbymember(const StringView &key,
  2871. const StringView &member,
  2872. double radius,
  2873. GeoUnit unit,
  2874. const StringView &destination,
  2875. bool store_dist,
  2876. long long count);
  2877. // See comments on *GEORADIUS*.
  2878. template <typename Output>
  2879. void georadiusbymember(const StringView &key,
  2880. const StringView &member,
  2881. double radius,
  2882. GeoUnit unit,
  2883. long long count,
  2884. bool asc,
  2885. Output output);
  2886. // SCRIPTING commands.
  2887. template <typename Result, typename Keys, typename Args>
  2888. Result eval(const StringView &script,
  2889. Keys keys_first,
  2890. Keys keys_last,
  2891. Args args_first,
  2892. Args args_last);
  2893. template <typename Result>
  2894. Result eval(const StringView &script,
  2895. std::initializer_list<StringView> keys,
  2896. std::initializer_list<StringView> args);
  2897. template <typename Keys, typename Args, typename Output>
  2898. void eval(const StringView &script,
  2899. Keys keys_first,
  2900. Keys keys_last,
  2901. Args args_first,
  2902. Args args_last,
  2903. Output output);
  2904. template <typename Output>
  2905. void eval(const StringView &script,
  2906. std::initializer_list<StringView> keys,
  2907. std::initializer_list<StringView> args,
  2908. Output output);
  2909. template <typename Result, typename Keys, typename Args>
  2910. Result evalsha(const StringView &script,
  2911. Keys keys_first,
  2912. Keys keys_last,
  2913. Args args_first,
  2914. Args args_last);
  2915. template <typename Result>
  2916. Result evalsha(const StringView &script,
  2917. std::initializer_list<StringView> keys,
  2918. std::initializer_list<StringView> args);
  2919. template <typename Keys, typename Args, typename Output>
  2920. void evalsha(const StringView &script,
  2921. Keys keys_first,
  2922. Keys keys_last,
  2923. Args args_first,
  2924. Args args_last,
  2925. Output output);
  2926. template <typename Output>
  2927. void evalsha(const StringView &script,
  2928. std::initializer_list<StringView> keys,
  2929. std::initializer_list<StringView> args,
  2930. Output output);
  2931. /// @brief Check if the given script exists.
  2932. /// @param sha1 SHA1 digest of the script.
  2933. /// @return Whether the script exists.
  2934. /// @retval true If the script exists.
  2935. /// @retval false If the script does not exist.
  2936. /// @see https://redis.io/commands/script-exists
  2937. bool script_exists(const StringView &sha1);
  2938. template <typename Input, typename Output>
  2939. void script_exists(Input first, Input last, Output output);
  2940. template <typename T, typename Output>
  2941. void script_exists(std::initializer_list<T> il, Output output) {
  2942. script_exists(il.begin(), il.end(), output);
  2943. }
  2944. void script_flush();
  2945. void script_kill();
  2946. std::string script_load(const StringView &script);
  2947. // PUBSUB commands.
  2948. long long publish(const StringView &channel, const StringView &message);
  2949. // Transaction commands.
  2950. void watch(const StringView &key);
  2951. template <typename Input>
  2952. void watch(Input first, Input last);
  2953. template <typename T>
  2954. void watch(std::initializer_list<T> il) {
  2955. watch(il.begin(), il.end());
  2956. }
  2957. void unwatch();
  2958. // Stream commands.
  2959. long long xack(const StringView &key, const StringView &group, const StringView &id);
  2960. template <typename Input>
  2961. long long xack(const StringView &key, const StringView &group, Input first, Input last);
  2962. template <typename T>
  2963. long long xack(const StringView &key, const StringView &group, std::initializer_list<T> il) {
  2964. return xack(key, group, il.begin(), il.end());
  2965. }
  2966. template <typename Input>
  2967. std::string xadd(const StringView &key, const StringView &id, Input first, Input last);
  2968. template <typename T>
  2969. std::string xadd(const StringView &key, const StringView &id, std::initializer_list<T> il) {
  2970. return xadd(key, id, il.begin(), il.end());
  2971. }
  2972. template <typename Input>
  2973. std::string xadd(const StringView &key,
  2974. const StringView &id,
  2975. Input first,
  2976. Input last,
  2977. long long count,
  2978. bool approx = true);
  2979. template <typename T>
  2980. std::string xadd(const StringView &key,
  2981. const StringView &id,
  2982. std::initializer_list<T> il,
  2983. long long count,
  2984. bool approx = true) {
  2985. return xadd(key, id, il.begin(), il.end(), count, approx);
  2986. }
  2987. template <typename Output>
  2988. void xclaim(const StringView &key,
  2989. const StringView &group,
  2990. const StringView &consumer,
  2991. const std::chrono::milliseconds &min_idle_time,
  2992. const StringView &id,
  2993. Output output);
  2994. template <typename Input, typename Output>
  2995. void xclaim(const StringView &key,
  2996. const StringView &group,
  2997. const StringView &consumer,
  2998. const std::chrono::milliseconds &min_idle_time,
  2999. Input first,
  3000. Input last,
  3001. Output output);
  3002. template <typename T, typename Output>
  3003. void xclaim(const StringView &key,
  3004. const StringView &group,
  3005. const StringView &consumer,
  3006. const std::chrono::milliseconds &min_idle_time,
  3007. std::initializer_list<T> il,
  3008. Output output) {
  3009. xclaim(key, group, consumer, min_idle_time, il.begin(), il.end(), output);
  3010. }
  3011. long long xdel(const StringView &key, const StringView &id);
  3012. template <typename Input>
  3013. long long xdel(const StringView &key, Input first, Input last);
  3014. template <typename T>
  3015. long long xdel(const StringView &key, std::initializer_list<T> il) {
  3016. return xdel(key, il.begin(), il.end());
  3017. }
  3018. void xgroup_create(const StringView &key,
  3019. const StringView &group,
  3020. const StringView &id,
  3021. bool mkstream = false);
  3022. void xgroup_setid(const StringView &key, const StringView &group, const StringView &id);
  3023. long long xgroup_destroy(const StringView &key, const StringView &group);
  3024. long long xgroup_delconsumer(const StringView &key,
  3025. const StringView &group,
  3026. const StringView &consumer);
  3027. long long xlen(const StringView &key);
  3028. template <typename Output>
  3029. auto xpending(const StringView &key, const StringView &group, Output output)
  3030. -> std::tuple<long long, OptionalString, OptionalString>;
  3031. template <typename Output>
  3032. void xpending(const StringView &key,
  3033. const StringView &group,
  3034. const StringView &start,
  3035. const StringView &end,
  3036. long long count,
  3037. Output output);
  3038. template <typename Output>
  3039. void xpending(const StringView &key,
  3040. const StringView &group,
  3041. const StringView &start,
  3042. const StringView &end,
  3043. long long count,
  3044. const StringView &consumer,
  3045. Output output);
  3046. template <typename Output>
  3047. void xrange(const StringView &key,
  3048. const StringView &start,
  3049. const StringView &end,
  3050. Output output);
  3051. template <typename Output>
  3052. void xrange(const StringView &key,
  3053. const StringView &start,
  3054. const StringView &end,
  3055. long long count,
  3056. Output output);
  3057. template <typename Output>
  3058. void xread(const StringView &key,
  3059. const StringView &id,
  3060. long long count,
  3061. Output output);
  3062. template <typename Output>
  3063. void xread(const StringView &key,
  3064. const StringView &id,
  3065. Output output) {
  3066. xread(key, id, 0, output);
  3067. }
  3068. template <typename Input, typename Output>
  3069. auto xread(Input first, Input last, long long count, Output output)
  3070. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
  3071. template <typename Input, typename Output>
  3072. auto xread(Input first, Input last, Output output)
  3073. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3074. xread(first ,last, 0, output);
  3075. }
  3076. template <typename Output>
  3077. void xread(const StringView &key,
  3078. const StringView &id,
  3079. const std::chrono::milliseconds &timeout,
  3080. long long count,
  3081. Output output);
  3082. template <typename Output>
  3083. void xread(const StringView &key,
  3084. const StringView &id,
  3085. const std::chrono::milliseconds &timeout,
  3086. Output output) {
  3087. xread(key, id, timeout, 0, output);
  3088. }
  3089. template <typename Input, typename Output>
  3090. auto xread(Input first,
  3091. Input last,
  3092. const std::chrono::milliseconds &timeout,
  3093. long long count,
  3094. Output output)
  3095. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
  3096. template <typename Input, typename Output>
  3097. auto xread(Input first,
  3098. Input last,
  3099. const std::chrono::milliseconds &timeout,
  3100. Output output)
  3101. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3102. xread(first, last, timeout, 0, output);
  3103. }
  3104. template <typename Output>
  3105. void xreadgroup(const StringView &group,
  3106. const StringView &consumer,
  3107. const StringView &key,
  3108. const StringView &id,
  3109. long long count,
  3110. bool noack,
  3111. Output output);
  3112. template <typename Output>
  3113. void xreadgroup(const StringView &group,
  3114. const StringView &consumer,
  3115. const StringView &key,
  3116. const StringView &id,
  3117. long long count,
  3118. Output output) {
  3119. xreadgroup(group, consumer, key, id, count, false, output);
  3120. }
  3121. template <typename Output>
  3122. void xreadgroup(const StringView &group,
  3123. const StringView &consumer,
  3124. const StringView &key,
  3125. const StringView &id,
  3126. Output output) {
  3127. xreadgroup(group, consumer, key, id, 0, false, output);
  3128. }
  3129. template <typename Input, typename Output>
  3130. auto xreadgroup(const StringView &group,
  3131. const StringView &consumer,
  3132. Input first,
  3133. Input last,
  3134. long long count,
  3135. bool noack,
  3136. Output output)
  3137. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
  3138. template <typename Input, typename Output>
  3139. auto xreadgroup(const StringView &group,
  3140. const StringView &consumer,
  3141. Input first,
  3142. Input last,
  3143. long long count,
  3144. Output output)
  3145. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3146. xreadgroup(group, consumer, first ,last, count, false, output);
  3147. }
  3148. template <typename Input, typename Output>
  3149. auto xreadgroup(const StringView &group,
  3150. const StringView &consumer,
  3151. Input first,
  3152. Input last,
  3153. Output output)
  3154. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3155. xreadgroup(group, consumer, first ,last, 0, false, output);
  3156. }
  3157. template <typename Output>
  3158. void xreadgroup(const StringView &group,
  3159. const StringView &consumer,
  3160. const StringView &key,
  3161. const StringView &id,
  3162. const std::chrono::milliseconds &timeout,
  3163. long long count,
  3164. bool noack,
  3165. Output output);
  3166. template <typename Output>
  3167. void xreadgroup(const StringView &group,
  3168. const StringView &consumer,
  3169. const StringView &key,
  3170. const StringView &id,
  3171. const std::chrono::milliseconds &timeout,
  3172. long long count,
  3173. Output output) {
  3174. xreadgroup(group, consumer, key, id, timeout, count, false, output);
  3175. }
  3176. template <typename Output>
  3177. void xreadgroup(const StringView &group,
  3178. const StringView &consumer,
  3179. const StringView &key,
  3180. const StringView &id,
  3181. const std::chrono::milliseconds &timeout,
  3182. Output output) {
  3183. xreadgroup(group, consumer, key, id, timeout, 0, false, output);
  3184. }
  3185. template <typename Input, typename Output>
  3186. auto xreadgroup(const StringView &group,
  3187. const StringView &consumer,
  3188. Input first,
  3189. Input last,
  3190. const std::chrono::milliseconds &timeout,
  3191. long long count,
  3192. bool noack,
  3193. Output output)
  3194. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type;
  3195. template <typename Input, typename Output>
  3196. auto xreadgroup(const StringView &group,
  3197. const StringView &consumer,
  3198. Input first,
  3199. Input last,
  3200. const std::chrono::milliseconds &timeout,
  3201. long long count,
  3202. Output output)
  3203. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3204. xreadgroup(group, consumer, first, last, timeout, count, false, output);
  3205. }
  3206. template <typename Input, typename Output>
  3207. auto xreadgroup(const StringView &group,
  3208. const StringView &consumer,
  3209. Input first,
  3210. Input last,
  3211. const std::chrono::milliseconds &timeout,
  3212. Output output)
  3213. -> typename std::enable_if<!std::is_convertible<Input, StringView>::value>::type {
  3214. xreadgroup(group, consumer, first, last, timeout, 0, false, output);
  3215. }
  3216. template <typename Output>
  3217. void xrevrange(const StringView &key,
  3218. const StringView &end,
  3219. const StringView &start,
  3220. Output output);
  3221. template <typename Output>
  3222. void xrevrange(const StringView &key,
  3223. const StringView &end,
  3224. const StringView &start,
  3225. long long count,
  3226. Output output);
  3227. long long xtrim(const StringView &key, long long count, bool approx = true);
  3228. private:
  3229. template <typename Impl>
  3230. friend class QueuedRedis;
  3231. friend class RedisCluster;
  3232. // For internal use.
  3233. explicit Redis(const GuardedConnectionSPtr &connection);
  3234. template <std::size_t ...Is, typename ...Args>
  3235. ReplyUPtr _command(const StringView &cmd_name, const IndexSequence<Is...> &, Args &&...args) {
  3236. return command(cmd_name, NthValue<Is>(std::forward<Args>(args)...)...);
  3237. }
  3238. template <typename Cmd, typename ...Args>
  3239. ReplyUPtr _command(Connection &connection, Cmd cmd, Args &&...args);
  3240. template <typename Cmd, typename ...Args>
  3241. ReplyUPtr _score_command(std::true_type, Cmd cmd, Args &&... args);
  3242. template <typename Cmd, typename ...Args>
  3243. ReplyUPtr _score_command(std::false_type, Cmd cmd, Args &&... args);
  3244. template <typename Output, typename Cmd, typename ...Args>
  3245. ReplyUPtr _score_command(Cmd cmd, Args &&... args);
  3246. // Pool Mode.
  3247. // Public constructors create a *Redis* instance with a pool.
  3248. // In this case, *_connection* is a null pointer, and is never used.
  3249. ConnectionPoolSPtr _pool;
  3250. // Single Connection Mode.
  3251. // Private constructor creates a *Redis* instance with a single connection.
  3252. // This is used when we create Transaction, Pipeline and Subscriber.
  3253. // In this case, *_pool* is empty, and is never used.
  3254. GuardedConnectionSPtr _connection;
  3255. };
  3256. }
  3257. }
  3258. #include "redis.hpp"
  3259. #endif // end SEWENEW_REDISPLUSPLUS_REDIS_H