1 /*
2  * Hunt - A redis client library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11  
12 module hunt.redis.commands.MultiKeyCommands;
13 
14 import hunt.redis.BitOP;
15 import hunt.redis.StreamEntryID;
16 import hunt.redis.RedisPubSub;
17 import hunt.redis.ScanParams;
18 import hunt.redis.ScanResult;
19 import hunt.redis.SortingParams;
20 import hunt.redis.StreamEntry;
21 import hunt.redis.ZParams;
22 
23 import hunt.collection.List;
24 import hunt.collection.Map;
25 import hunt.collection.Set;
26 import hunt.Long;
27 
28 /**
29  * 
30  */
31 interface MultiKeyCommands {
32     Long del(string[] keys...);
33 
34     Long unlink(string[] keys...);
35 
36     Long exists(string[] keys...);
37 
38     List!(string) blpop(int timeout, string[] keys...);
39 
40     List!(string) brpop(int timeout, string[] keys...);
41 
42     List!(string) blpop(string[] args...);
43 
44     List!(string) brpop(string[] args...);
45 
46     /**
47      * Returns all the keys matching the glob-style pattern. For example if
48      * you have in the database the keys "foo" and "foobar" the command "KEYS foo*" will return
49      * "foo foobar".<br>
50      * <strong>Warning:</strong> consider this as a command that should be used in production environments with <strong>extreme care</strong>.
51      * It may ruin performance when it is executed against large databases.
52      * This command is intended for debugging and special operations, such as changing your keyspace layout.
53      * <strong>Don't use it in your regular application code.</strong>
54      * If you're looking for a way to find keys in a subset of your keyspace, consider using {@link #scan(string, ScanParams)} or sets.
55      * <p>
56      * While the time complexity for this operation is O(N), the constant times are fairly low.
57      * For example, Redis running on an entry level laptop can scan a 1 million key database in 40 milliseconds.
58      * <p>
59      * Glob style patterns examples:
60      * <ul>
61      * <li>h?llo will match hello hallo hhllo
62      * <li>h*llo will match hllo heeeello
63      * <li>h[ae]llo will match hello and hallo, but not hillo
64      * </ul>
65      * <p>
66      * Use \ to escape special chars if you want to match them verbatim.
67      * <p>
68      * Time complexity: O(n) (with n being the number of keys in the DB, and assuming keys and pattern
69      * of limited length)
70      * @param pattern
71      * @return Multi bulk reply
72      * @see <a href="https://redis.io/commands/keys">Redis KEYS documentation</a>
73      */
74     Set!(string) keys(string pattern);
75 
76     List!(string) mget(string[] keys...);
77 
78     string mset(string[] keysvalues...);
79 
80     Long msetnx(string[] keysvalues...);
81 
82     string rename(string oldkey, string newkey);
83 
84     Long renamenx(string oldkey, string newkey);
85 
86     string rpoplpush(string srckey, string dstkey);
87 
88     Set!(string) sdiff(string[] keys...);
89 
90     Long sdiffstore(string dstkey, string[] keys...);
91 
92     Set!(string) sinter(string[] keys...);
93 
94     Long sinterstore(string dstkey, string[] keys...);
95 
96     Long smove(string srckey, string dstkey, string member);
97 
98     Long sort(string key, SortingParams sortingParameters, string dstkey);
99 
100     Long sort(string key, string dstkey);
101 
102     Set!(string) sunion(string[] keys...);
103 
104     Long sunionstore(string dstkey, string[] keys...);
105 
106     string watch(string[] keys...);
107 
108     string unwatch();
109 
110     Long zinterstore(string dstkey, string[] sets...);
111 
112     Long zinterstore(string dstkey, ZParams params, string[] sets...);
113 
114     Long zunionstore(string dstkey, string[] sets...);
115 
116     Long zunionstore(string dstkey, ZParams params, string[] sets...);
117 
118     string brpoplpush(string source, string destination, int timeout);
119 
120     Long publish(string channel, string message);
121 
122     void subscribe(RedisPubSub redisPubSub, string[] channels...);
123 
124     void psubscribe(RedisPubSub redisPubSub, string[] patterns...);
125 
126     string randomKey();
127 
128     Long bitop(BitOP op, string destKey, string[] srcKeys...);
129 
130     /**
131      * @see #scan(string, ScanParams)
132      * 
133      * @param cursor
134      * @return 
135      */
136     ScanResult!(string) scan(string cursor);
137 
138     /**
139      * Iterates the set of keys in the currently selected Redis database.
140      * <p>
141      * Since this command allows for incremental iteration, returning only a small number of elements per call,
142      * it can be used in production without the downside of commands like {@link #keys(string)} or
143      * {@link RedisCommands#smembers(string)} )} that may block the server for a long time (even several seconds)
144      * when called against big collections of keys or elements.
145      * <p>
146      * SCAN basic usage!(br)
147      * SCAN is a cursor based iterator. This means that at every call of the command, the server returns an updated cursor
148      * that the user needs to use as the cursor argument in the next call.
149      * An iteration starts when the cursor is set to 0, and terminates when the cursor returned by the server is 0.
150      * <p>
151      * Scan guarantees!(br)
152      * The SCAN command, and the other commands in the SCAN family, are able to provide to the user a set of guarantees
153      * associated to full iterations.
154      * <ul>
155      * <li>A full iteration always retrieves all the elements that were present in the collection from the start to the
156      * end of a full iteration. This means that if a given element is inside the collection when an iteration is started,
157      * and is still there when an iteration terminates, then at some point SCAN returned it to the user.
158      * <li>A full iteration never returns any element that was NOT present in the collection from the start to the end of
159      * a full iteration. So if an element was removed before the start of an iteration, and is never added back to the
160      * collection for all the time an iteration lasts, SCAN ensures that this element will never be returned.
161      * </ul>
162      * However because SCAN has very little state associated (just the cursor) it has the following drawbacks:
163      * <ul>
164      * <li>A given element may be returned multiple times. It is up to the application to handle the case of duplicated
165      * elements, for example only using the returned elements in order to perform operations that are safe when re-applied
166      * multiple times.
167      * <li>Elements that were not constantly present in the collection during a full iteration, may be returned or not:
168      * it is undefined.
169      * </ul>
170      * <p>
171      * Time complexity: O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor
172      * to return back to 0. N is the number of elements inside the DB.
173      *
174      * @param cursor The cursor.
175      * @param params the scan parameters. For example a glob-style match pattern
176      * @return the scan result with the results of this iteration and the new position of the cursor
177      * @see <a href="https://redis.io/commands/scan">Redis SCAN documentation</a>
178      */
179     ScanResult!(string) scan(string cursor, ScanParams params);
180 
181     string pfmerge(string destkey, string[] sourcekeys...);
182 
183     Long pfcount(string[] keys...);
184 
185     Long touch(string[] keys...);
186     
187     /**
188      * XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
189      * 
190      * @param key
191      * @param count
192      * @param block
193      * @param streams
194      * @return
195      */
196     List!(MapEntry!(string, List!(StreamEntry))) xread(int count, long block, MapEntry!(string, StreamEntryID)[] streams...);
197 
198     /**
199      * XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
200      * 
201      * @param key
202      * @param groupname
203      * @param cosumer
204      * @param count
205      * @param block
206      * @param streams
207      * @return
208      */
209     List!(MapEntry!(string, List!(StreamEntry))) xreadGroup(string groupname, string consumer, int count, 
210                 long block, bool noAck, MapEntry!(string, StreamEntryID)[] streams...);
211 }