diff --git a/examples/data_types.cpp b/examples/data_types.cpp index 28bafb7..d714b66 100644 --- a/examples/data_types.cpp +++ b/examples/data_types.cpp @@ -1,9 +1,12 @@ /** -* Basic use of Redox to set and get a Redis key. +* Test special data type templates for multi-element replies using Redox. */ #include #include "../src/redox.hpp" +#include +#include +#include using namespace std; @@ -16,15 +19,40 @@ int main(int argc, char* argv[]) { rdx.command_blocking("LPUSH mylist 1 2 3 4 5 6 7 8 9 10"); - auto c = rdx.command_blocking>("LRANGE mylist -3 -1"); - if(!c->ok()) cerr << "Error with LRANGE: " << c->status() << endl; - for(const string& s : c->reply()) cout << s << endl; - c->free(); - -// if(!rdx.set("apples", "are great!")) // Set a key, check if succeeded -// cerr << "Failed to set key!" << endl; -// -// cout << "key = alaska, value = \"" << rdx.get("apples") << "\"" << endl; - - rdx.stop(); // Shut down the event loop + rdx.command>("LRANGE mylist 0 4", + [](const string& cmd, const vector& reply){ + cout << "Last 5 elements as a vector: "; + for(const string& s : reply) cout << s << " "; + cout << endl; + }, + [](const string& cmd, int status) { + cerr << "Error with LRANGE: " << status << endl; + } + ); + + rdx.command>("LRANGE mylist 0 4", + [](const string& cmd, const unordered_set& reply){ + cout << "Last 5 elements as an unordered set: "; + for(const string& s : reply) cout << s << " "; + cout << endl; + }, + [](const string& cmd, int status) { + cerr << "Error with LRANGE: " << status << endl; + } + ); + + rdx.command>("LRANGE mylist 0 4", + [&rdx](const string& cmd, const set& reply){ + cout << "Last 5 elements as a set: "; + for(const string& s : reply) cout << s << " "; + cout << endl; + rdx.stop_signal(); + }, + [&rdx](const string& cmd, int status) { + cerr << "Error with LRANGE: " << status << endl; + rdx.stop_signal(); + } + ); + + rdx.block(); // Shut down the event loop } diff --git a/src/command.cpp b/src/command.cpp index 8b6290b..3715003 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -3,7 +3,8 @@ */ #include -#include +#include +#include #include "command.hpp" @@ -134,4 +135,52 @@ void Command>::invoke_callback() { } } +template<> +void Command>::invoke_callback() { + + if(is_error_reply()) invoke_error(REDOX_ERROR_REPLY); + + else if(reply_obj->type != REDIS_REPLY_ARRAY) { + std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; + invoke_error(REDOX_WRONG_TYPE); + + } else { + std::unordered_set v; + size_t count = reply_obj->elements; + for(size_t i = 0; i < count; i++) { + redisReply* r = *(reply_obj->element + i); + if(r->type != REDIS_REPLY_STRING) { + std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; + invoke_error(REDOX_WRONG_TYPE); + } + v.insert(r->str); + } + invoke(v); + } +} + +template<> +void Command>::invoke_callback() { + + if(is_error_reply()) invoke_error(REDOX_ERROR_REPLY); + + else if(reply_obj->type != REDIS_REPLY_ARRAY) { + std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; + invoke_error(REDOX_WRONG_TYPE); + + } else { + std::set v; + size_t count = reply_obj->elements; + for(size_t i = 0; i < count; i++) { + redisReply* r = *(reply_obj->element + i); + if(r->type != REDIS_REPLY_STRING) { + std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; + invoke_error(REDOX_WRONG_TYPE); + } + v.insert(r->str); + } + invoke(v); + } +} + } // End namespace redox diff --git a/src/redox.cpp b/src/redox.cpp index 1fa1640..aec4319 100644 --- a/src/redox.cpp +++ b/src/redox.cpp @@ -308,42 +308,36 @@ void Redox::process_queued_commands(struct ev_loop* loop, ev_async* async, int r rdx->command_queue.pop(); if(rdx->process_queued_command(id)) {} - else if(rdx->process_queued_command(id)) {} + else if(rdx->process_queued_command(id)) {} else if(rdx->process_queued_command(id)) {} else if(rdx->process_queued_command(id)) {} else if(rdx->process_queued_command(id)) {} - else if(rdx->process_queued_command(id)) {} - else if(rdx->process_queued_command>(id)) {} + else if(rdx->process_queued_command(id)) {} + else if(rdx->process_queued_command>(id)) {} + else if(rdx->process_queued_command>(id)) {} + else if(rdx->process_queued_command>(id)) {} else throw runtime_error("[FATAL] Command pointer not found in any queue!"); } } -// ---------------------------- +// --------------------------------- +// get_command_map specializations +// --------------------------------- template<> unordered_map*>& -Redox::get_command_map() { -// cout << "redis reply command map at " << &commands_redis_reply << endl; - return commands_redis_reply; } +Redox::get_command_map() { return commands_redis_reply; } template<> unordered_map*>& -Redox::get_command_map() { -// cout << "string command map at " << &commands_string_r << endl; - return commands_string_r; } +Redox::get_command_map() { return commands_string_r; } template<> unordered_map*>& -Redox::get_command_map() { -// cout << "char* command map at " << &commands_char_p << endl; - return commands_char_p; } +Redox::get_command_map() { return commands_char_p; } template<> unordered_map*>& -Redox::get_command_map() { -// cout << "int command map at " << &commands_int << " has size: " << commands_int.size() << endl; - return commands_int; } +Redox::get_command_map() { return commands_int; } template<> unordered_map*>& -Redox::get_command_map() { -// cout << "long long int command map at " << &commands_long_long_int << endl; - return commands_long_long_int; } +Redox::get_command_map() { return commands_long_long_int; } template<> unordered_map*>& Redox::get_command_map() { return commands_null; } @@ -351,6 +345,12 @@ Redox::get_command_map() { return commands_null; } template<> unordered_map>*>& Redox::get_command_map>() { return commands_vector_string; } +template<> unordered_map>*>& +Redox::get_command_map>() { return commands_set_string; } + +template<> unordered_map>*>& +Redox::get_command_map>() { return commands_unordered_set_string; } + // ---------------------------- // Helpers // ---------------------------- diff --git a/src/redox.hpp b/src/redox.hpp index f1287a9..48820fb 100644 --- a/src/redox.hpp +++ b/src/redox.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -235,6 +236,8 @@ private: std::unordered_map*> commands_long_long_int; std::unordered_map*> commands_null; std::unordered_map>*> commands_vector_string; + std::unordered_map>*> commands_set_string; + std::unordered_map>*> commands_unordered_set_string; std::mutex command_map_guard; // Guards access to all of the above // Return the correct map from the above, based on the template specialization