Arduino-Redis
A Redis library for Arduino.
Redis.h
1 
20 #ifndef REDIS_H
21 #define REDIS_H
22 
23 #include "Arduino.h"
24 #include "Client.h"
25 
26 typedef enum {
27  RedisSuccess = 0,
28  RedisNotConnectedFailure = 1,
29  RedisAuthFailure = 2,
30 } RedisReturnValue;
31 
40 class Redis {
41 public:
47  Redis(Client& client) : conn(client) {}
48 
49  ~Redis() {}
50  Redis(const Redis&) = delete;
51  Redis& operator=(const Redis&) = delete;
52 
58  RedisReturnValue authenticate(const char* password);
59 
69  bool set(const char* key, const char* value);
70 
76  String get(const char* key);
77 
83  bool del(const char* key);
84 
90  bool exists(const char* key);
91 
98  int append(const char* key, const char* value);
99 
106  int publish(const char* channel, const char* message);
107 
114  bool expire(const char* key, int seconds) { return _expire_(key, seconds, "EXPIRE"); }
115 
123  bool expire_at(const char* key, int timestamp) { return _expire_(key, timestamp, "EXPIREAT"); }
124 
131  bool pexpire(const char* key, int ms) { return _expire_(key, ms, "PEXPIRE"); }
132 
140  bool pexpire_at(const char* key, int timestamp) { return _expire_(key, timestamp, "PEXPIREAT"); }
141 
147  bool persist(const char* key);
148 
155  int ttl(const char* key) { return _ttl_(key, "TTL"); }
156 
163  int pttl(const char* key) { return _ttl_(key, "PTTL"); }
164 
172  bool hset(const char* key, const char* field, const char* value) { return _hset_(key, field, value, "HSET"); }
173 
181  bool hsetnx(const char* key, const char* field, const char* value) { return _hset_(key, field, value, "HSETNX"); }
182 
189  String hget(const char* key, const char* field);
196  bool hdel(const char* key, const char* field);
197 
203  int hlen(const char* key);
204 
211  int hstrlen(const char* key, const char* field);
212 
219  bool hexists(const char* key, const char* field);
220 
221 #if ARDUINO_REDIS_TEST
222  typedef struct {
223  int total;
224  int passed;
225  } TestResults;
226 
227  TestResults runTests(bool logToSerial = false,
228  String prefix = "__com.arduino-redis.test",
229  bool retainData = false);
230 #endif // ARDUINO_REDIS_TEST
231 
232 private:
233  Client& conn;
234 
235  bool _expire_(const char*, int, const char*);
236  int _ttl_(const char*, const char*);
237  bool _hset_(const char*, const char*, const char*, const char*);
238 };
239 
240 #if ARDUINO_REDIS_TEST
241 #include <map>
242 
243 /* tests are not expected to pass if retainData = true */
244 Redis::TestResults Redis::runTests(bool logToSerial, String prefix, bool retainData)
245 {
246  /* These are NOT executed in definition order! */
247  std::map<String, std::function<bool(const char*)>> g_Tests
248  {
249  { "set", [this](const char* k) { return set(k, "!"); } },
250  { "setget", [this](const char* k) { return set(k, "!") == 1 && get(k) == "!"; } },
251  { "expire", [this](const char* k) {
252  return set(k, "E") && expire(k, 5) && ttl(k) > 4;
253  } },
254  { "pexpire", [this](const char* k) {
255  return set(k, "PE") && pexpire(k, 5000) && pttl(k) > 4500;
256  } },
257  { "dlyexp", [this](const char* k) {
258  auto sr = set(k, "DE");
259  expire(k, 10);
260  delay(4000);
261  auto t = ttl(k);
262  return sr && t > 5 && t < 7;
263  } },
264  { "hset", [this](const char* k) { return hset(k, "TF", "H!") && hexists(k, "TF"); } },
265  { "hsetget", [this](const char* k) {
266  return hset(k, "TF", "HH") && hget(k, "TF") == "HH";
267  } },
268  { "hlen", [this](const char* k) {
269  for (int i = 0; i < 10; i++) {
270  auto fv = String(i);
271  hset(k, String("field-" + fv).c_str(), fv.c_str());
272  }
273  return hlen(k) == 10;
274  } },
275  { "hstrlen", [this](const char* k) {
276  return hset(k, "hsr", k) && hstrlen(k, "hsr") == strlen(k);
277  } },
278  { "append", [this](const char* k) { return append(k, "foo") == 3; } },
279  { "exists", [this](const char* k) { return set(k, k) && exists(k); } }
280  };
281 
282  if (logToSerial) {
283  Serial.begin(115200);
284  Serial.printf("Redis::run_tests(\"%s\") starting...\n", prefix.c_str());
285  }
286 
287  auto pFunc = [&prefix](const String& n) { return String(prefix + "." + n); };
288 
289  int total = 0, pass = 0;
290  for (auto& kv : g_Tests)
291  {
292  auto tName = kv.first;
293  auto tFunc = kv.second;
294  auto pName = pFunc(tName);
295  auto tRes = tFunc(pName.c_str());
296  if (logToSerial)
297  Serial.printf("\tTest \"%s\":\t%s\n", tName.c_str(), tRes ? "pass" : "FAIL");
298  total++;
299  pass += tRes ? 1 : 0;
300  }
301 
302  if (logToSerial)
303  Serial.printf("Result: %d passed / %d total\n", pass, total);
304 
305  if (!retainData)
306  for (auto& kv : g_Tests)
307  (void)del(pFunc(kv.first).c_str());
308 
309  return { .total = total, .passed = pass };
310 }
311 #endif
312 
313 #endif
String hget(const char *key, const char *field)
Definition: Redis.cpp:76
bool del(const char *key)
Definition: Redis.cpp:36
bool pexpire_at(const char *key, int timestamp)
Definition: Redis.h:140
int hlen(const char *key)
Definition: Redis.cpp:86
bool expire_at(const char *key, int timestamp)
Definition: Redis.h:123
int ttl(const char *key)
Definition: Redis.h:155
int publish(const char *channel, const char *message)
Definition: Redis.cpp:46
int pttl(const char *key)
Definition: Redis.h:163
bool persist(const char *key)
Definition: Redis.cpp:61
RedisReturnValue authenticate(const char *password)
Definition: Redis.cpp:6
bool pexpire(const char *key, int ms)
Definition: Redis.h:131
int hstrlen(const char *key, const char *field)
Definition: Redis.cpp:91
Definition: Redis.h:40
bool hsetnx(const char *key, const char *field, const char *value)
Definition: Redis.h:181
Redis(Client &client)
Definition: Redis.h:47
bool exists(const char *key)
Definition: Redis.cpp:51
bool expire(const char *key, int seconds)
Definition: Redis.h:114
int append(const char *key, const char *value)
Definition: Redis.cpp:41
bool hdel(const char *key, const char *field)
Definition: Redis.cpp:81
bool hset(const char *key, const char *field, const char *value)
Definition: Redis.h:172
bool hexists(const char *key, const char *field)
Definition: Redis.cpp:96