Skip to content

Commit 2b9a00f

Browse files
authored
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 7db299a commit 2b9a00f

14 files changed

+275
-268
lines changed

common/Makefile.am

-1
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

+161
Original file line numberDiff line numberDiff line change
@@ -527,4 +527,165 @@ string DBConnector::getClientName()
527527
}
528528
}
529529

530+
int64_t DBConnector::del(const string &key)
531+
{
532+
RedisCommand sdel;
533+
sdel.format("DEL %s", key.c_str());
534+
RedisReply r(this, sdel, REDIS_REPLY_INTEGER);
535+
return r.getContext()->integer;
536+
}
537+
538+
bool DBConnector::exists(const string &key)
539+
{
540+
RedisCommand rexists;
541+
if (key.find_first_of(" \t") != string::npos)
542+
{
543+
SWSS_LOG_ERROR("EXISTS failed, invalid space or tab in single key: %s", key.c_str());
544+
throw runtime_error("EXISTS failed, invalid space or tab in single key");
545+
}
546+
rexists.format("EXISTS %s", key.c_str());
547+
RedisReply r(this, rexists, REDIS_REPLY_INTEGER);
548+
return (r.getContext()->integer > 0);
549+
}
550+
551+
int64_t DBConnector::hdel(const string &key, const string &field)
552+
{
553+
RedisCommand shdel;
554+
shdel.format("HDEL %s %s", key.c_str(), field.c_str());
555+
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
556+
return r.getContext()->integer;
557+
}
558+
559+
int64_t DBConnector::hdel(const std::string &key, const std::vector<std::string> &fields)
560+
{
561+
RedisCommand shdel;
562+
shdel.formatHDEL(key, fields);
563+
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
564+
return r.getContext()->integer;
565+
}
566+
567+
void DBConnector::hset(const string &key, const string &field, const string &value)
568+
{
569+
RedisCommand shset;
570+
shset.format("HSET %s %s %s", key.c_str(), field.c_str(), value.c_str());
571+
RedisReply r(this, shset, REDIS_REPLY_INTEGER);
572+
}
573+
574+
void DBConnector::set(const string &key, const string &value)
575+
{
576+
RedisCommand sset;
577+
sset.format("SET %s %s", key.c_str(), value.c_str());
578+
RedisReply r(this, sset, REDIS_REPLY_STATUS);
579+
}
580+
581+
unordered_map<string, string> DBConnector::hgetall(const string &key)
582+
{
583+
unordered_map<string, string> map;
584+
hgetall(key, std::inserter(map, map.end()));
585+
return map;
586+
}
587+
588+
vector<string> DBConnector::keys(const string &key)
589+
{
590+
RedisCommand skeys;
591+
skeys.format("KEYS %s", key.c_str());
592+
RedisReply r(this, skeys, REDIS_REPLY_ARRAY);
593+
594+
auto ctx = r.getContext();
595+
596+
vector<string> list;
597+
for (unsigned int i = 0; i < ctx->elements; i++)
598+
list.emplace_back(ctx->element[i]->str);
599+
600+
return list;
601+
}
602+
603+
int64_t DBConnector::incr(const string &key)
604+
{
605+
RedisCommand sincr;
606+
sincr.format("INCR %s", key.c_str());
607+
RedisReply r(this, sincr, REDIS_REPLY_INTEGER);
608+
return r.getContext()->integer;
609+
}
610+
611+
int64_t DBConnector::decr(const string &key)
612+
{
613+
RedisCommand sdecr;
614+
sdecr.format("DECR %s", key.c_str());
615+
RedisReply r(this, sdecr, REDIS_REPLY_INTEGER);
616+
return r.getContext()->integer;
617+
}
618+
619+
shared_ptr<string> DBConnector::get(const string &key)
620+
{
621+
RedisCommand sget;
622+
sget.format("GET %s", key.c_str());
623+
RedisReply r(this, sget);
624+
auto reply = r.getContext();
625+
626+
if (reply->type == REDIS_REPLY_NIL)
627+
{
628+
return shared_ptr<string>(NULL);
629+
}
630+
631+
if (reply->type == REDIS_REPLY_STRING)
632+
{
633+
shared_ptr<string> ptr(new string(reply->str));
634+
return ptr;
635+
}
636+
637+
throw runtime_error("GET failed, memory exception");
638+
}
639+
640+
shared_ptr<string> DBConnector::hget(const string &key, const string &field)
641+
{
642+
RedisCommand shget;
643+
shget.format("HGET %s %s", key.c_str(), field.c_str());
644+
RedisReply r(this, shget);
645+
auto reply = r.getContext();
646+
647+
if (reply->type == REDIS_REPLY_NIL)
648+
{
649+
return shared_ptr<string>(NULL);
650+
}
651+
652+
if (reply->type == REDIS_REPLY_STRING)
653+
{
654+
shared_ptr<string> ptr(new string(reply->str));
655+
return ptr;
656+
}
657+
658+
SWSS_LOG_ERROR("HGET failed, reply-type: %d, %s: %s", reply->type, key.c_str(), field.c_str());
659+
throw runtime_error("HGET failed, unexpected reply type, memory exception");
660+
}
661+
662+
int64_t DBConnector::rpush(const string &list, const string &item)
663+
{
664+
RedisCommand srpush;
665+
srpush.format("RPUSH %s %s", list.c_str(), item.c_str());
666+
RedisReply r(this, srpush, REDIS_REPLY_INTEGER);
667+
return r.getContext()->integer;
668+
}
669+
670+
shared_ptr<string> DBConnector::blpop(const string &list, int timeout)
671+
{
672+
RedisCommand sblpop;
673+
sblpop.format("BLPOP %s %d", list.c_str(), timeout);
674+
RedisReply r(this, sblpop);
675+
auto reply = r.getContext();
676+
677+
if (reply->type == REDIS_REPLY_NIL)
678+
{
679+
return shared_ptr<string>(NULL);
680+
}
681+
682+
if (reply->type == REDIS_REPLY_STRING)
683+
{
684+
shared_ptr<string> ptr(new string(reply->str));
685+
return ptr;
686+
}
687+
688+
throw runtime_error("GET failed, memory exception");
689+
}
690+
530691
}

common/dbconnector.h

+61
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 {
@@ -103,12 +106,70 @@ class DBConnector
103106

104107
std::string getClientName();
105108

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

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

common/logger.cpp

+3-4
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

+2-3
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)