From 0ab66fa1f14f402afa29f0229b9ae43f283367e8 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 7 Jun 2016 22:45:30 +0100 Subject: [PATCH] Stub implementation of a Redis backend. --- CMakeLists.txt | 2 - src/backends/CMakeLists.txt | 2 + src/backends/redis/CMakeLists.txt | 24 ++++ src/backends/redis/backend_redis.cpp | 158 +++++++++++++++++++++++++++ src/backends/redis/backend_redis.hpp | 71 ++++++++++++ src/pq/CMakeLists.txt | 2 + 6 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 src/backends/redis/CMakeLists.txt create mode 100644 src/backends/redis/backend_redis.cpp create mode 100644 src/backends/redis/backend_redis.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b3f19f6..3a69bc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,6 @@ configure_file( target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE ${Boost_INCLUDE_DIRS} - INTERFACE ${PostgreSQL_INCLUDE_DIRS} ) target_compile_features(${PROJECT_NAME} @@ -147,7 +146,6 @@ if (BUILD_TESTING) endif() target_link_libraries(${PROJECT_NAME} - INTERFACE ${PostgreSQL_LIBRARIES} INTERFACE ${Boost_LIBRARIES} INTERFACE ${bare_name}-pq INTERFACE ${bare_name}-inc diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt index 0ac6613..60e0a31 100644 --- a/src/backends/CMakeLists.txt +++ b/src/backends/CMakeLists.txt @@ -25,5 +25,7 @@ target_link_libraries(${PROJECT_NAME} #) add_subdirectory(postgresql) +add_subdirectory(redis) add_dependencies(${PROJECT_NAME} ${bare_name}-backend-postgresql) +add_dependencies(${PROJECT_NAME} ${bare_name}-backend-redis) diff --git a/src/backends/redis/CMakeLists.txt b/src/backends/redis/CMakeLists.txt new file mode 100644 index 0000000..8535712 --- /dev/null +++ b/src/backends/redis/CMakeLists.txt @@ -0,0 +1,24 @@ +project(${bare_name}-backend-redis CXX) + +find_package(hiredis 0.11.0 REQUIRED) + +add_library(${PROJECT_NAME} SHARED + backend_redis.cpp +) + +target_include_directories(${PROJECT_NAME} SYSTEM + PUBLIC ${Boost_INCLUDE_DIRS} + PRIVATE ${HIREDIS_INCLUDE_DIRS} +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE ${bare_name}-inc + PRIVATE ${bare_name}-pq + PRIVATE ${HIREDIS_LIBRARIES} +) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/static +) \ No newline at end of file diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp new file mode 100644 index 0000000..8ddfb66 --- /dev/null +++ b/src/backends/redis/backend_redis.cpp @@ -0,0 +1,158 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "dindexer" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "dindexer". If not, see . + */ + +#include "backend_redis.hpp" +#include "dindexer-machinery/recorddata.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace dindb { + namespace { + using RedisReply = std::unique_ptr; + } //unnamed namespace + + BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, + bool parConnect) : + m_conn(nullptr, &redisFree), + m_address(std::move(parAddress)), + m_port(parPort) { + if (parConnect) + this->connect(); + } + + BackendRedis::~BackendRedis() noexcept { + } + + void BackendRedis::connect() { + if (not m_conn) { + struct timeval timeout = {5, 500000}; //5.5 seconds? + RedisConnection conn( + redisConnectWithTimeout(m_address.c_str(), m_port, timeout), + &redisFree + ); + if (not conn) { + std::ostringstream oss; + oss << "Unable to connect to Redis server at " << m_address << ':' << m_port; + throw std::runtime_error(oss.str()); + } + if (conn->err) { + std::ostringstream oss; + oss << "Unable to connect to Redis server at " << m_address << ':' << m_port << + ": " << conn->errstr; + throw std::runtime_error(oss.str()); + } + std::swap(conn, m_conn); + } + } + + void BackendRedis::disconnect() { + m_conn.reset(); + } + + void BackendRedis::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + } + + void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + } + + void BackendRedis::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + } + + void BackendRedis::delete_tags (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + } + + void BackendRedis::delete_all_tags (const std::vector& parFiles, GroupIDType parSet) { + } + + void BackendRedis::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) { + } + + void BackendRedis::delete_group (const std::vector& parIDs, ConfirmDeleCallback parConf) { + } + + void BackendRedis::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { + assert(is_connected()); + std::string key; + { + std::ostringstream key_oss; + RedisReply incr_reply(static_cast(redisCommand(m_conn.get(), "incr set_counter")), &freeReplyObject); + key_oss << "sets:" << incr_reply->integer; + key = key_oss.str(); + } + + RedisReply insert_reply( + static_cast(redisCommand( + m_conn.get(), + "hmset %b name %b disk_label %b fs_uuid %b", + key.data(), + key.size(), + parSetData.name.data(), + parSetData.name.size(), + parSetData.disk_label.data(), + parSetData.disk_label.size(), + parSetData.fs_uuid.data(), + parSetData.fs_uuid.size() + )), + &freeReplyObject + ); + } + + bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { + return false; + } + + std::vector BackendRedis::locate_in_db (const std::string& parSearch, const TagList& parTags) { + return std::vector(); + } + + std::vector BackendRedis::locate_in_db (const mchlib::TigerHash& parSearch, const TagList& parTags) { + return std::vector(); + } + + std::vector BackendRedis::locate_sets_in_db (const std::string& parSearch, bool parCaseInsensitive) { + return std::vector(); + } + + std::vector BackendRedis::locate_sets_in_db (const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { + return std::vector(); + } + + std::vector BackendRedis::find_all_sets() { + return std::vector(); + } + + std::vector> BackendRedis::find_set_details (const std::vector& parSets) { + return std::vector>(); + } + + std::vector> BackendRedis::find_file_details (GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir) { + return std::vector>(); + } + + std::vector BackendRedis::find_paths_starting_by (GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath) { + return std::vector(); + } + + bool BackendRedis::is_connected() const { + return m_conn and not m_conn->err; + } +} //namespace dindb diff --git a/src/backends/redis/backend_redis.hpp b/src/backends/redis/backend_redis.hpp new file mode 100644 index 0000000..3ab92a0 --- /dev/null +++ b/src/backends/redis/backend_redis.hpp @@ -0,0 +1,71 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "dindexer" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "dindexer". If not, see . + */ + +#ifndef idB2F92EE07A004D5293FD0657EEE8F75B +#define idB2F92EE07A004D5293FD0657EEE8F75B + +#include "backends/db_backend.hpp" +#include +#include +#include + +struct redisContext; + +namespace dindb { + class BackendRedis : public Backend { + public: + BackendRedis ( BackendRedis&& ) = default; + BackendRedis ( std::string&& parAddress, uint16_t parPort, bool parConnect ); + virtual ~BackendRedis ( void ) noexcept; + + virtual void connect ( void ) override; + virtual void disconnect ( void ) override; + + virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) override; + virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) override; + virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) override; + virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) override; + virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) override; + virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) override; + + virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) override; + + virtual void write_files ( const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature ) override; + virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ) override; + + virtual std::vector locate_in_db ( const std::string& parSearch, const TagList& parTags ) override; + virtual std::vector locate_in_db ( const mchlib::TigerHash& parSearch, const TagList& parTags ) override; + virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ) override; + virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ) override; + + virtual std::vector find_all_sets ( void ) override; + virtual std::vector> find_set_details ( const std::vector& parSets ) override; + virtual std::vector> find_file_details ( GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ) override; + virtual std::vector find_paths_starting_by ( GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ) override; + + private: + using RedisConnection = std::unique_ptr; + + bool is_connected ( void ) const; + + RedisConnection m_conn; + std::string m_address; + uint16_t m_port; + }; +} //namespace dindb + +#endif diff --git a/src/pq/CMakeLists.txt b/src/pq/CMakeLists.txt index 6bda657..d164d80 100644 --- a/src/pq/CMakeLists.txt +++ b/src/pq/CMakeLists.txt @@ -12,10 +12,12 @@ add_library(${PROJECT_NAME} STATIC target_include_directories(${PROJECT_NAME} PRIVATE ${libpqtypes_INCLUDE_DIRS} + PRIVATE ${PostgreSQL_INCLUDE_DIRS} ) target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE pqtypes + PRIVATE ${PostgreSQL_LIBRARIES} ) target_compile_features(${PROJECT_NAME}