diff --git a/src/backends/redis/find.cpp b/src/backends/redis/find.cpp index f6b6e96..737988a 100644 --- a/src/backends/redis/find.cpp +++ b/src/backends/redis/find.cpp @@ -174,11 +174,10 @@ namespace dindb { std::vector find_all_sets (redis::IncRedis& parRedis) { using dincore::split_and_trim; - using dinhelp::lexical_cast; std::vector retval; for (const auto& itm : parRedis.scan(PROGRAM_NAME ":set:*")) { - retval.push_back(lexical_cast(split_and_trim(itm, ':').back())); + retval.push_back(dinhelp::lexical_cast(split_and_trim(itm, ':').back())); } return retval; } diff --git a/src/backends/redis/incredis_batch.hpp b/src/backends/redis/incredis_batch.hpp index b173489..2112892 100644 --- a/src/backends/redis/incredis_batch.hpp +++ b/src/backends/redis/incredis_batch.hpp @@ -19,11 +19,20 @@ #define id3C772A92AB0E440DA84DAFD807BC962D #include "batch.hpp" +#include "helpers/sequence_bt.hpp" #include +#include +#include namespace redis { class IncRedisBatch { public: + enum ZADD_Mode { + ZADD_XX_UpdateOnly, + ZADD_NX_AlwaysAdd, + ZADD_None + }; + IncRedisBatch ( void ) = delete; IncRedisBatch ( IncRedisBatch&& ) = default; IncRedisBatch ( const Batch& ) = delete; @@ -55,6 +64,10 @@ namespace redis { template IncRedisBatch& sadd ( boost::string_ref parKey, Args&&... parArgs ); + //Sorted set + template + IncRedisBatch& zadd ( boost::string_ref parKey, ZADD_Mode parMode, bool parChange, Args&&... parArgs ); + //Script IncRedisBatch& script_flush ( void ); @@ -62,6 +75,11 @@ namespace redis { Batch m_batch; }; + namespace implem { + template + void run_conv_floats_to_strings ( Batch& parBatch, dinhelp::bt::index_seq, Args&&... parArgs ); + } //namespace implem + template IncRedisBatch& IncRedisBatch::hmget (boost::string_ref parKey, Args&&... parArgs) { static_assert(sizeof...(Args) > 0, "No fields specified"); @@ -71,6 +89,7 @@ namespace redis { template IncRedisBatch& IncRedisBatch::hmset (boost::string_ref parKey, Args&&... parArgs) { + static_assert(sizeof...(Args) >= 1, "No parameters specified"); static_assert(sizeof...(Args) % 2 == 0, "Uneven number of parameters received"); m_batch.run("HMSET", parKey, std::forward(parArgs)...); return *this; @@ -89,6 +108,65 @@ namespace redis { m_batch.run("DEL", std::forward(parArgs)...); return *this; } + + template + IncRedisBatch& IncRedisBatch::zadd (boost::string_ref parKey, ZADD_Mode parMode, bool parChange, Args&&... parArgs) { + static_assert(sizeof...(Args) >= 1, "No score/value pairs specified"); + static_assert(sizeof...(Args) % 2 == 0, "Uneven number of parameters received"); + + using dinhelp::bt::index_range; + + if (parChange) { + if (ZADD_None == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, "CH", std::forward(parArgs)...); + else if (ZADD_NX_AlwaysAdd == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, "NX", "CH", std::forward(parArgs)...); + else if (ZADD_XX_UpdateOnly == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, "XX", "CH", std::forward(parArgs)...); + } + else { + if (ZADD_None == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, std::forward(parArgs)...); + else if (ZADD_NX_AlwaysAdd == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, "NX", std::forward(parArgs)...); + else if (ZADD_XX_UpdateOnly == parMode) + implem::run_conv_floats_to_strings(m_batch, index_range<0, sizeof...(Args)>(), "ZADD", parKey, "XX", std::forward(parArgs)...); + } + return *this; + } + + namespace implem { + template =IGNORE_COUNT) && ((IDX-IGNORE_COUNT)%2)==0> + struct stringize_or_forward_impl { + typedef T type; + static T&& do_it ( T&& parT ) { return std::forward(parT); } + }; + template + struct stringize_or_forward_impl { + static_assert(std::is_floating_point::value, "Scores must be given as floating point values"); + typedef std::string type; + static std::string do_it ( T parT ) { return boost::lexical_cast(parT); } + }; + + template + auto stringize_or_forward (T&& parValue) -> typename stringize_or_forward_impl::type { + return stringize_or_forward_impl::do_it(std::forward(parValue)); + } + + template + void run_conv_floats_to_strings_impl (Batch& parBatch, dinhelp::bt::index_seq, Args&&... parArgs) { + static_assert(sizeof...(I) == sizeof...(Args), "Wrong number of indices"); + static_assert(PreArgsCount <= sizeof...(I), "Can't ignore more arguments than those that were received"); + parBatch.run(stringize_or_forward(std::forward(parArgs))...); + } + + template + void run_conv_floats_to_strings (Batch& parBatch, dinhelp::bt::index_seq, Args&&... parArgs) { + static_assert(sizeof...(Args) >= sizeof...(I), "Unexpected count, there should be at least as many argument as there are indices"); + constexpr const auto pre_args_count = sizeof...(Args) - sizeof...(I); + run_conv_floats_to_strings_impl(parBatch, dinhelp::bt::index_range<0, sizeof...(Args)>(), std::forward(parArgs)...); + }; + } //namespace implem } //namespace redis #endif