Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move RedisClient functions into DBConnector #382

Merged
merged 5 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ libswsscommon_la_SOURCES = \
json.cpp \
producertable.cpp \
producerstatetable.cpp \
redisclient.cpp \
rediscommand.cpp \
redistran.cpp \
redisselect.cpp \
Expand Down
161 changes: 161 additions & 0 deletions common/dbconnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,165 @@ string DBConnector::getClientName()
}
}

int64_t DBConnector::del(const string &key)
{
RedisCommand sdel;
sdel.format("DEL %s", key.c_str());
RedisReply r(this, sdel, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

bool DBConnector::exists(const string &key)
{
RedisCommand rexists;
if (key.find_first_of(" \t") != string::npos)
{
SWSS_LOG_ERROR("EXISTS failed, invalid space or tab in single key: %s", key.c_str());
throw runtime_error("EXISTS failed, invalid space or tab in single key");
}
rexists.format("EXISTS %s", key.c_str());
RedisReply r(this, rexists, REDIS_REPLY_INTEGER);
return (r.getContext()->integer > 0);
}

int64_t DBConnector::hdel(const string &key, const string &field)
{
RedisCommand shdel;
shdel.format("HDEL %s %s", key.c_str(), field.c_str());
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

int64_t DBConnector::hdel(const std::string &key, const std::vector<std::string> &fields)
{
RedisCommand shdel;
shdel.formatHDEL(key, fields);
RedisReply r(this, shdel, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

void DBConnector::hset(const string &key, const string &field, const string &value)
{
RedisCommand shset;
shset.format("HSET %s %s %s", key.c_str(), field.c_str(), value.c_str());
RedisReply r(this, shset, REDIS_REPLY_INTEGER);
}

void DBConnector::set(const string &key, const string &value)
{
RedisCommand sset;
sset.format("SET %s %s", key.c_str(), value.c_str());
RedisReply r(this, sset, REDIS_REPLY_STATUS);
}

unordered_map<string, string> DBConnector::hgetall(const string &key)
{
unordered_map<string, string> map;
hgetall(key, std::inserter(map, map.end()));
return map;
}

vector<string> DBConnector::keys(const string &key)
{
RedisCommand skeys;
skeys.format("KEYS %s", key.c_str());
RedisReply r(this, skeys, REDIS_REPLY_ARRAY);

auto ctx = r.getContext();

vector<string> list;
for (unsigned int i = 0; i < ctx->elements; i++)
list.emplace_back(ctx->element[i]->str);

return list;
}

int64_t DBConnector::incr(const string &key)
{
RedisCommand sincr;
sincr.format("INCR %s", key.c_str());
RedisReply r(this, sincr, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

int64_t DBConnector::decr(const string &key)
{
RedisCommand sdecr;
sdecr.format("DECR %s", key.c_str());
RedisReply r(this, sdecr, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

shared_ptr<string> DBConnector::get(const string &key)
{
RedisCommand sget;
sget.format("GET %s", key.c_str());
RedisReply r(this, sget);
auto reply = r.getContext();

if (reply->type == REDIS_REPLY_NIL)
{
return shared_ptr<string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
shared_ptr<string> ptr(new string(reply->str));
return ptr;
}

throw runtime_error("GET failed, memory exception");
}

shared_ptr<string> DBConnector::hget(const string &key, const string &field)
{
RedisCommand shget;
shget.format("HGET %s %s", key.c_str(), field.c_str());
RedisReply r(this, shget);
auto reply = r.getContext();

if (reply->type == REDIS_REPLY_NIL)
{
return shared_ptr<string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
shared_ptr<string> ptr(new string(reply->str));
return ptr;
}

SWSS_LOG_ERROR("HGET failed, reply-type: %d, %s: %s", reply->type, key.c_str(), field.c_str());
throw runtime_error("HGET failed, unexpected reply type, memory exception");
}

int64_t DBConnector::rpush(const string &list, const string &item)
{
RedisCommand srpush;
srpush.format("RPUSH %s %s", list.c_str(), item.c_str());
RedisReply r(this, srpush, REDIS_REPLY_INTEGER);
return r.getContext()->integer;
}

shared_ptr<string> DBConnector::blpop(const string &list, int timeout)
{
RedisCommand sblpop;
sblpop.format("BLPOP %s %d", list.c_str(), timeout);
RedisReply r(this, sblpop);
auto reply = r.getContext();

if (reply->type == REDIS_REPLY_NIL)
{
return shared_ptr<string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
shared_ptr<string> ptr(new string(reply->str));
return ptr;
}

throw runtime_error("GET failed, memory exception");
}

}
61 changes: 61 additions & 0 deletions common/dbconnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
#include <vector>
#include <unordered_map>
#include <utility>
#include <memory>

#include <hiredis/hiredis.h>
#include "rediscommand.h"
#include "redisreply.h"
#define EMPTY_NAMESPACE std::string()

namespace swss {
Expand Down Expand Up @@ -103,12 +106,70 @@ class DBConnector

std::string getClientName();

int64_t del(const std::string &key);

bool exists(const std::string &key);

int64_t hdel(const std::string &key, const std::string &field);

int64_t hdel(const std::string &key, const std::vector<std::string> &fields);

std::unordered_map<std::string, std::string> hgetall(const std::string &key);

template <typename OutputIterator>
void hgetall(const std::string &key, OutputIterator result);

std::vector<std::string> keys(const std::string &key);

void set(const std::string &key, const std::string &value);

void hset(const std::string &key, const std::string &field, const std::string &value);

template<typename InputIterator>
void hmset(const std::string &key, InputIterator start, InputIterator stop);

std::shared_ptr<std::string> get(const std::string &key);

std::shared_ptr<std::string> hget(const std::string &key, const std::string &field);

int64_t incr(const std::string &key);

int64_t decr(const std::string &key);

int64_t rpush(const std::string &list, const std::string &item);

std::shared_ptr<std::string> blpop(const std::string &list, int timeout);

private:
redisContext *m_conn;
int m_dbId;
std::string m_dbName;
std::string m_namespace;
};

template<typename OutputIterator>
void DBConnector::hgetall(const std::string &key, OutputIterator result)
{
RedisCommand sincr;
sincr.format("HGETALL %s", key.c_str());
RedisReply r(this, sincr, REDIS_REPLY_ARRAY);

auto ctx = r.getContext();

for (unsigned int i = 0; i < ctx->elements; i += 2)
{
*result = std::make_pair(ctx->element[i]->str, ctx->element[i+1]->str);
++result;
}
}

template<typename InputIterator>
void DBConnector::hmset(const std::string &key, InputIterator start, InputIterator stop)
{
RedisCommand shmset;
shmset.formatHMSET(key, start, stop);
RedisReply r(this, shmset, REDIS_REPLY_STATUS);
}

}
#endif
7 changes: 3 additions & 4 deletions common/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ void Logger::linkToDbWithOutput(const std::string &dbName, const PriorityChangeN
// Initialize internal DB with observer
logger.m_settingChangeObservers.insert(std::make_pair(dbName, std::make_pair(prioNotify, outputNotify)));
DBConnector db("LOGLEVEL_DB", 0);
RedisClient redisClient(&db);
auto keys = redisClient.keys("*");
auto keys = db.keys("*");

std::string key = dbName + ":" + dbName;
std::string prio, output;
bool doUpdate = false;
auto prioPtr = redisClient.hget(key, DAEMON_LOGLEVEL);
auto outputPtr = redisClient.hget(key, DAEMON_LOGOUTPUT);
auto prioPtr = db.hget(key, DAEMON_LOGLEVEL);
auto outputPtr = db.hget(key, DAEMON_LOGOUTPUT);

if ( prioPtr == nullptr )
{
Expand Down
5 changes: 2 additions & 3 deletions common/loglevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ int main(int argc, char **argv)
}

DBConnector db("LOGLEVEL_DB", 0);
RedisClient redisClient(&db);
auto keys = redisClient.keys("*");
auto keys = db.keys("*");
for (auto& key : keys)
{
size_t colonPos = key.find(':');
Expand All @@ -136,7 +135,7 @@ int main(int argc, char **argv)
for (const auto& key : keys)
{
const auto redis_key = std::string(key).append(":").append(key);
auto level = redisClient.hget(redis_key, DAEMON_LOGLEVEL);
auto level = db.hget(redis_key, DAEMON_LOGLEVEL);
if (nullptr == level)
{
std::cerr << std::left << std::setw(30) << key << "Unknown log level" << std::endl;
Expand Down
Loading