-
Notifications
You must be signed in to change notification settings - Fork 3
/
RedisJSON.h
334 lines (290 loc) · 12 KB
/
RedisJSON.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/**
* Copyright 2021 Pieter du Preez <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
#ifndef REDIS_PLUS_PLUS_REDIS_JSON_H
#define REDIS_PLUS_PLUS_REDIS_JSON_H
#include "Module.h"
#include <sstream>
#include <iomanip>
namespace redis::module {
template <typename RedisInstance>
class RedisJSON : public Module<RedisInstance>
{
public:
enum class DelOpt{ NX = 0, XX = 1 };
explicit RedisJSON(RedisInstance& redis)
: Module<RedisInstance>(redis, "ReJSON", "JSON")
{}
auto del(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.DEL", key);
}
auto del(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.DEL", key, path);
}
template <typename Input>
auto get(const sw::redis::StringView &key,
Input first, Input last,
const sw::redis::StringView &indent = "",
const sw::redis::StringView &newline = "",
const sw::redis::StringView &space = "",
bool noescape = false) {
static const std::string cmd = "JSON.GET";
sw::redis::range_check(cmd.c_str(), first, last);
std::vector<sw::redis::StringView> args = { cmd, key };
if (indent.data() != "") {
args.push_back("INDENT");
args.push_back(indent);
}
if (newline.data() != "") {
args.push_back("NEWLINE");
args.push_back(newline);
}
if (space.data() != "") {
args.push_back("SPACE");
args.push_back(space);
}
if (noescape) {
args.push_back("NOESCAPE");
}
std::for_each(first, last, [&args](auto &s){ args.push_back(s); });
return Module<RedisInstance>::_redis.template
command<std::string>(args.begin(), args.end());
}
auto get(const sw::redis::StringView &key,
const sw::redis::StringView &path,
const sw::redis::StringView &indent = "",
const sw::redis::StringView &newline = "",
const sw::redis::StringView &space = "",
bool noescape = false) {
std::vector<sw::redis::StringView> p = {path};
return get(key, p.begin(), p.end(), indent, newline, space, noescape);
}
template <typename Input, typename Output>
void mget(Input first, Input last,
const std::string& path,
Output &result) {
static const std::string cmd = "JSON.MGET";
sw::redis::range_check(cmd.c_str(), first, last);
std::vector<sw::redis::StringView> args = { cmd };
std::for_each(first, last, [&args](auto &s){ args.push_back(s); });
args.push_back(path);
Module<RedisInstance>::_redis.template
command(args.begin(), args.end(), std::back_inserter(result));
}
template <typename Input, typename Output>
void mget(Input first, Input last,
Output &result) {
mget(first, last, ".", result);
}
auto forget(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.DEL", key);
}
auto forget(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.DEL", key, path);
}
bool set(const sw::redis::StringView &key,
const sw::redis::StringView &path,
const sw::redis::StringView &value,
const DelOpt& opt) {
auto ret = Module<RedisInstance>::_redis.template
command<sw::redis::OptionalString>
("JSON.SET", key, path, value.data(),
(opt == DelOpt::NX) ? "NX" : "XX");
return (ret && *ret == "OK");
}
bool set(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long value,
const DelOpt& opt) {
auto ret = Module<RedisInstance>::_redis.template
command<sw::redis::OptionalString>
("JSON.SET", key, path, value,
(opt == DelOpt::NX) ? "NX" : "XX");
return (ret && *ret == "OK");
}
bool set(const sw::redis::StringView &key,
const sw::redis::StringView &path,
const sw::redis::StringView &value) {
auto ret = Module<RedisInstance>::_redis.template
command<sw::redis::OptionalString>
("JSON.SET", key, path, value.data());
return (ret && *ret == "OK");
}
bool set(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long value) {
auto ret = Module<RedisInstance>::_redis.template
command<sw::redis::OptionalString>
("JSON.SET", key, path, value);
return (ret && *ret == "OK");
}
auto arrlen(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.ARRLEN", key);
}
auto arrlen(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.ARRLEN", key, path);
}
auto arrpop(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long index = -1) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.ARRPOP", key, path, index);
}
auto arrpop(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.ARRPOP", key);
}
template <typename Input>
auto arrinsert(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long index,
Input first, Input last) {
static const std::string cmd = "JSON.ARRINSERT";
sw::redis::range_check(cmd.c_str(), first, last);
std::vector<std::string> args = { cmd, key.data(), path.data(), std::to_string(index) };
std::for_each(first, last, [this, &args](auto &s){
args.push_back(s.data());
});
return Module<RedisInstance>::_redis.template
command<long long>(args.begin(), args.end());
}
auto arrinsert(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long index,
const sw::redis::StringView &json) {
std::vector<std::string> j = {json.data()};
return arrinsert(key, path, index, j.begin(), j.end());
}
template <typename Input>
auto arrappend(const sw::redis::StringView &key,
const sw::redis::StringView &path,
Input first, Input last) {
static const std::string cmd = "JSON.ARRAPPEND";
sw::redis::range_check(cmd.c_str(), first, last);
std::vector<std::string> args = { cmd, key.data(), path.data() };
std::for_each(first, last, [this, &args](auto &s){
args.push_back(s);
});
return Module<RedisInstance>::_redis.template
command<long long>(args.begin(), args.end());
}
auto arrtrim(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long from,
long long to) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.ARRTRIM", key, path, from, to);
}
auto arrindex(const sw::redis::StringView &key,
const sw::redis::StringView &path,
const sw::redis::StringView &json,
long long from = 0,
long long to = 0) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.ARRINDEX", key, path, json, std::to_string(from), std::to_string(to));
}
auto strlen(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.STRLEN", key);
}
auto strlen(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.STRLEN", key, path);
}
auto type(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.TYPE", key);
}
auto type(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.TYPE", key, path);
}
auto resp(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.RESP", key);
}
auto resp(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<std::string>("JSON.RESP", key, path);
}
auto numincrby(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long num) {
return std::stoll(Module<RedisInstance>::_redis.template
command<std::string>("JSON.NUMINCRBY", key, path, num));
}
auto nummultby(const sw::redis::StringView &key,
const sw::redis::StringView &path,
long long num) {
return std::stoll(Module<RedisInstance>::_redis.template
command<std::string>("JSON.NUMMULTBY", key, path, num));
}
auto strappend(const sw::redis::StringView &key,
const sw::redis::StringView &str) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.STRAPPEND", key, str.data());
}
auto strappend(const sw::redis::StringView &key,
const sw::redis::StringView &path,
const sw::redis::StringView &str) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.STRAPPEND", key, path, str.data());
}
template <typename Output>
void objkeys(const sw::redis::StringView &key,
const sw::redis::StringView &path,
Output &result) {
Module<RedisInstance>::_redis.template
command("JSON.OBJKEYS", key, path, std::back_inserter(result));
}
template <typename Output>
void objkeys(const sw::redis::StringView &key,
Output &result) {
Module<RedisInstance>::_redis.template
command("JSON.OBJKEYS", key, std::back_inserter(result));
}
auto objlen(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.OBJLEN", key, path);
}
auto objlen(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<long long>("JSON.OBJLEN", key);
}
auto debugmem(const sw::redis::StringView &key,
const sw::redis::StringView &path) {
return Module<RedisInstance>::_redis.template
command<sw::redis::OptionalLongLong>("JSON.DEBUG", "MEMORY", key, path);
}
auto debugmem(const sw::redis::StringView &key) {
return Module<RedisInstance>::_redis.template
command<sw::redis::OptionalLongLong>("JSON.DEBUG", "MEMORY", key);
}
};
} // namespace
#endif