From ee19720231bd4b6a35d1b0e123f027acb855e95c Mon Sep 17 00:00:00 2001 From: fbraem Date: Mon, 9 Nov 2015 22:25:10 +0100 Subject: [PATCH] Add more commands --- Redis/include/Poco/Redis/Command.h | 44 ++++++ Redis/src/Command.cpp | 122 +++++++++++++++- Redis/testsuite/src/RedisTest.cpp | 223 ++++++++++++++++------------- Redis/testsuite/src/RedisTest.h | 1 + 4 files changed, 290 insertions(+), 100 deletions(-) diff --git a/Redis/include/Poco/Redis/Command.h b/Redis/include/Poco/Redis/Command.h index ae0dd52b5..da28e93e0 100644 --- a/Redis/include/Poco/Redis/Command.h +++ b/Redis/include/Poco/Redis/Command.h @@ -21,6 +21,8 @@ #include "Poco/Redis/Redis.h" #include "Poco/Redis/Array.h" +#include + namespace Poco { namespace Redis { @@ -38,8 +40,50 @@ public: virtual ~Command(); /// Destructor + static Command append(const std::string& key, const std::string& value); + /// Returns an APPEND command + + static Command del(const std::string& key); + /// Returns an DEL command + + static Command del(const std::vector& keys); + /// Returns an DEL command + + static Command get(const std::string& key); + /// Returns an GET command + + static Command incr(const std::string& key, Int64 by = 0); + /// Returns an INCR or INCRBY command. Calls INCR when by is omitted or zero. + + static Command lindex(const std::string& list, Int64 index = 0); + /// Returns a LINDEX command + + static Command linsert(const std::string& list, bool before, const std::string& reference, const std::string& value); + /// Returns a LINSERT command + + static Command llen(const std::string& list); + /// Returns a LINDEX command + + static Command lpush(const std::string& list, const std::string& value, bool create = true); + /// Returns a LPUSH or LPUSHX (when create is false) command + + static Command lpush(const std::string& list, const std::vector& value, bool create = true); + /// Returns a LPUSH or LPUSHX (when create is false) command + + static Command lrange(const std::string& list, Int64 start = 0, Int64 stop = 0); + /// Returns a LRANGE command + static Command set(const std::string& key, const std::string& value, bool overwrite = true, const Poco::Timespan& expireTime = 0, bool create = true); /// Returns a SET command to set the key with a value + + static Command set(const std::string& key, Int64 value, bool overwrite = true, const Poco::Timespan& expireTime = 0, bool create = true); + /// Returns a SET command to set the key with a value + + static Command rpush(const std::string& list, const std::string& value, bool create = true); + /// Returns a RPUSH or RPUSHX (when create is false) command + + static Command rpush(const std::string& list, const std::vector& value, bool create = true); + /// Returns a RPUSH or RPUSHX (when create is false) command }; }} // namespace Poco::Redis diff --git a/Redis/src/Command.cpp b/Redis/src/Command.cpp index 648e06f49..578500648 100644 --- a/Redis/src/Command.cpp +++ b/Redis/src/Command.cpp @@ -16,6 +16,7 @@ // #include "Poco/Redis/Command.h" +#include "Poco/NumberFormatter.h" namespace Poco { namespace Redis { @@ -33,18 +34,131 @@ Command::~Command() { } +Command Command::append(const std::string& key, const std::string& value) +{ + Command cmd("APPEND"); + cmd.add(key).add(value); + return cmd; +} + +Command Command::del(const std::string& key) +{ + Command cmd("DEL"); + cmd.add(key); + return cmd; +} + +Command Command::del(const std::vector& keys) +{ + Command cmd("DEL"); + for(std::vector::const_iterator it = keys.begin(); it != keys.end(); ++it) + { + cmd.add(*it); + } + return cmd; +} + +Command Command::get(const std::string& key) +{ + Command cmd("GET"); + cmd.add(key); + return cmd; +} + +Command Command::incr(const std::string& key, Int64 by) +{ + Command cmd(by == 0 ? "INCR" : "INCRBY"); + cmd.add(key); + if ( by > 0 ) cmd.add(NumberFormatter::format(by)); + return cmd; +} + +Command Command::lindex(const std::string& list, Int64 index) +{ + Command cmd("LINDEX"); + cmd.add(list).add(NumberFormatter::format(index)); + return cmd; +} + +Command Command::linsert(const std::string& list, bool before, const std::string& reference, const std::string& value) +{ + Command cmd("LINSERT"); + cmd.add(list).add(before ? "BEFORE" : "AFTER").add(reference).add(value); + return cmd; +} + +Command Command::llen(const std::string& list) +{ + Command cmd("LLEN"); + cmd.add(list); + return cmd; +} + +Command Command::lpush(const std::string& list, const std::string& value, bool create) +{ + Command cmd(create ? "LPUSH" : "LPUSHX"); + cmd.add(list).add(value); + + return cmd; +} + +Command Command::lpush(const std::string& list, const std::vector& values, bool create) +{ + Command cmd(create ? "LPUSH" : "LPUSHX"); + cmd.add(list); + + for(std::vector::const_iterator it = values.begin(); it != values.end(); ++it) + { + cmd.add(*it); + } + + return cmd; +} + +Command Command::lrange(const std::string& list, Int64 start, Int64 stop) +{ + Command cmd("LRANGE"); + cmd.add(list).add(NumberFormatter::format(start)).add(NumberFormatter::format(stop)); + return cmd; +} + + Command Command::set(const std::string& key, const std::string& value, bool overwrite, const Poco::Timespan& expireTime, bool create) { Command cmd("SET"); - cmd.add(key); - cmd.add(value); + cmd.add(key).add(value); if ( ! overwrite ) cmd.add("NX"); if ( ! create ) cmd.add("XX"); if ( expireTime.totalMicroseconds() > 0 ) { - cmd.add("PX"); - cmd.add(expireTime.totalMilliseconds()); + cmd.add("PX").add(expireTime.totalMilliseconds()); + } + + return cmd; +} + +Command Command::set(const std::string& key, Int64 value, bool overwrite, const Poco::Timespan& expireTime, bool create) +{ + return set(key, NumberFormatter::format(value), overwrite, expireTime, create); +} + +Command Command::rpush(const std::string& list, const std::string& value, bool create) +{ + Command cmd(create ? "RPUSH" : "RPUSHX"); + cmd.add(list).add(value); + + return cmd; +} + +Command Command::rpush(const std::string& list, const std::vector& values, bool create) +{ + Command cmd(create ? "RPUSH" : "RPUSHX"); + cmd.add(list); + + for(std::vector::const_iterator it = values.begin(); it != values.end(); ++it) + { + cmd.add(*it); } return cmd; diff --git a/Redis/testsuite/src/RedisTest.cpp b/Redis/testsuite/src/RedisTest.cpp index 917d53e1e..651e457ce 100644 --- a/Redis/testsuite/src/RedisTest.cpp +++ b/Redis/testsuite/src/RedisTest.cpp @@ -80,9 +80,7 @@ void RedisTest::testAppend() return; } - Array delCommand; - delCommand.add("DEL") - .add("mykey"); + Command delCommand = Command::del("mykey"); try { _redis.execute(delCommand); @@ -111,10 +109,7 @@ void RedisTest::testAppend() fail(e.message()); } - Array appendCommand; - appendCommand.add("APPEND") - .add("mykey") - .add(" World"); + Command appendCommand = Command::append("mykey", " World"); try { Poco::Int64 result = _redis.execute(appendCommand); @@ -129,9 +124,7 @@ void RedisTest::testAppend() fail(e.message()); } - Array getCommand; - getCommand.add("GET") - .add("mykey"); + Command getCommand = Command::get("mykey"); try { BulkString result = _redis.execute(getCommand); @@ -179,11 +172,7 @@ void RedisTest::testIncr() return; } - Array command; - command.add("SET") - .add("mykey") - .add("10"); - + Command command = Command::set("mykey", "10"); // A set responds with a simple OK string try { @@ -195,10 +184,7 @@ void RedisTest::testIncr() fail(e.message()); } - command.clear(); - command.add("INCR") - .add("mykey"); - + command = Command::incr("mykey"); try { Poco::Int64 value = _redis.execute(command); @@ -218,11 +204,7 @@ void RedisTest::testIncrBy() return; } - Array command; - command.add("SET") - .add("mykey") - .add("10"); - + Command command = Command::set("mykey", "10"); // A set responds with a simple OK string try { @@ -234,11 +216,7 @@ void RedisTest::testIncrBy() fail(e.message()); } - command.clear(); - command.add("INCRBY") - .add("mykey") - .add("5"); - + command = Command::incr("mykey", 5); try { Poco::Int64 value = _redis.execute(command); @@ -429,9 +407,7 @@ void RedisTest::testRPush() } // Make sure the list is not there yet ... - Array delCommand; - delCommand.add("DEL") - .add("mylist"); + Command delCommand = Command::del("mylist"); try { _redis.execute(delCommand); @@ -445,48 +421,53 @@ void RedisTest::testRPush() fail(e.message()); } - for(int i = 0; i < 2; ++i) - { - Array command; - command.add("RPUSH") - .add("mylist"); - - if ( i == 0 ) command.add("Hello"); - else command.add("World"); - - // A RPUSH responds with an integer - try - { - Poco::Int64 result = _redis.execute(command); - assert(result == (i + 1)); - } - catch(RedisException &e) - { - fail(e.message()); - } - } - - Array command; - command.add("LRANGE") - .add("mylist") - .add("0") - .add("-1"); - try { - Array result = _redis.execute(command); + Command rpush = Command::rpush("mylist", "World"); + Poco::Int64 result = _redis.execute(rpush); + assert(result == 1); - assert(result.size() == 2); - BulkString value = result.get(0); - assert(value.value().compare("Hello") == 0); - - value = result.get(1); - assert(value.value().compare("World") == 0); + rpush = Command::rpush("mylist", "Hello"); + result = _redis.execute(rpush); + assert(result == 2); } catch(RedisException &e) { fail(e.message()); } + + Command llen = Command::llen("mylist"); + try + { + Poco::Int64 n = _redis.execute(llen); + assert(n == 2); + } + catch(RedisException &e) + { + fail(e.message()); + } + catch(Poco::BadCastException& e) + { + fail(e.message()); + } + + Command lrange = Command::lrange("mylist", 0, -1); + try + { + Array result = _redis.execute(lrange); + + assert(result.size() == 2); + assert(result.get(0).value().compare("World") == 0); + assert(result.get(1).value().compare("Hello") == 0); + } + catch(RedisException &e) + { + fail(e.message()); + } + catch(Poco::NullValueException &e) + { + fail(e.message()); + } } void RedisTest::testLIndex() @@ -498,9 +479,7 @@ void RedisTest::testLIndex() } // Make sure the list is not there yet ... - Array delCommand; - delCommand.add("DEL") - .add("mylist"); + Command delCommand = Command::del("mylist"); try { _redis.execute(delCommand); @@ -514,35 +493,25 @@ void RedisTest::testLIndex() fail(e.message()); } - for(int i = 0; i < 2; ++i) - { - Array command; - command.add("LPUSH") - .add("mylist"); - - if ( i == 0 ) command.add("World"); - else command.add("Hello"); - - // A RPUSH responds with an integer - try - { - Poco::Int64 result = _redis.execute(command); - assert(result == (i + 1)); - } - catch(RedisException &e) - { - fail(e.message()); - } - } - - Array command; - command.add("LINDEX") - .add("mylist") - .add("0"); - try { - BulkString result = _redis.execute(command); + Command lpush = Command::lpush("mylist", "World"); + Poco::Int64 result = _redis.execute(lpush); + assert(result == 1); + + lpush = Command::lpush("mylist", "Hello"); + result = _redis.execute(lpush); + assert(result == 2); + } + catch(RedisException &e) + { + fail(e.message()); + } + + Command lindex = Command::lindex("mylist", 0); + try + { + BulkString result = _redis.execute(lindex); assert(result.value().compare("Hello") == 0); } catch(RedisException &e) @@ -551,6 +520,67 @@ void RedisTest::testLIndex() } } +void RedisTest::testLInsert() +{ + if (!_connected) + { + std::cout << "Not connected, test skipped." << std::endl; + return; + } + + // Make sure the list is not there yet ... + Command delCommand = Command::del("mylist"); + try + { + _redis.execute(delCommand); + } + catch(RedisException& e) + { + fail(e.message()); + } + catch(Poco::BadCastException& e) + { + fail(e.message()); + } + + try + { + Command rpush = Command::rpush("mylist", "Hello"); + Poco::Int64 result = _redis.execute(rpush); + assert(result == 1); + + rpush = Command::rpush("mylist", "World"); + result = _redis.execute(rpush); + assert(result == 2); + + Command linsert = Command::linsert("mylist", true, "World", "There"); + result = _redis.execute(linsert); + assert(result == 3); + + Command lrange = Command::lrange("mylist", 0, -1); + Array range = _redis.execute(lrange); + assert(range.size() == 3); + + std::cout << range.toString() << std::endl; + + assert(range.get(0).value().compare("Hello") == 0); + assert(range.get(1).value().compare("There") == 0); + assert(range.get(2).value().compare("World") == 0); + } + catch(RedisException &e) + { + fail(e.message()); + } + catch(Poco::BadCastException &e) + { + fail(e.message()); + } + catch(Poco::NullValueException &e) + { + fail(e.message()); + } +} + void RedisTest::testMulti() { if (!_connected) @@ -806,6 +836,7 @@ CppUnit::Test* RedisTest::suite() CppUnit_addTest(pSuite, RedisTest, testStrlen); CppUnit_addTest(pSuite, RedisTest, testRPush); CppUnit_addTest(pSuite, RedisTest, testLIndex); + CppUnit_addTest(pSuite, RedisTest, testLInsert); CppUnit_addTest(pSuite, RedisTest, testMulti); CppUnit_addTest(pSuite, RedisTest, testPubSub); diff --git a/Redis/testsuite/src/RedisTest.h b/Redis/testsuite/src/RedisTest.h index 369f6fb9f..bf2d3d11b 100644 --- a/Redis/testsuite/src/RedisTest.h +++ b/Redis/testsuite/src/RedisTest.h @@ -40,6 +40,7 @@ public: void testStrlen(); void testRPush(); void testLIndex(); + void testLInsert(); void testMulti(); void testPubSub();