Arduino-Redis
A Redis library for Arduino.
Redis.cpp
1 #include "Redis.h"
2 #include "RedisInternal.h"
3 
4 RedisReturnValue Redis::authenticate(const char* password)
5 {
6  if(conn.connected())
7  {
8  int passwordLength = strlen(password);
9  if (passwordLength > 0)
10  {
11  auto cmdRet = RedisCommand("AUTH", ArgList{password}).issue(conn);
12  return cmdRet->type() == RedisObject::Type::SimpleString && (String)*cmdRet == "OK"
13  ? RedisSuccess : RedisAuthFailure;
14  }
15 
16  return RedisSuccess;
17  }
18 
19  return RedisNotConnectedFailure;
20 }
21 
22 bool Redis::set(const char* key, const char* value)
23 {
24  return ((String)*RedisCommand("SET", ArgList{key, value}).issue(conn)).indexOf("OK") != -1;
25 }
26 
27 #define TRCMD(t, c, ...) return RedisCommand(c, ArgList{__VA_ARGS__}).issue_typed<t>(conn)
28 
29 String Redis::get(const char* key)
30 {
31  TRCMD(String, "GET", key);
32 }
33 
34 bool Redis::del(const char* key)
35 {
36  TRCMD(bool, "DEL", key);
37 }
38 
39 int Redis::append(const char* key, const char* value)
40 {
41  TRCMD(int, "APPEND", key, value);
42 }
43 
44 int Redis::publish(const char* channel, const char* message)
45 {
46  TRCMD(int, "PUBLISH", channel, message);
47 }
48 
49 bool Redis::exists(const char* key)
50 {
51  TRCMD(bool, "EXISTS", key);
52 }
53 
54 bool Redis::_expire_(const char* key, int arg, const char* cmd_var)
55 {
56  TRCMD(bool, cmd_var, key, String(arg));
57 }
58 
59 bool Redis::persist(const char* key)
60 {
61  TRCMD(bool, "PERSIST", key);
62 }
63 
64 int Redis::_ttl_(const char* key, const char* cmd_var)
65 {
66  TRCMD(int, cmd_var, key);
67 }
68 
69 bool Redis::_hset_(const char* key, const char* field, const char* value, const char* cmd_var)
70 {
71  TRCMD(int, cmd_var, key, field, value);
72 }
73 
74 String Redis::hget(const char* key, const char* field)
75 {
76  TRCMD(String, "HGET", key, field);
77 }
78 
79 bool Redis::hdel(const char* key, const char* field)
80 {
81  TRCMD(bool, "HDEL", key, field);
82 }
83 
84 int Redis::hlen(const char* key)
85 {
86  TRCMD(int, "HLEN", key);
87 }
88 
89 int Redis::hstrlen(const char* key, const char* field)
90 {
91  TRCMD(int, "HSTRLEN", key, field);
92 }
93 
94 bool Redis::hexists(const char* key, const char* field)
95 {
96  TRCMD(bool, "HEXISTS", key, field);
97 }
98 
99 std::vector<String> Redis::lrange(const char* key, int start, int stop)
100 {
101  auto rv = RedisCommand("LRANGE", ArgList{key, String(start), String(stop)}).issue(conn);
102  return rv->type() == RedisObject::Type::Array
103  ? (std::vector<String>)*((RedisArray*)rv.get())
104  : std::vector<String>();
105 }
106 
107 bool Redis::_subscribe(SubscribeSpec spec)
108 {
109  if (!subscriberMode) {
110  subSpec.push_back(spec);
111  return true;
112  }
113 
114  const char* cmdName = spec.pattern ? "PSUBSCRIBE" : "SUBSCRIBE";
115  auto rv = RedisCommand(cmdName, ArgList{spec.spec}).issue(conn);
116  return rv->type() == RedisObject::Type::Array;
117 }
118 
119 bool Redis::unsubscribe(const char* channelOrPattern)
120 {
121  auto rv = RedisCommand("UNSUBSCRIBE", ArgList{channelOrPattern}).issue(conn);
122 
123  if (rv->type() == RedisObject::Type::Array) {
124  auto vec = (std::vector<String>)*((RedisArray*)rv.get());
125  return vec.size() == 3 && vec[1] == String(channelOrPattern);
126  }
127 
128  return false;
129 }
130 
131 RedisSubscribeResult Redis::startSubscribing(RedisMsgCallback messageCallback, RedisMsgErrorCallback errCallback)
132 {
133  if (!messageCallback) {
134  return RedisSubscribeBadCallback;
135  }
136 
137  bool success = true;
138  subscriberMode = true;
139  if (subSpec.size()) {
140  for (auto spec : subSpec) {
141  success = _subscribe(spec) && success;
142  }
143  }
144 
145  if (!success) {
146  return RedisSubscribeSetupFailure;
147  }
148 
149  auto emitErr = [=](RedisMessageError errCode) -> bool {
150  if (errCallback) {
151  errCallback(this, errCode);
152  }
153  };
154 
155  subLoopRun = true;
156  while (subLoopRun) {
157  auto msg = RedisObject::parseType(conn);
158 
159  if (msg->type() != RedisObject::Type::Array) {
160  emitErr(RedisMessageBadResponseType);
161  continue;
162  }
163 
164  auto msgVec = (std::vector<String>)*((RedisArray*)msg.get());
165 
166  if (msgVec.size() < 3) {
167  emitErr(RedisMessageTruncatedResponse);
168  continue;
169  }
170 
171  if (msgVec[0] != "message" && msgVec[0] != "pmessage") {
172  emitErr(RedisMessageUnknownType);
173  continue;
174  }
175 
176  // pmessage payloads have an extra paramter at index 1 that specifies the matched pattern; we ignore it here
177  auto pMsgAdd = msgVec[0] == "pmessage" ? 1 : 0;
178  messageCallback(this, msgVec[1 + pMsgAdd], msgVec[2 + pMsgAdd]);
179  }
180 
181  return RedisSubscribeSuccess;
182 }
Redis::hget
String hget(const char *key, const char *field)
Definition: Redis.cpp:74
RedisCommand
Definition: RedisInternal.h:133
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::publish
int publish(const char *channel, const char *message)
Definition: Redis.cpp:44
Redis::persist
bool persist(const char *key)
Definition: Redis.cpp:59
RedisArray
Definition: RedisInternal.h:86
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::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::append
int append(const char *key, const char *value)
Definition: Redis.cpp:39
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