Arduino-Redis
A Redis library for Arduino.
Redis.h
1 
21 #ifndef REDIS_H
22 #define REDIS_H
23 
24 #include "Arduino.h"
25 #include "Client.h"
26 
27 #include <vector>
28 
29 typedef enum {
30  RedisSuccess = 0,
31  RedisNotConnectedFailure = 1,
32  RedisAuthFailure = 2,
33 } RedisReturnValue;
34 
35 typedef enum {
36  RedisSubscribeBadCallback = -255,
37  RedisSubscribeSetupFailure,
38  RedisSubscribeSuccess = 0
39 } RedisSubscribeResult;
40 
41 typedef enum {
42  RedisMessageBadResponseType = -255,
43  RedisMessageTruncatedResponse,
44  RedisMessageUnknownType,
45 } RedisMessageError;
46 
55 class Redis {
56 public:
57  typedef void (*RedisMsgCallback)(Redis*, String, String);
58 
59  typedef void (*RedisMsgErrorCallback)(Redis*, RedisMessageError);
60 
66  Redis(Client& client) : conn(client) {}
67 
68  ~Redis() {}
69  Redis(const Redis&) = delete;
70  Redis& operator=(const Redis&) = delete;
71  Redis(const Redis&&) = delete;
72  Redis& operator=(const Redis&&) = delete;
73 
79  RedisReturnValue authenticate(const char* password);
80 
90  bool set(const char* key, const char* value);
91 
97  String get(const char* key);
98 
104  bool del(const char* key);
105 
111  bool exists(const char* key);
112 
119  int append(const char* key, const char* value);
120 
127  int publish(const char* channel, const char* message);
128 
135  bool expire(const char* key, int seconds) { return _expire_(key, seconds, "EXPIRE"); }
136 
144  bool expire_at(const char* key, int timestamp) { return _expire_(key, timestamp, "EXPIREAT"); }
145 
152  bool pexpire(const char* key, int ms) { return _expire_(key, ms, "PEXPIRE"); }
153 
161  bool pexpire_at(const char* key, int timestamp) { return _expire_(key, timestamp, "PEXPIREAT"); }
162 
168  bool persist(const char* key);
169 
176  int ttl(const char* key) { return _ttl_(key, "TTL"); }
177 
184  int pttl(const char* key) { return _ttl_(key, "PTTL"); }
185 
193  bool hset(const char* key, const char* field, const char* value) { return _hset_(key, field, value, "HSET"); }
194 
202  bool hsetnx(const char* key, const char* field, const char* value) { return _hset_(key, field, value, "HSETNX"); }
203 
210  String hget(const char* key, const char* field);
217  bool hdel(const char* key, const char* field);
218 
224  int hlen(const char* key);
225 
232  int hstrlen(const char* key, const char* field);
233 
240  bool hexists(const char* key, const char* field);
241 
248  std::vector<String> lrange(const char* key, int start, int stop);
249 
253  bool subscribe(const char* channel) { return _subscribe(SubscribeSpec{false, String(channel)}); }
254 
258  bool psubscribe(const char* pattern) { return _subscribe(SubscribeSpec{true, String(pattern)}); }
259 
263  bool unsubscribe(const char* channelOrPattern);
264 
274  RedisSubscribeResult startSubscribing(RedisMsgCallback messageCallback, RedisMsgErrorCallback errorCallback = nullptr);
275 
279  void stopSubscribing() { subLoopRun = false; }
280 
281 #if ARDUINO_REDIS_TEST
282  typedef struct {
283  int total;
284  int passed;
285  } TestResults;
286 
287  TestResults runTests(bool logToSerial = false,
288  String prefix = "__com.arduino-redis.test",
289  bool retainData = false);
290 #endif // ARDUINO_REDIS_TEST
291 
292 private:
293  typedef struct {
294  bool pattern;
295  String spec;
296  } SubscribeSpec;
297 
298  bool _subscribe(SubscribeSpec spec);
299 
300  Client& conn;
301  std::vector<SubscribeSpec> subSpec;
302  bool subscriberMode = false;
303  bool subLoopRun = false;
304 
305  bool _expire_(const char*, int, const char*);
306  int _ttl_(const char*, const char*);
307  bool _hset_(const char*, const char*, const char*, const char*);
308 };
309 
310 #if ARDUINO_REDIS_TEST
311 #include <map>
312 
313 /* tests are not expected to pass if retainData = true */
314 Redis::TestResults Redis::runTests(bool logToSerial, String prefix, bool retainData)
315 {
316  /* These are NOT executed in definition order! */
317  std::map<String, std::function<bool(const char*)>> g_Tests
318  {
319  { "set", [this](const char* k) { return set(k, "!"); } },
320  { "setget", [this](const char* k) { return set(k, "!") == 1 && get(k) == "!"; } },
321  { "expire", [this](const char* k) {
322  return set(k, "E") && expire(k, 5) && ttl(k) > 4;
323  } },
324  { "pexpire", [this](const char* k) {
325  return set(k, "PE") && pexpire(k, 5000) && pttl(k) > 4500;
326  } },
327  { "dlyexp", [this](const char* k) {
328  auto sr = set(k, "DE");
329  expire(k, 10);
330  delay(4000);
331  auto t = ttl(k);
332  return sr && t > 5 && t < 7;
333  } },
334  { "hset", [this](const char* k) { return hset(k, "TF", "H!") && hexists(k, "TF"); } },
335  { "hsetget", [this](const char* k) {
336  return hset(k, "TF", "HH") && hget(k, "TF") == "HH";
337  } },
338  { "hlen", [this](const char* k) {
339  for (int i = 0; i < 10; i++) {
340  auto fv = String(i);
341  hset(k, String("field-" + fv).c_str(), fv.c_str());
342  }
343  return hlen(k) == 10;
344  } },
345  { "hstrlen", [this](const char* k) {
346  return hset(k, "hsr", k) && hstrlen(k, "hsr") == strlen(k);
347  } },
348  { "append", [this](const char* k) { return append(k, "foo") == 3; } },
349  { "exists", [this](const char* k) { return set(k, k) && exists(k); } }
350  };
351 
352  if (logToSerial) {
353  Serial.begin(115200);
354  Serial.printf("Redis::run_tests(\"%s\") starting...\n", prefix.c_str());
355  }
356 
357  auto pFunc = [&prefix](const String& n) { return String(prefix + "." + n); };
358 
359  int total = 0, pass = 0;
360  for (auto& kv : g_Tests)
361  {
362  auto tName = kv.first;
363  auto tFunc = kv.second;
364  auto pName = pFunc(tName);
365  auto tRes = tFunc(pName.c_str());
366  if (logToSerial)
367  Serial.printf("\tTest \"%s\":\t%s\n", tName.c_str(), tRes ? "pass" : "FAIL");
368  total++;
369  pass += tRes ? 1 : 0;
370  }
371 
372  if (logToSerial)
373  Serial.printf("Result: %d passed / %d total\n", pass, total);
374 
375  if (!retainData)
376  for (auto& kv : g_Tests)
377  (void)del(pFunc(kv.first).c_str());
378 
379  return { .total = total, .passed = pass };
380 }
381 #endif
382 
383 #endif
Redis::ttl
int ttl(const char *key)
Definition: Redis.h:176
Redis::hget
String hget(const char *key, const char *field)
Definition: Redis.cpp:74
Redis::pexpire_at
bool pexpire_at(const char *key, int timestamp)
Definition: Redis.h:161
Redis
Definition: Redis.h:55
Redis::stopSubscribing
void stopSubscribing()
Definition: Redis.h:279
Redis::subscribe
bool subscribe(const char *channel)
Definition: Redis.h:253
Redis::del
bool del(const char *key)
Definition: Redis.cpp:34
Redis::get
String get(const char *key)
Definition: Redis.cpp:29
Redis::startSubscribing
RedisSubscribeResult startSubscribing(RedisMsgCallback messageCallback, RedisMsgErrorCallback errorCallback=nullptr)
Definition: Redis.cpp:131
Redis::unsubscribe
bool unsubscribe(const char *channelOrPattern)
Definition: Redis.cpp:119
Redis::expire_at
bool expire_at(const char *key, int timestamp)
Definition: Redis.h:144
Redis::pexpire
bool pexpire(const char *key, int ms)
Definition: Redis.h:152
Redis::publish
int publish(const char *channel, const char *message)
Definition: Redis.cpp:44
Redis::pttl
int pttl(const char *key)
Definition: Redis.h:184
Redis::persist
bool persist(const char *key)
Definition: Redis.cpp:59
Redis::lrange
std::vector< String > lrange(const char *key, int start, int stop)
Definition: Redis.cpp:99
Redis::authenticate
RedisReturnValue authenticate(const char *password)
Definition: Redis.cpp:4
Redis::hsetnx
bool hsetnx(const char *key, const char *field, const char *value)
Definition: Redis.h:202
Redis::exists
bool exists(const char *key)
Definition: Redis.cpp:49
Redis::hstrlen
int hstrlen(const char *key, const char *field)
Definition: Redis.cpp:89
Redis::hdel
bool hdel(const char *key, const char *field)
Definition: Redis.cpp:79
Redis::hexists
bool hexists(const char *key, const char *field)
Definition: Redis.cpp:94
Redis::Redis
Redis(Client &client)
Definition: Redis.h:66
Redis::append
int append(const char *key, const char *value)
Definition: Redis.cpp:39
Redis::hset
bool hset(const char *key, const char *field, const char *value)
Definition: Redis.h:193
Redis::psubscribe
bool psubscribe(const char *pattern)
Definition: Redis.h:258
Redis::set
bool set(const char *key, const char *value)
Definition: Redis.cpp:22
Redis::hlen
int hlen(const char *key)
Definition: Redis.cpp:84
Redis::expire
bool expire(const char *key, int seconds)
Definition: Redis.h:135