Skip to content

Commit 508bb62

Browse files
qiluo-msftkktheballer
authored andcommitted
Move RedisClient functions into DBConnector (sonic-net#382)
* Move RedisClient functions into DBConnector * RedisClient redirects all functions to DBConnector * Remove cpp file * Remove RedisClient * Add TODO comment
1 parent e1a597f commit 508bb62

14 files changed

+560
-251
lines changed

common/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ libswsscommon_la_SOURCES = \
3333
json.cpp \
3434
producertable.cpp \
3535
producerstatetable.cpp \
36-
redisclient.cpp \
3736
rediscommand.cpp \
3837
redistran.cpp \
3938
redisselect.cpp \

common/dbconnector.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,165 @@ string DBConnector::getClientName()
461461
}
462462
}
463463

464+
int64_t DBConnector::del(const string &key)
465+
{
466+
RedisCommand sdel;
467+
sdel.format("DEL %s", key.c_str());
468+
RedisReply r(this, sdel, REDIS_REPLY_INTEGER);
469+
return r.getContext()->integer;
470+
}
471+
472+
bool DBConnector::exists(const string &key)
473+
{
474+
RedisCommand rexists;
475+
if (key.find_first_of(" \t") != string::npos)
476+
{
477+
SWSS_LOG_ERROR("EXISTS failed, invalid space or tab in single key: %s", key.c_str());
478+
throw runtime_error("EXISTS failed, invalid space or tab in single key");
479+
}
480+
rexists.format("EXISTS %s", key.c_str());
481+
RedisReply r(this, rexists, REDIS_REPLY_INTEGER);
482+
return (r.getContext()->integer > 0);
483+
}
484+
485+
int64_t DBConnector::hdel(const string &key, const string &field)
486+
{
487+
RedisCommand shdel;
488+
shdel.format("HDEL %s %s", key.c_str(), field.c_str());
489+
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
490+
return r.getContext()->integer;
491+
}
492+
493+
int64_t DBConnector::hdel(const std::string &key, const std::vector<std::string> &fields)
494+
{
495+
RedisCommand shdel;
496+
shdel.formatHDEL(key, fields);
497+
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
498+
return r.getContext()->integer;
499+
}
500+
501+
void DBConnector::hset(const string &key, const string &field, const string &value)
502+
{
503+
RedisCommand shset;
504+
shset.format("HSET %s %s %s", key.c_str(), field.c_str(), value.c_str());
505+
RedisReply r(this, shset, REDIS_REPLY_INTEGER);
506+
}
507+
508+
void DBConnector::set(const string &key, const string &value)
509+
{
510+
RedisCommand sset;
511+
sset.format("SET %s %s", key.c_str(), value.c_str());
512+
RedisReply r(this, sset, REDIS_REPLY_STATUS);
513+
}
514+
515+
unordered_map<string, string> DBConnector::hgetall(const string &key)
516+
{
517+
unordered_map<string, string> map;
518+
hgetall(key, std::inserter(map, map.end()));
519+
return map;
520+
}
521+
522+
vector<string> DBConnector::keys(const string &key)
523+
{
524+
RedisCommand skeys;
525+
skeys.format("KEYS %s", key.c_str());
526+
RedisReply r(this, skeys, REDIS_REPLY_ARRAY);
527+
528+
auto ctx = r.getContext();
529+
530+
vector<string> list;
531+
for (unsigned int i = 0; i < ctx->elements; i++)
532+
list.emplace_back(ctx->element[i]->str);
533+
534+
return list;
535+
}
536+
537+
int64_t DBConnector::incr(const string &key)
538+
{
539+
RedisCommand sincr;
540+
sincr.format("INCR %s", key.c_str());
541+
RedisReply r(this, sincr, REDIS_REPLY_INTEGER);
542+
return r.getContext()->integer;
543+
}
544+
545+
int64_t DBConnector::decr(const string &key)
546+
{
547+
RedisCommand sdecr;
548+
sdecr.format("DECR %s", key.c_str());
549+
RedisReply r(this, sdecr, REDIS_REPLY_INTEGER);
550+
return r.getContext()->integer;
551+
}
552+
553+
shared_ptr<string> DBConnector::get(const string &key)
554+
{
555+
RedisCommand sget;
556+
sget.format("GET %s", key.c_str());
557+
RedisReply r(this, sget);
558+
auto reply = r.getContext();
559+
560+
if (reply->type == REDIS_REPLY_NIL)
561+
{
562+
return shared_ptr<string>(NULL);
563+
}
564+
565+
if (reply->type == REDIS_REPLY_STRING)
566+
{
567+
shared_ptr<string> ptr(new string(reply->str));
568+
return ptr;
569+
}
570+
571+
throw runtime_error("GET failed, memory exception");
572+
}
573+
574+
shared_ptr<string> DBConnector::hget(const string &key, const string &field)
575+
{
576+
RedisCommand shget;
577+
shget.format("HGET %s %s", key.c_str(), field.c_str());
578+
RedisReply r(this, shget);
579+
auto reply = r.getContext();
580+
581+
if (reply->type == REDIS_REPLY_NIL)
582+
{
583+
return shared_ptr<string>(NULL);
584+
}
585+
586+
if (reply->type == REDIS_REPLY_STRING)
587+
{
588+
shared_ptr<string> ptr(new string(reply->str));
589+
return ptr;
590+
}
591+
592+
SWSS_LOG_ERROR("HGET failed, reply-type: %d, %s: %s", reply->type, key.c_str(), field.c_str());
593+
throw runtime_error("HGET failed, unexpected reply type, memory exception");
594+
}
595+
596+
int64_t DBConnector::rpush(const string &list, const string &item)
597+
{
598+
RedisCommand srpush;
599+
srpush.format("RPUSH %s %s", list.c_str(), item.c_str());
600+
RedisReply r(this, srpush, REDIS_REPLY_INTEGER);
601+
return r.getContext()->integer;
602+
}
603+
604+
shared_ptr<string> DBConnector::blpop(const string &list, int timeout)
605+
{
606+
RedisCommand sblpop;
607+
sblpop.format("BLPOP %s %d", list.c_str(), timeout);
608+
RedisReply r(this, sblpop);
609+
auto reply = r.getContext();
610+
611+
if (reply->type == REDIS_REPLY_NIL)
612+
{
613+
return shared_ptr<string>(NULL);
614+
}
615+
616+
if (reply->type == REDIS_REPLY_STRING)
617+
{
618+
shared_ptr<string> ptr(new string(reply->str));
619+
return ptr;
620+
}
621+
622+
throw runtime_error("GET failed, memory exception");
623+
}
624+
464625
}

common/dbconnector.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
#include <vector>
66
#include <unordered_map>
77
#include <utility>
8+
#include <memory>
89

910
#include <hiredis/hiredis.h>
11+
#include "rediscommand.h"
12+
#include "redisreply.h"
1013
#define EMPTY_NAMESPACE std::string()
1114

1215
namespace swss {
@@ -101,12 +104,70 @@ class DBConnector
101104

102105
std::string getClientName();
103106

107+
int64_t del(const std::string &key);
108+
109+
bool exists(const std::string &key);
110+
111+
int64_t hdel(const std::string &key, const std::string &field);
112+
113+
int64_t hdel(const std::string &key, const std::vector<std::string> &fields);
114+
115+
std::unordered_map<std::string, std::string> hgetall(const std::string &key);
116+
117+
template <typename OutputIterator>
118+
void hgetall(const std::string &key, OutputIterator result);
119+
120+
std::vector<std::string> keys(const std::string &key);
121+
122+
void set(const std::string &key, const std::string &value);
123+
124+
void hset(const std::string &key, const std::string &field, const std::string &value);
125+
126+
template<typename InputIterator>
127+
void hmset(const std::string &key, InputIterator start, InputIterator stop);
128+
129+
std::shared_ptr<std::string> get(const std::string &key);
130+
131+
std::shared_ptr<std::string> hget(const std::string &key, const std::string &field);
132+
133+
int64_t incr(const std::string &key);
134+
135+
int64_t decr(const std::string &key);
136+
137+
int64_t rpush(const std::string &list, const std::string &item);
138+
139+
std::shared_ptr<std::string> blpop(const std::string &list, int timeout);
140+
104141
private:
105142
redisContext *m_conn;
106143
int m_dbId;
107144
std::string m_dbName;
108145
std::string m_namespace;
109146
};
110147

148+
template<typename OutputIterator>
149+
void DBConnector::hgetall(const std::string &key, OutputIterator result)
150+
{
151+
RedisCommand sincr;
152+
sincr.format("HGETALL %s", key.c_str());
153+
RedisReply r(this, sincr, REDIS_REPLY_ARRAY);
154+
155+
auto ctx = r.getContext();
156+
157+
for (unsigned int i = 0; i < ctx->elements; i += 2)
158+
{
159+
*result = std::make_pair(ctx->element[i]->str, ctx->element[i+1]->str);
160+
++result;
161+
}
162+
}
163+
164+
template<typename InputIterator>
165+
void DBConnector::hmset(const std::string &key, InputIterator start, InputIterator stop)
166+
{
167+
RedisCommand shmset;
168+
shmset.formatHMSET(key, start, stop);
169+
RedisReply r(this, shmset, REDIS_REPLY_STATUS);
170+
}
171+
111172
}
112173
#endif

common/logger.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,13 @@ void Logger::linkToDbWithOutput(const std::string &dbName, const PriorityChangeN
9292
// Initialize internal DB with observer
9393
logger.m_settingChangeObservers.insert(std::make_pair(dbName, std::make_pair(prioNotify, outputNotify)));
9494
DBConnector db("LOGLEVEL_DB", 0);
95-
RedisClient redisClient(&db);
96-
auto keys = redisClient.keys("*");
95+
auto keys = db.keys("*");
9796

9897
std::string key = dbName + ":" + dbName;
9998
std::string prio, output;
10099
bool doUpdate = false;
101-
auto prioPtr = redisClient.hget(key, DAEMON_LOGLEVEL);
102-
auto outputPtr = redisClient.hget(key, DAEMON_LOGOUTPUT);
100+
auto prioPtr = db.hget(key, DAEMON_LOGLEVEL);
101+
auto outputPtr = db.hget(key, DAEMON_LOGOUTPUT);
103102

104103
if ( prioPtr == nullptr )
105104
{

common/loglevel.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ int main(int argc, char **argv)
108108
}
109109

110110
DBConnector db("LOGLEVEL_DB", 0);
111-
RedisClient redisClient(&db);
112-
auto keys = redisClient.keys("*");
111+
auto keys = db.keys("*");
113112
for (auto& key : keys)
114113
{
115114
size_t colonPos = key.find(':');
@@ -136,7 +135,7 @@ int main(int argc, char **argv)
136135
for (const auto& key : keys)
137136
{
138137
const auto redis_key = std::string(key).append(":").append(key);
139-
auto level = redisClient.hget(redis_key, DAEMON_LOGLEVEL);
138+
auto level = db.hget(redis_key, DAEMON_LOGLEVEL);
140139
if (nullptr == level)
141140
{
142141
std::cerr << std::left << std::setw(30) << key << "Unknown log level" << std::endl;

0 commit comments

Comments
 (0)