diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index fd18299..6d9db6c 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace dindb { namespace { @@ -93,6 +94,23 @@ namespace dindb { } return retval; } + + std::string read_script (const dincore::SearchPaths& parSearch, const char* parName) { + const auto full_path = parSearch.first_hit(boost::string_ref(parName)); + if (full_path.empty()) { + const std::string msg = std::string("Unable to locate and load Lua script \"") + parName + "\" from any of the given search paths"; + throw std::runtime_error(msg); + } + + std::ifstream script(full_path); + std::string retval; + script.seekg(0, std::ios::end); + retval.reserve(script.tellg()); + script.seekg(0, std::ios::beg); + retval.assign(std::istreambuf_iterator(script), std::istreambuf_iterator()); + + return retval; + } } //unnamed namespace } //namespace dindb @@ -165,6 +183,9 @@ namespace dindb { oss << "Error connecting to Redis: " << m_redis.connection_error(); throw std::runtime_error(oss.str()); } + + m_script_save = m_redis.make_script(read_script(m_lua_script_paths, "save.lua")); + m_script_delete = m_redis.make_script(read_script(m_lua_script_paths, "delete.lua")); } void BackendRedis::disconnect() { diff --git a/src/backends/redis/backend_redis.hpp b/src/backends/redis/backend_redis.hpp index d7ced97..040a22a 100644 --- a/src/backends/redis/backend_redis.hpp +++ b/src/backends/redis/backend_redis.hpp @@ -20,6 +20,7 @@ #include "backends/db_backend.hpp" #include "command.hpp" +#include "script.hpp" #include "dindexer-core/searchpaths.hpp" #include #include @@ -58,6 +59,8 @@ namespace dindb { private: redis::Command m_redis; + redis::Script m_script_save; + redis::Script m_script_delete; dincore::SearchPaths m_lua_script_paths; uint16_t m_database; }; diff --git a/src/backends/redis/script.cpp b/src/backends/redis/script.cpp index af7eeac..d88ec39 100644 --- a/src/backends/redis/script.cpp +++ b/src/backends/redis/script.cpp @@ -18,9 +18,15 @@ #include "script.hpp" namespace redis { + Script::Script() : + m_sha1(), + m_manager(nullptr) + { + } + Script::Script (boost::string_ref parSha1, ScriptManager& parManager) : m_sha1(parSha1), - m_manager(parManager) + m_manager(&parManager) { } } //namespace redis diff --git a/src/backends/redis/script.hpp b/src/backends/redis/script.hpp index e169bf6..033469c 100644 --- a/src/backends/redis/script.hpp +++ b/src/backends/redis/script.hpp @@ -23,12 +23,15 @@ #include "helpers/sequence_bt.hpp" #include #include +#include +#include namespace redis { class ScriptManager; class Script { public: + Script ( void ); Script ( Script&& ) = default; Script ( boost::string_ref parSha1, ScriptManager& parManager ); ~Script ( void ) noexcept = default; @@ -36,12 +39,14 @@ namespace redis { template void run ( Batch& parBatch, const std::tuple& parKeys, const std::tuple& parValues ); + Script& operator= ( Script&& ) = default; + private: template void run_with_indices ( Batch& parBatch, const std::tuple& parKeys, const std::tuple& parValues, dinhelp::bt::index_seq, dinhelp::bt::index_seq ); boost::string_ref m_sha1; - ScriptManager& m_manager; + ScriptManager* m_manager; }; template @@ -62,6 +67,9 @@ namespace redis { static_assert(sizeof...(Keys) == std::tuple_size::value, "Wrong key count"); static_assert(sizeof...(Values) == std::tuple_size::value, "Wrong value count"); + assert(not m_sha1.empty()); + assert(m_manager); + parBatch.run( "EVALSHA", m_sha1,