From 5203fbece2a942037f86fc0dc15ece1b109e9e18 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 22 May 2016 02:53:54 +0100 Subject: [PATCH 001/170] Move db tagging functions to a new postgresql backend lib. --- CMakeLists.txt | 1 + .../backends/postgresql/tag.hpp | 0 src/backends/postgresql/CMakeLists.txt | 21 +++++++++++++++++++ .../postgresql/tag.cpp} | 2 +- src/tag/CMakeLists.txt | 2 +- src/tag/main.cpp | 2 +- 6 files changed, 25 insertions(+), 3 deletions(-) rename src/tag/tag_postgres.hpp => include/backends/postgresql/tag.hpp (100%) create mode 100644 src/backends/postgresql/CMakeLists.txt rename src/{tag/tag_postgres.cpp => backends/postgresql/tag.cpp} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75f887d..1cee3d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ add_subdirectory(src/common) add_subdirectory(src/machinery) add_subdirectory(lib/pbl) add_subdirectory(lib/glob2regex) +add_subdirectory(src/backends/postgresql) #Actions add_subdirectory(src/main) diff --git a/src/tag/tag_postgres.hpp b/include/backends/postgresql/tag.hpp similarity index 100% rename from src/tag/tag_postgres.hpp rename to include/backends/postgresql/tag.hpp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt new file mode 100644 index 0000000..a57cd59 --- /dev/null +++ b/src/backends/postgresql/CMakeLists.txt @@ -0,0 +1,21 @@ +project(${bare_name}-backend-postgresql CXX) + +add_library(${PROJECT_NAME} STATIC + tag.cpp +) + +#target_include_directories(${PROJECT_NAME} +#) +#target_include_directories(${PROJECT_NAME} SYSTEM +#) + +target_link_libraries(${PROJECT_NAME} + PRIVATE ${bare_name}-if + PRIVATE pq +) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/static +) diff --git a/src/tag/tag_postgres.cpp b/src/backends/postgresql/tag.cpp similarity index 99% rename from src/tag/tag_postgres.cpp rename to src/backends/postgresql/tag.cpp index 7a41096..cc46cea 100644 --- a/src/tag/tag_postgres.cpp +++ b/src/backends/postgresql/tag.cpp @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -#include "tag_postgres.hpp" +#include "backends/postgresql/tag.hpp" #include "pq/connection.hpp" #include "dindexer-common/settings.hpp" #include diff --git a/src/tag/CMakeLists.txt b/src/tag/CMakeLists.txt index e642dc2..3a992c6 100644 --- a/src/tag/CMakeLists.txt +++ b/src/tag/CMakeLists.txt @@ -3,7 +3,6 @@ project(${bare_name}-tag CXX) add_executable(${PROJECT_NAME} main.cpp commandline.cpp - tag_postgres.cpp ) target_include_directories(${PROJECT_NAME} @@ -16,6 +15,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common PRIVATE glob2regex + PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/tag/main.cpp b/src/tag/main.cpp index ed0e7e1..fba9d66 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -18,7 +18,7 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "tag_postgres.hpp" +#include "backends/postgresql/tag.hpp" #include "dindexer-common/split_tags.hpp" #include "glob2regex/glob2regex.hpp" #include "enum.h" From 45ecdb9a2b66ab3c0ffe0308f826269ee107049f Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 22 May 2016 03:02:39 +0100 Subject: [PATCH 002/170] Move db delete to the postgresql backend lib. --- .../backends/postgresql/delete.hpp | 0 src/backends/postgresql/CMakeLists.txt | 3 ++- .../postgre_delete.cpp => backends/postgresql/delete.cpp} | 2 +- src/delete/CMakeLists.txt | 2 +- src/delete/main.cpp | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) rename src/delete/postgre_delete.hpp => include/backends/postgresql/delete.hpp (100%) rename src/{delete/postgre_delete.cpp => backends/postgresql/delete.cpp} (98%) diff --git a/src/delete/postgre_delete.hpp b/include/backends/postgresql/delete.hpp similarity index 100% rename from src/delete/postgre_delete.hpp rename to include/backends/postgresql/delete.hpp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index a57cd59..01e7159 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -2,6 +2,7 @@ project(${bare_name}-backend-postgresql CXX) add_library(${PROJECT_NAME} STATIC tag.cpp + delete.cpp ) #target_include_directories(${PROJECT_NAME} @@ -11,7 +12,7 @@ add_library(${PROJECT_NAME} STATIC target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if - PRIVATE pq + PRIVATE ${bare_name}-pq ) install(TARGETS ${PROJECT_NAME} diff --git a/src/delete/postgre_delete.cpp b/src/backends/postgresql/delete.cpp similarity index 98% rename from src/delete/postgre_delete.cpp rename to src/backends/postgresql/delete.cpp index 6fe550c..610fabb 100644 --- a/src/delete/postgre_delete.cpp +++ b/src/backends/postgresql/delete.cpp @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -#include "postgre_delete.hpp" +#include "backends/postgresql/delete.hpp" #include "pq/connection.hpp" #include "dindexer-common/settings.hpp" #include "helpers/infix_iterator.hpp" diff --git a/src/delete/CMakeLists.txt b/src/delete/CMakeLists.txt index 7d05e34..1563f35 100644 --- a/src/delete/CMakeLists.txt +++ b/src/delete/CMakeLists.txt @@ -3,7 +3,6 @@ project(${bare_name}-delete CXX) add_executable(${PROJECT_NAME} main.cpp commandline.cpp - postgre_delete.cpp ) target_include_directories(${PROJECT_NAME} @@ -13,6 +12,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common + PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/delete/main.cpp b/src/delete/main.cpp index c510d6f..29a1332 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -18,7 +18,7 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "postgre_delete.hpp" +#include "backends/postgresql/delete.hpp" #include #include #include From 641261306fe0d8b294a228e9aa8e124956556ecb Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 22 May 2016 03:05:58 +0100 Subject: [PATCH 003/170] Move db locate functions to the postgresql backend lib. --- .../backends/postgresql/locate.hpp | 0 src/backends/postgresql/CMakeLists.txt | 1 + .../postgre_locate.cpp => backends/postgresql/locate.cpp} | 2 +- src/locate/CMakeLists.txt | 2 +- src/locate/main.cpp | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) rename src/locate/postgre_locate.hpp => include/backends/postgresql/locate.hpp (100%) rename src/{locate/postgre_locate.cpp => backends/postgresql/locate.cpp} (99%) diff --git a/src/locate/postgre_locate.hpp b/include/backends/postgresql/locate.hpp similarity index 100% rename from src/locate/postgre_locate.hpp rename to include/backends/postgresql/locate.hpp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 01e7159..0fbcaa5 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -3,6 +3,7 @@ project(${bare_name}-backend-postgresql CXX) add_library(${PROJECT_NAME} STATIC tag.cpp delete.cpp + locate.cpp ) #target_include_directories(${PROJECT_NAME} diff --git a/src/locate/postgre_locate.cpp b/src/backends/postgresql/locate.cpp similarity index 99% rename from src/locate/postgre_locate.cpp rename to src/backends/postgresql/locate.cpp index 00e0361..eb68e02 100644 --- a/src/locate/postgre_locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -#include "postgre_locate.hpp" +#include "backends/postgresql/locate.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/tiger.hpp" #include diff --git a/src/locate/CMakeLists.txt b/src/locate/CMakeLists.txt index 9b68d0f..cddde1d 100644 --- a/src/locate/CMakeLists.txt +++ b/src/locate/CMakeLists.txt @@ -3,7 +3,6 @@ project(${bare_name}-locate CXX) add_executable(${PROJECT_NAME} main.cpp commandline.cpp - postgre_locate.cpp hash.cpp ) @@ -17,6 +16,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-common PRIVATE ${bare_name}-machinery PRIVATE glob2regex + PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/locate/main.cpp b/src/locate/main.cpp index 7b619c4..a30ae5f 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -16,7 +16,7 @@ */ #include "commandline.hpp" -#include "postgre_locate.hpp" +#include "backends/postgresql/locate.hpp" #include "dindexer-common/settings.hpp" #include "dindexer-common/split_tags.hpp" #include "dindexerConfig.h" From b6d45eee3c00bb9b3fed9fb8c0063872268c66f9 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 22 May 2016 03:17:26 +0100 Subject: [PATCH 004/170] Move db scan functions to the postgresql backend lib. --- src/scan/dbbackend.hpp => include/backends/postgresql/scan.hpp | 0 src/backends/postgresql/CMakeLists.txt | 1 + src/{scan/dbbackend.cpp => backends/postgresql/scan.cpp} | 2 +- src/scan/CMakeLists.txt | 2 +- src/scan/main.cpp | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) rename src/scan/dbbackend.hpp => include/backends/postgresql/scan.hpp (100%) rename src/{scan/dbbackend.cpp => backends/postgresql/scan.cpp} (99%) diff --git a/src/scan/dbbackend.hpp b/include/backends/postgresql/scan.hpp similarity index 100% rename from src/scan/dbbackend.hpp rename to include/backends/postgresql/scan.hpp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 0fbcaa5..00d2afc 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(${PROJECT_NAME} STATIC tag.cpp delete.cpp locate.cpp + scan.cpp ) #target_include_directories(${PROJECT_NAME} diff --git a/src/scan/dbbackend.cpp b/src/backends/postgresql/scan.cpp similarity index 99% rename from src/scan/dbbackend.cpp rename to src/backends/postgresql/scan.cpp index 04f2ebc..14328f4 100644 --- a/src/scan/dbbackend.cpp +++ b/src/backends/postgresql/scan.cpp @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -#include "dbbackend.hpp" +#include "backends/postgresql/scan.hpp" #include "pq/connection.hpp" #include "dindexer-common/settings.hpp" #include "dindexer-machinery/recorddata.hpp" diff --git a/src/scan/CMakeLists.txt b/src/scan/CMakeLists.txt index 7137249..b5e4d9e 100644 --- a/src/scan/CMakeLists.txt +++ b/src/scan/CMakeLists.txt @@ -4,7 +4,6 @@ include(WithMediaAutodetect) add_executable(${PROJECT_NAME} main.cpp - dbbackend.cpp commandline.cpp ) @@ -16,6 +15,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common PRIVATE ${bare_name}-machinery + PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/scan/main.cpp b/src/scan/main.cpp index a8c9cac..e44b871 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -25,7 +25,7 @@ #include "dindexer-common/common_info.hpp" #include "dindexer-common/settings.hpp" #include "commandline.hpp" -#include "dbbackend.hpp" +#include "backends/postgresql/scan.hpp" #include "dindexer-machinery/scantask/dirtree.hpp" #include "dindexer-machinery/scantask/mediatype.hpp" #include "dindexer-machinery/scantask/hashing.hpp" From baa67138eb5bcbcae8e99852139eb73240f6fcbe Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 23 May 2016 10:06:59 +0200 Subject: [PATCH 005/170] Move MaxSizedArray to helpers include dir. --- {src/navigate => include/helpers}/MaxSizedArray.hpp | 8 ++++---- {src/navigate => include/helpers}/MaxSizedArray.inl | 4 ++-- {src/navigate => include/helpers/implem}/AutomemBase.hpp | 4 ++-- {src/navigate => include/helpers/implem}/AutomemBase.inl | 4 ++-- .../navigate => include/helpers/implem}/IteratorOnPtr.hpp | 4 ++-- src/navigate/dbsource.hpp | 4 +++- 6 files changed, 15 insertions(+), 13 deletions(-) rename {src/navigate => include/helpers}/MaxSizedArray.hpp (97%) rename {src/navigate => include/helpers}/MaxSizedArray.inl (99%) rename {src/navigate => include/helpers/implem}/AutomemBase.hpp (98%) rename {src/navigate => include/helpers/implem}/AutomemBase.inl (99%) rename {src/navigate => include/helpers/implem}/IteratorOnPtr.hpp (99%) diff --git a/src/navigate/MaxSizedArray.hpp b/include/helpers/MaxSizedArray.hpp similarity index 97% rename from src/navigate/MaxSizedArray.hpp rename to include/helpers/MaxSizedArray.hpp index 6082b7b..d147176 100644 --- a/src/navigate/MaxSizedArray.hpp +++ b/include/helpers/MaxSizedArray.hpp @@ -18,15 +18,15 @@ #ifndef idBC9F804ADD33468A9C7657E823FFC706 #define idBC9F804ADD33468A9C7657E823FFC706 -#include "AutomemBase.hpp" -#include "IteratorOnPtr.hpp" +#include "implem/AutomemBase.hpp" +#include "implem/IteratorOnPtr.hpp" #include #include #include #include #include -namespace din { +namespace dinhelp { const size_t MAXSZARR_MAX_STACK_ALLOC_SIZE = MAX_STACK_ALLOC_SIZE; //TODO: add a template parameter to force stack allocation regardless of @@ -107,7 +107,7 @@ namespace din { T* m_localMem; //A copy of memory pointer is required size_type m_used; }; -} //namespace din +} //namespace dinhelp #include "MaxSizedArray.inl" diff --git a/src/navigate/MaxSizedArray.inl b/include/helpers/MaxSizedArray.inl similarity index 99% rename from src/navigate/MaxSizedArray.inl rename to include/helpers/MaxSizedArray.inl index e89f6a2..f46661d 100644 --- a/src/navigate/MaxSizedArray.inl +++ b/include/helpers/MaxSizedArray.inl @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -namespace din { +namespace dinhelp { ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template @@ -278,4 +278,4 @@ namespace din { throw std::length_error("Unable to reserve more memory than the build-time size for MaxSizedArray"); } } -} //namespace din +} //namespace dinhelp diff --git a/src/navigate/AutomemBase.hpp b/include/helpers/implem/AutomemBase.hpp similarity index 98% rename from src/navigate/AutomemBase.hpp rename to include/helpers/implem/AutomemBase.hpp index fd2d78c..c632976 100644 --- a/src/navigate/AutomemBase.hpp +++ b/include/helpers/implem/AutomemBase.hpp @@ -30,7 +30,7 @@ # define ASSERTIONSENABLED #endif -namespace din { +namespace dinhelp { const size_t MAX_STACK_ALLOC_SIZE = 128; ///------------------------------------------------------------------------- @@ -81,7 +81,7 @@ namespace din { void operator= (const AutomemRawBase_stack&); typename std::aligned_storage::type m_localMem[S]; }; -} //namespace din +} //namespace dinhelp #include "AutomemBase.inl" diff --git a/src/navigate/AutomemBase.inl b/include/helpers/implem/AutomemBase.inl similarity index 99% rename from src/navigate/AutomemBase.inl rename to include/helpers/implem/AutomemBase.inl index ba25d2e..6909bda 100644 --- a/src/navigate/AutomemBase.inl +++ b/include/helpers/implem/AutomemBase.inl @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -namespace din { +namespace dinhelp { namespace { #if defined(ASSERTIONSENABLED) const char g_guard = 0xAB; @@ -115,4 +115,4 @@ namespace din { #endif return new(location) T(std::forward(parArgs)...); } -} //namespace din +} //namespace dinhelp diff --git a/src/navigate/IteratorOnPtr.hpp b/include/helpers/implem/IteratorOnPtr.hpp similarity index 99% rename from src/navigate/IteratorOnPtr.hpp rename to include/helpers/implem/IteratorOnPtr.hpp index c384c40..4845592 100644 --- a/src/navigate/IteratorOnPtr.hpp +++ b/include/helpers/implem/IteratorOnPtr.hpp @@ -23,7 +23,7 @@ #include #include -namespace din { +namespace dinhelp { namespace implem_iop { template class IteratorOnPtr_base : public std::iterator { @@ -309,6 +309,6 @@ namespace din { this->MoveIterator(-parOther); return *this; } -} //namespace din +} //namespace dinhelp #endif diff --git a/src/navigate/dbsource.hpp b/src/navigate/dbsource.hpp index 5da8df9..acef295 100644 --- a/src/navigate/dbsource.hpp +++ b/src/navigate/dbsource.hpp @@ -20,7 +20,7 @@ #include "dindexer-machinery/recorddata.hpp" #include "flatinsertin2dlist.hpp" -#include "MaxSizedArray.hpp" +#include "helpers/MaxSizedArray.hpp" #include #include #include @@ -40,6 +40,8 @@ namespace pq { } //namespace pq namespace din { + using dinhelp::MaxSizedArray; + enum SetDetails { SetDetail_Desc = 0x01, SetDetail_Type = 0x02, From 70caa9e26c3c7401911e33628e64dd3082c9dfe3 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 23 May 2016 19:28:50 +0200 Subject: [PATCH 006/170] Move db dbsource files to the postgresql backend lib and rename namespace. --- .../backends/postgresql}/dbsource.hpp | 20 +++++------ include/backends/postgresql/delete.hpp | 10 +++--- include/backends/postgresql/locate.hpp | 15 ++++---- include/backends/postgresql/scan.hpp | 14 ++++---- include/backends/postgresql/settings.hpp | 34 +++++++++++++++++++ include/backends/postgresql/tag.hpp | 20 +++++------ include/dindexer-common/settings.hpp | 12 ++----- .../helpers}/flatinsertin2dlist.hpp | 14 ++++++-- .../helpers/implem}/flatinsertin2dlist.inl | 4 +-- src/backends/postgresql/CMakeLists.txt | 1 + .../postgresql}/dbsource.cpp | 12 +++---- src/backends/postgresql/delete.cpp | 8 ++--- src/backends/postgresql/locate.cpp | 17 +++++----- src/backends/postgresql/scan.cpp | 10 +++--- src/backends/postgresql/tag.cpp | 17 +++++----- src/common/settings.cpp | 8 ++--- src/delete/main.cpp | 6 ++-- src/locate/main.cpp | 16 ++++----- src/navigate/CMakeLists.txt | 2 +- src/navigate/listdircontent.cpp | 8 ++--- src/navigate/listdircontent.hpp | 9 +++-- src/navigate/main.cpp | 10 +++--- src/scan/main.cpp | 8 ++--- src/tag/main.cpp | 22 ++++++------ 24 files changed, 166 insertions(+), 131 deletions(-) rename {src/navigate => include/backends/postgresql}/dbsource.hpp (92%) create mode 100644 include/backends/postgresql/settings.hpp rename {src/navigate => include/helpers}/flatinsertin2dlist.hpp (73%) rename {src/navigate => include/helpers/implem}/flatinsertin2dlist.inl (98%) rename src/{navigate => backends/postgresql}/dbsource.cpp (95%) diff --git a/src/navigate/dbsource.hpp b/include/backends/postgresql/dbsource.hpp similarity index 92% rename from src/navigate/dbsource.hpp rename to include/backends/postgresql/dbsource.hpp index acef295..087435a 100644 --- a/src/navigate/dbsource.hpp +++ b/include/backends/postgresql/dbsource.hpp @@ -19,7 +19,7 @@ #define id63F35BA8B3C94A129291D963ABE66018 #include "dindexer-machinery/recorddata.hpp" -#include "flatinsertin2dlist.hpp" +#include "helpers/flatinsertin2dlist.hpp" #include "helpers/MaxSizedArray.hpp" #include #include @@ -31,17 +31,15 @@ #include #include -namespace dinlib { - struct SettingsDB; -} //namespace dinlib - namespace pq { class Connection; } //namespace pq -namespace din { +namespace dinbpostgres { using dinhelp::MaxSizedArray; + struct Settings; + enum SetDetails { SetDetail_Desc = 0x01, SetDetail_Type = 0x02, @@ -69,7 +67,7 @@ namespace din { class DBSource { public: - explicit DBSource ( const dinlib::SettingsDB& parDBSettings ); + explicit DBSource ( const Settings& parDBSettings ); ~DBSource ( void ) noexcept; void disconnect ( void ); @@ -121,8 +119,9 @@ namespace din { template auto DBSource::set_details (const std::vector& parIDs) -> std::vector> { + using dinhelp::FlatInsertIn2DList; typedef std::vector> ReturnType; - typedef void(din::FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); + typedef void(FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); const auto columns = implem::make_columns_vec(m_set_details_map); @@ -135,8 +134,9 @@ namespace din { template auto DBSource::file_details (uint32_t parSetID, uint16_t parLevel, boost::string_ref parDir) -> std::vector> { + using dinhelp::FlatInsertIn2DList; typedef std::vector> ReturnType; - typedef void(din::FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); + typedef void(FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); const auto columns = implem::make_columns_vec(m_file_details_map); @@ -146,6 +146,6 @@ namespace din { this->query_files_in_dir(columns, parDir, parLevel, parSetID, std::bind(pback_func, &flat_list, std::placeholders::_1)); return list; } -} //namespace din +} //namespace dinbpostgres #endif diff --git a/include/backends/postgresql/delete.hpp b/include/backends/postgresql/delete.hpp index f6221b5..85bba77 100644 --- a/include/backends/postgresql/delete.hpp +++ b/include/backends/postgresql/delete.hpp @@ -24,15 +24,13 @@ #include #include -namespace dinlib { - struct SettingsDB; -} //namespace dinlib +namespace dinbpostgres { + struct Settings; -namespace din { using IDDescMap = std::map; using ConfirmDeleCallback = std::function; - void delete_group_from_db ( const dinlib::SettingsDB& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf ); -} //namespace din + void delete_group_from_db ( const Settings& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf ); +} //namespace dinbpostgres #endif diff --git a/include/backends/postgresql/locate.hpp b/include/backends/postgresql/locate.hpp index b30c6fb..e982a17 100644 --- a/include/backends/postgresql/locate.hpp +++ b/include/backends/postgresql/locate.hpp @@ -18,7 +18,6 @@ #ifndef id1AE05A59AE0E4A4490040FD85D9AF665 #define id1AE05A59AE0E4A4490040FD85D9AF665 -#include "dindexer-common/settings.hpp" #include #include #include @@ -28,7 +27,9 @@ namespace mchlib { struct TigerHash; } //namespace mchlib -namespace din { +namespace dinbpostgres { + struct Settings; + struct LocatedItem { std::string path; uint64_t id; @@ -44,10 +45,10 @@ namespace din { using TagList = std::vector; - std::vector locate_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, const TagList& parTags ); - std::vector locate_in_db ( const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags ); - std::vector locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive ); - std::vector locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); -} //namespace din + std::vector locate_in_db ( const Settings& parDB, const std::string& parSearch, const TagList& parTags ); + std::vector locate_in_db ( const Settings& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags ); + std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, bool parCaseInsensitive ); + std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); +} //namespace dinbpostgres #endif diff --git a/include/backends/postgresql/scan.hpp b/include/backends/postgresql/scan.hpp index 943c74e..6dee13f 100644 --- a/include/backends/postgresql/scan.hpp +++ b/include/backends/postgresql/scan.hpp @@ -22,10 +22,6 @@ #include #include -namespace dinlib { - struct SettingsDB;; -} //namespace dinlib - namespace mchlib { struct FileRecordData; struct SetRecordData; @@ -33,9 +29,11 @@ namespace mchlib { struct TigerHash; } //namespace mchlib -namespace din { - void write_to_db ( const dinlib::SettingsDB& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); - bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parHash ); -} //namespace din +namespace dinbpostgres { + struct Settings;; + + void write_to_db ( const Settings& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); + bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const Settings& parDB, const mchlib::TigerHash& parHash ); +} //namespace dinbpostgres #endif diff --git a/include/backends/postgresql/settings.hpp b/include/backends/postgresql/settings.hpp new file mode 100644 index 0000000..5c22c1a --- /dev/null +++ b/include/backends/postgresql/settings.hpp @@ -0,0 +1,34 @@ +/* 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 idC895D12FEB324387A37FF631E0C09560 +#define idC895D12FEB324387A37FF631E0C09560 + +#include +#include + +namespace dinbpostgres { + struct Settings { + std::string address; + std::string username; + std::string password; + std::string dbname; + uint16_t port; + }; +} //namespace dinbpostgres + +#endif diff --git a/include/backends/postgresql/tag.hpp b/include/backends/postgresql/tag.hpp index 5fd2608..8a0af9f 100644 --- a/include/backends/postgresql/tag.hpp +++ b/include/backends/postgresql/tag.hpp @@ -22,23 +22,21 @@ #include #include -namespace dinlib { - struct SettingsDB; -} //namespace dinlib +namespace dinbpostgres { + struct Settings; -namespace din { struct OwnerSetInfo { uint32_t group_id; bool is_valid; }; - void tag_files ( const dinlib::SettingsDB& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); - void tag_files ( const dinlib::SettingsDB& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); + void tag_files ( const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); + void tag_files ( const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); - void delete_tags ( const dinlib::SettingsDB& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); - void delete_tags ( const dinlib::SettingsDB& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); - void delete_all_tags ( const dinlib::SettingsDB& parDB, const std::vector& parFiles, OwnerSetInfo parSet ); - void delete_all_tags ( const dinlib::SettingsDB& parDB, const std::vector& parRegexes, OwnerSetInfo parSet ); -} //namespace din + void delete_tags ( const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); + void delete_tags ( const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); + void delete_all_tags ( const Settings& parDB, const std::vector& parFiles, OwnerSetInfo parSet ); + void delete_all_tags ( const Settings& parDB, const std::vector& parRegexes, OwnerSetInfo parSet ); +} //namespace dinbpostgres #endif diff --git a/include/dindexer-common/settings.hpp b/include/dindexer-common/settings.hpp index e72bb0a..86e7a2b 100644 --- a/include/dindexer-common/settings.hpp +++ b/include/dindexer-common/settings.hpp @@ -19,19 +19,11 @@ #define idDC29E3C667BD4793BA0644AE7DC5BD3F #include -#include +#include "backends/postgresql/settings.hpp" namespace dinlib { - struct SettingsDB { - std::string address; - std::string username; - std::string password; - std::string dbname; - uint16_t port; - }; - struct Settings { - SettingsDB db; + dinbpostgres::Settings db; }; bool load_settings ( const std::string& parPath, Settings& parOut, bool parExpand=true ); diff --git a/src/navigate/flatinsertin2dlist.hpp b/include/helpers/flatinsertin2dlist.hpp similarity index 73% rename from src/navigate/flatinsertin2dlist.hpp rename to include/helpers/flatinsertin2dlist.hpp index b8d2a20..927b47d 100644 --- a/src/navigate/flatinsertin2dlist.hpp +++ b/include/helpers/flatinsertin2dlist.hpp @@ -18,13 +18,21 @@ #ifndef idAA901DA47E234E37B325B3192EF50423 #define idAA901DA47E234E37B325B3192EF50423 +//Use this function to turn a 1D sequence of elements that are logically grouped +//together by position into a 2D list. For example, if you have an input sequence +//like {A1, B1, C1, A2, B2, C2, A3, B3, C3} and you want to turn it into +//{ {A1, B1, C1}, {A2, B2, C2}, {A3, B3, C3} } you can use these functions to +//achieve that. You need to specify the size of the innermost groups, 3 in the +//example just given, and push_back() will automatically move to the next +//sublist every 3 items. + #include #include #include #include #include -namespace din { +namespace dinhelp { template class FlatInsertIn2DList { public: @@ -44,8 +52,8 @@ namespace din { const std::size_t m_inner_count; const std::size_t m_outer_count; }; -} //namespace din +} //namespace dinhelp -#include "flatinsertin2dlist.inl" +#include "implem/flatinsertin2dlist.inl" #endif diff --git a/src/navigate/flatinsertin2dlist.inl b/include/helpers/implem/flatinsertin2dlist.inl similarity index 98% rename from src/navigate/flatinsertin2dlist.inl rename to include/helpers/implem/flatinsertin2dlist.inl index edb9f09..4778887 100644 --- a/src/navigate/flatinsertin2dlist.inl +++ b/include/helpers/implem/flatinsertin2dlist.inl @@ -15,7 +15,7 @@ * along with "dindexer". If not, see . */ -namespace din { +namespace dinhelp { template FlatInsertIn2DList::FlatInsertIn2DList (list_type* parList, std::size_t parInnerCount, std::size_t parOuterCount) : m_list(parList), @@ -70,4 +70,4 @@ namespace din { return (m_list->size() - 1) * m_inner_count + m_list[m_list->size() - 1].size(); } } -} //namespace din +} //namespace dinhelp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 00d2afc..77f3a2b 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(${PROJECT_NAME} STATIC delete.cpp locate.cpp scan.cpp + dbsource.cpp ) #target_include_directories(${PROJECT_NAME} diff --git a/src/navigate/dbsource.cpp b/src/backends/postgresql/dbsource.cpp similarity index 95% rename from src/navigate/dbsource.cpp rename to src/backends/postgresql/dbsource.cpp index 02100f3..5c8af19 100644 --- a/src/navigate/dbsource.cpp +++ b/src/backends/postgresql/dbsource.cpp @@ -15,8 +15,8 @@ * along with "dindexer". If not, see . */ -#include "dbsource.hpp" -#include "dindexer-common/settings.hpp" +#include "backends/postgresql/dbsource.hpp" +#include "backends/postgresql/settings.hpp" #include "pq/connection.hpp" #include "helpers/infix_iterator.hpp" #include @@ -25,7 +25,7 @@ #include #include -namespace din { +namespace dinbpostgres { namespace { const uint32_t g_files_query_limit = 500; @@ -62,7 +62,7 @@ namespace din { }; struct DBSource::LocalData { - explicit LocalData ( const dinlib::SettingsDB& parDBSettings ) : + explicit LocalData ( const Settings& parDBSettings ) : conn( std::string(parDBSettings.username), std::string(parDBSettings.password), @@ -76,7 +76,7 @@ namespace din { pq::Connection conn; }; - DBSource::DBSource (const dinlib::SettingsDB& parDBSettings) : + DBSource::DBSource (const Settings& parDBSettings) : m_local_data(new LocalData(parDBSettings)) { assert(not m_local_data->conn.is_connected()); @@ -180,4 +180,4 @@ namespace din { } return retval; } -} //namespace din +} //namespace dinbpostgres diff --git a/src/backends/postgresql/delete.cpp b/src/backends/postgresql/delete.cpp index 610fabb..2d28d2b 100644 --- a/src/backends/postgresql/delete.cpp +++ b/src/backends/postgresql/delete.cpp @@ -16,8 +16,8 @@ */ #include "backends/postgresql/delete.hpp" +#include "backends/postgresql/settings.hpp" #include "pq/connection.hpp" -#include "dindexer-common/settings.hpp" #include "helpers/infix_iterator.hpp" #include #include @@ -27,7 +27,7 @@ #include #include -namespace din { +namespace dinbpostgres { namespace { IDDescMap fetch_existing_ids (pq::Connection& parConn, const std::vector& parIDs) { using boost::lexical_cast; @@ -50,7 +50,7 @@ namespace din { } } //unnamed namespace - void delete_group_from_db (const dinlib::SettingsDB& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf) { + void delete_group_from_db (const Settings& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); const auto dele_ids = fetch_existing_ids(conn, parIDs); @@ -72,4 +72,4 @@ namespace din { conn.query(oss.str()); } -} //namespace din +} //namespace dinbpostgres diff --git a/src/backends/postgresql/locate.cpp b/src/backends/postgresql/locate.cpp index eb68e02..48da2b0 100644 --- a/src/backends/postgresql/locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -16,19 +16,20 @@ */ #include "backends/postgresql/locate.hpp" +#include "backends/postgresql/settings.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/tiger.hpp" #include #include #include -namespace din { +namespace dinbpostgres { namespace { const int g_max_results = 200; - pq::Connection make_pq_conn ( const dinlib::SettingsDB& parDB, bool parOpen=true ); + pq::Connection make_pq_conn ( const Settings& parDB, bool parOpen=true ); - pq::Connection make_pq_conn (const dinlib::SettingsDB& parDB, bool parOpen) { + pq::Connection make_pq_conn (const Settings& parDB, bool parOpen) { auto conn = pq::Connection(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); if (parOpen) { conn.connect(); @@ -94,20 +95,20 @@ namespace din { } } //unnamed namespace - std::vector locate_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, const TagList& parTags) { + std::vector locate_in_db (const Settings& parDB, const std::string& parSearch, const TagList& parTags) { auto conn = make_pq_conn(parDB); const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"path\" ~ $1"; return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, parSearch); } - std::vector locate_in_db (const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags) { + std::vector locate_in_db (const Settings& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags) { auto conn = make_pq_conn(parDB); const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"hash\"=$1"; return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, mchlib::tiger_to_string(parSearch, true)); } - std::vector locate_sets_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive) { + std::vector locate_sets_in_db (const Settings& parDB, const std::string& parSearch, bool parCaseInsensitive) { auto conn = make_pq_conn(parDB); const std::string query = std::string("SELECT \"id\", \"desc\", " @@ -120,7 +121,7 @@ namespace din { return sets_result_to_vec(std::move(result)); } - std::vector locate_sets_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { + std::vector locate_sets_in_db (const Settings& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { if (parSets.empty()) { return locate_sets_in_db(parDB, parSearch, parCaseInsensitive); } @@ -136,4 +137,4 @@ namespace din { auto result = conn.query(query, parSearch, parCaseInsensitive, parSets); return sets_result_to_vec(std::move(result)); } -} //namespace din +} //namespace dinbpostgres diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index 14328f4..e3635f1 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -16,8 +16,8 @@ */ #include "backends/postgresql/scan.hpp" +#include "backends/postgresql/settings.hpp" #include "pq/connection.hpp" -#include "dindexer-common/settings.hpp" #include "dindexer-machinery/recorddata.hpp" #include #include @@ -28,11 +28,11 @@ #include #include -namespace din { +namespace dinbpostgres { namespace { } //unnamed namespace - bool read_from_db (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parHash) { + bool read_from_db (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const Settings& parDB, const mchlib::TigerHash& parHash) { using boost::lexical_cast; pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); @@ -82,7 +82,7 @@ namespace din { return true; } - void write_to_db (const dinlib::SettingsDB& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { + void write_to_db (const Settings& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { using std::chrono::system_clock; using boost::lexical_cast; @@ -144,4 +144,4 @@ namespace din { } conn.query("COMMIT;"); } -} //namespace din +} //namespace dinbpostgres diff --git a/src/backends/postgresql/tag.cpp b/src/backends/postgresql/tag.cpp index cc46cea..8cee222 100644 --- a/src/backends/postgresql/tag.cpp +++ b/src/backends/postgresql/tag.cpp @@ -16,12 +16,13 @@ */ #include "backends/postgresql/tag.hpp" +#include "backends/postgresql/settings.hpp" #include "pq/connection.hpp" #include "dindexer-common/settings.hpp" #include -namespace din { - void tag_files (const dinlib::SettingsDB& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { +namespace dinbpostgres { + void tag_files (const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -37,7 +38,7 @@ namespace din { } } - void tag_files (const dinlib::SettingsDB& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { + void tag_files (const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -71,7 +72,7 @@ namespace din { } } - void delete_tags (const dinlib::SettingsDB& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { + void delete_tags (const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -97,7 +98,7 @@ namespace din { } } - void delete_tags (const dinlib::SettingsDB& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { + void delete_tags (const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -123,7 +124,7 @@ namespace din { } } - void delete_all_tags (const dinlib::SettingsDB& parDB, const std::vector& parFiles, OwnerSetInfo parSet) { + void delete_all_tags (const Settings& parDB, const std::vector& parFiles, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -139,7 +140,7 @@ namespace din { } } - void delete_all_tags (const dinlib::SettingsDB& parDB, const std::vector& parRegexes, OwnerSetInfo parSet) { + void delete_all_tags (const Settings& parDB, const std::vector& parRegexes, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -152,4 +153,4 @@ namespace din { conn.query(query, parRegexes); } } -} //namespace din +} //namespace dinbpostgres diff --git a/src/common/settings.cpp b/src/common/settings.cpp index e37c189..997bca4 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -22,8 +22,8 @@ namespace YAML { template<> - struct convert { - static Node encode (const dinlib::SettingsDB& parSettings) { + struct convert { + static Node encode (const dinbpostgres::Settings& parSettings) { Node node; node["address"] = parSettings.address; node["username"] = parSettings.username; @@ -33,7 +33,7 @@ namespace YAML { return node; } - static bool decode (const Node& parNode, dinlib::SettingsDB& parSettings) { + static bool decode (const Node& parNode, dinbpostgres::Settings& parSettings) { if (not parNode.IsMap() or parNode.size() != 5) { return false; } @@ -60,7 +60,7 @@ namespace dinlib { auto settings = YAML::LoadFile(path); if (settings["db_settings"]) { - parOut.db = settings["db_settings"].as(); + parOut.db = settings["db_settings"].as(); return true; } } diff --git a/src/delete/main.cpp b/src/delete/main.cpp index 29a1332..0162093 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -26,7 +26,7 @@ #include namespace { - bool confirm_delete (const din::IDDescMap& parMap) { + bool confirm_delete (const dinbpostgres::IDDescMap& parMap) { for (const auto& itm : parMap) { std::cout << "ID " << itm.first << '\t' << itm.second << '\n'; } @@ -38,7 +38,7 @@ namespace { return (answer.empty() or "y" == answer or "Y" == answer); } - bool always_delete (const din::IDDescMap&) { + bool always_delete (const dinbpostgres::IDDescMap&) { return true; } } //unnamed namespace @@ -77,7 +77,7 @@ int main (int parArgc, char* parArgv[]) { const auto ids = vm["groupid"].as>(); auto confirm_func = (vm.count("confirm") ? &always_delete : &confirm_delete); - din::delete_group_from_db(settings.db, ids, confirm_func); + dinbpostgres::delete_group_from_db(settings.db, ids, confirm_func); return 0; } diff --git a/src/locate/main.cpp b/src/locate/main.cpp index a30ae5f..7055432 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -27,7 +27,7 @@ #include #include -namespace din { +namespace dinbpostgres { std::ostream& operator<< (std::ostream& parStream, const LocatedItem& parItem) { parStream << parItem.group_id << '\t' << parItem.id << '\t' << parItem.path; return parStream; @@ -41,7 +41,7 @@ namespace din { '\t' << parItem.files_count << '\t' << dircount; return parStream; } -} //namespace din +} //namespace dinbpostgres namespace { std::vector extract_tags (const boost::program_options::variables_map& parVM) { @@ -81,22 +81,22 @@ int main (int parArgc, char* parArgv[]) { } if (vm.count("set")) { - const auto results = din::locate_sets_in_db(settings.db, vm["substring"].as(), not not vm.count("case-insensitive")); - std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); + const auto results = dinbpostgres::locate_sets_in_db(settings.db, vm["substring"].as(), not not vm.count("case-insensitive")); + std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } else { - std::vector results; + std::vector results; const std::vector tags = extract_tags(vm); if (vm.count("byhash")) { const auto hash = din::hash(vm["substring"].as()); - results = din::locate_in_db(settings.db, hash, tags); + results = dinbpostgres::locate_in_db(settings.db, hash, tags); } else { const auto search_regex = g2r::convert(vm["substring"].as(), not vm.count("case-insensitive")); - results = din::locate_in_db(settings.db, search_regex, tags); + results = dinbpostgres::locate_in_db(settings.db, search_regex, tags); } - std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); + std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } return 0; } diff --git a/src/navigate/CMakeLists.txt b/src/navigate/CMakeLists.txt index 86c0986..303b539 100644 --- a/src/navigate/CMakeLists.txt +++ b/src/navigate/CMakeLists.txt @@ -5,7 +5,6 @@ add_executable(${PROJECT_NAME} commandline.cpp commandprocessor.cpp entrypath.cpp - dbsource.cpp linereader.cpp listdircontent.cpp ) @@ -17,6 +16,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common + PRIVATE ${bare_name}-backend-postgresql ) target_compile_features(${PROJECT_NAME} diff --git a/src/navigate/listdircontent.cpp b/src/navigate/listdircontent.cpp index fef051c..e85cdcf 100644 --- a/src/navigate/listdircontent.cpp +++ b/src/navigate/listdircontent.cpp @@ -17,7 +17,7 @@ #include "listdircontent.hpp" #include "entrypath.hpp" -#include "dbsource.hpp" +#include "backends/postgresql/dbsource.hpp" #include "helpers/infix_iterator.hpp" #include #include @@ -68,7 +68,7 @@ namespace din { } } //unnamed namespace - ListDirContent::ListDirContent (DBSource* parDB) : + ListDirContent::ListDirContent (dinbpostgres::DBSource* parDB) : m_cache(g_max_cached_lists), m_db(parDB) { @@ -86,13 +86,13 @@ namespace din { //Requested item is not cached, so we need to query the db now if (parDir.points_to_group()) { auto sets_ids = m_db->sets(); - auto sets_info = m_db->set_details(sets_ids); + auto sets_info = m_db->set_details(sets_ids); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(sets_info))); } else { auto path_prefix = parDir.file_path(); const auto set_id = parDir.group_id(); - auto files_info = m_db->file_details(set_id, parDir.level() + 1, path_prefix); + auto files_info = m_db->file_details(set_id, parDir.level() + 1, path_prefix); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(files_info))); } return last_cached_item(curr_path); diff --git a/src/navigate/listdircontent.hpp b/src/navigate/listdircontent.hpp index 9a02e40..37be26f 100644 --- a/src/navigate/listdircontent.hpp +++ b/src/navigate/listdircontent.hpp @@ -23,15 +23,18 @@ #include #include +namespace dinbpostgres { + class DBSource; +} //namespace dinbpostgres + namespace din { class EntryPath; - class DBSource; class ListDirContent { using ListType = std::vector; using CachedItemType = std::pair; public: - explicit ListDirContent ( DBSource* parDB ); + explicit ListDirContent ( dinbpostgres::DBSource* parDB ); ~ListDirContent ( void ) noexcept = default; const ListType& ls ( const EntryPath& parDir ) const; @@ -41,7 +44,7 @@ namespace din { const ListType& last_cached_item ( const std::string& parCurrPath ) const; mutable boost::circular_buffer m_cache; - DBSource* m_db; + dinbpostgres::DBSource* m_db; }; } //namespace din diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp index 594ba89..f52a0a9 100644 --- a/src/navigate/main.cpp +++ b/src/navigate/main.cpp @@ -19,7 +19,7 @@ #include "commandprocessor.hpp" #include "dindexer-common/settings.hpp" #include "entrypath.hpp" -#include "dbsource.hpp" +#include "backends/postgresql/dbsource.hpp" #include "dindexerConfig.h" #include "linereader.hpp" #include "listdircontent.hpp" @@ -31,7 +31,7 @@ #include namespace { - void do_navigation ( din::DBSource& parDB ); + void do_navigation ( dinbpostgres::DBSource& parDB ); bool on_exit ( void ); void on_pwd ( const din::EntryPath& parDirMan ); @@ -61,7 +61,7 @@ int main (int parArgc, char* parArgv[]) { } } - din::DBSource db_source(settings.db); + dinbpostgres::DBSource db_source(settings.db); do_navigation(db_source); return 0; @@ -81,7 +81,7 @@ namespace { boost::copy(ls_result, std::ostream_iterator(std::cout, "\n")); } - void do_navigation (din::DBSource& parDB) { + void do_navigation (dinbpostgres::DBSource& parDB) { const std::string prompt; din::ListDirContent ls(&parDB); din::LineReader lines(&ls); @@ -92,7 +92,7 @@ namespace { din::EntryPath dir_man; proc.add_command("exit", &on_exit, 0); proc.add_command("cd", std::function(std::bind(&din::EntryPath::push_piece, &dir_man, std::placeholders::_1)), 1); - proc.add_command("disconnect", std::function(std::bind(&din::DBSource::disconnect, &parDB)), 0); + proc.add_command("disconnect", std::function(std::bind(&dinbpostgres::DBSource::disconnect, &parDB)), 0); proc.add_command("pwd", std::function(std::bind(&on_pwd, std::ref(dir_man))), 0); proc.add_command("ls", std::function(std::bind(on_ls, std::ref(ls), std::ref(dir_man))), 0); do { diff --git a/src/scan/main.cpp b/src/scan/main.cpp index e44b871..2028f8f 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -41,7 +41,7 @@ #endif namespace { - bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinlib::SettingsDB& parDBSettings, bool parForce=false ); + bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinbpostgres::Settings& parDBSettings, bool parForce=false ); #if defined(WITH_PROGRESS_FEEDBACK) void print_progress ( const boost::string_ref parPath, uint64_t parFileBytes, uint64_t parTotalBytes, uint32_t parFileNum, std::size_t& parClearCount ); #endif @@ -115,7 +115,7 @@ int main (int parArgc, char* parArgv[]) { } namespace { - bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinlib::SettingsDB& parDBSettings, bool parForce) { + bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinbpostgres::Settings& parDBSettings, bool parForce) { using mchlib::FileRecordData; using mchlib::SetRecordDataFull; using mchlib::SetRecordData; @@ -124,7 +124,7 @@ namespace { const auto& first_hash = parData.front().hash; FileRecordData itm; SetRecordDataFull set; - const bool already_in_db = din::read_from_db(itm, set, parDBSettings, first_hash); + const bool already_in_db = dinbpostgres::read_from_db(itm, set, parDBSettings, first_hash); if (already_in_db) { return false; } @@ -134,7 +134,7 @@ namespace { const auto app_signature = dinlib::dindexer_signature(); const auto lib_signature = mchlib::lib_signature(); const std::string signature = std::string(app_signature.data(), app_signature.size()) + "/" + std::string(lib_signature.data(), lib_signature.size()); - din::write_to_db(parDBSettings, parData, set_data, signature); + dinbpostgres::write_to_db(parDBSettings, parData, set_data, signature); return true; } diff --git a/src/tag/main.cpp b/src/tag/main.cpp index fba9d66..a838eed 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -47,8 +47,8 @@ namespace { return retval; } - din::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) { - din::OwnerSetInfo set_info; + dinbpostgres::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) { + dinbpostgres::OwnerSetInfo set_info; if (parVM.count("set")) { set_info.is_valid = true; set_info.group_id = parVM["set"].as(); @@ -60,11 +60,11 @@ namespace { return set_info; } - int tag_files (const dinlib::SettingsDB& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int tag_files (const dinbpostgres::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; - const din::OwnerSetInfo set_info = make_owner_set_info(parVM); + const dinbpostgres::OwnerSetInfo set_info = make_owner_set_info(parVM); switch (parMode) { case TaggingMode::ID: @@ -73,14 +73,14 @@ namespace { std::vector ids; ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); - din::tag_files(parDB, ids, parTags, set_info); + dinbpostgres::tag_files(parDB, ids, parTags, set_info); return 0; } case TaggingMode::Glob: { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); - din::tag_files(parDB, regexes, parTags, set_info); + dinbpostgres::tag_files(parDB, regexes, parTags, set_info); return 0; } @@ -90,7 +90,7 @@ namespace { } } - int delete_tags (const dinlib::SettingsDB& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int delete_tags (const dinbpostgres::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; @@ -104,9 +104,9 @@ namespace { ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); if (parVM.count("alltags")) - din::delete_all_tags(parDB, ids, make_owner_set_info(parVM)); + dinbpostgres::delete_all_tags(parDB, ids, make_owner_set_info(parVM)); else - din::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM)); + dinbpostgres::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM)); return 0; } @@ -114,9 +114,9 @@ namespace { { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); if (parVM.count("alltags")) - din::delete_all_tags(parDB, regexes, make_owner_set_info(parVM)); + dinbpostgres::delete_all_tags(parDB, regexes, make_owner_set_info(parVM)); else - din::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM)); + dinbpostgres::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM)); return 0; } From fb722719b225d1c62b117a1907ac82522c2c8d5c Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 23 May 2016 19:50:12 +0200 Subject: [PATCH 007/170] Move postgresql backend's include files to a new db subdir. Fix build and remove unneeded include in tag.cpp --- include/backends/postgresql/{ => db}/dbsource.hpp | 0 include/backends/postgresql/{ => db}/delete.hpp | 0 include/backends/postgresql/{ => db}/locate.hpp | 0 include/backends/postgresql/{ => db}/scan.hpp | 0 include/backends/postgresql/{ => db}/settings.hpp | 0 include/backends/postgresql/{ => db}/tag.hpp | 0 src/backends/postgresql/CMakeLists.txt | 5 +++-- src/backends/postgresql/dbsource.cpp | 4 ++-- src/backends/postgresql/delete.cpp | 4 ++-- src/backends/postgresql/locate.cpp | 4 ++-- src/backends/postgresql/scan.cpp | 4 ++-- src/backends/postgresql/tag.cpp | 5 ++--- 12 files changed, 13 insertions(+), 13 deletions(-) rename include/backends/postgresql/{ => db}/dbsource.hpp (100%) rename include/backends/postgresql/{ => db}/delete.hpp (100%) rename include/backends/postgresql/{ => db}/locate.hpp (100%) rename include/backends/postgresql/{ => db}/scan.hpp (100%) rename include/backends/postgresql/{ => db}/settings.hpp (100%) rename include/backends/postgresql/{ => db}/tag.hpp (100%) diff --git a/include/backends/postgresql/dbsource.hpp b/include/backends/postgresql/db/dbsource.hpp similarity index 100% rename from include/backends/postgresql/dbsource.hpp rename to include/backends/postgresql/db/dbsource.hpp diff --git a/include/backends/postgresql/delete.hpp b/include/backends/postgresql/db/delete.hpp similarity index 100% rename from include/backends/postgresql/delete.hpp rename to include/backends/postgresql/db/delete.hpp diff --git a/include/backends/postgresql/locate.hpp b/include/backends/postgresql/db/locate.hpp similarity index 100% rename from include/backends/postgresql/locate.hpp rename to include/backends/postgresql/db/locate.hpp diff --git a/include/backends/postgresql/scan.hpp b/include/backends/postgresql/db/scan.hpp similarity index 100% rename from include/backends/postgresql/scan.hpp rename to include/backends/postgresql/db/scan.hpp diff --git a/include/backends/postgresql/settings.hpp b/include/backends/postgresql/db/settings.hpp similarity index 100% rename from include/backends/postgresql/settings.hpp rename to include/backends/postgresql/db/settings.hpp diff --git a/include/backends/postgresql/tag.hpp b/include/backends/postgresql/db/tag.hpp similarity index 100% rename from include/backends/postgresql/tag.hpp rename to include/backends/postgresql/db/tag.hpp diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 77f3a2b..396b0e5 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -8,8 +8,9 @@ add_library(${PROJECT_NAME} STATIC dbsource.cpp ) -#target_include_directories(${PROJECT_NAME} -#) +target_include_directories(${PROJECT_NAME} + PUBLIC ${CMAKE_SOURCE_DIR}/include/backends/postgresql +) #target_include_directories(${PROJECT_NAME} SYSTEM #) diff --git a/src/backends/postgresql/dbsource.cpp b/src/backends/postgresql/dbsource.cpp index 5c8af19..4d923c1 100644 --- a/src/backends/postgresql/dbsource.cpp +++ b/src/backends/postgresql/dbsource.cpp @@ -15,8 +15,8 @@ * along with "dindexer". If not, see . */ -#include "backends/postgresql/dbsource.hpp" -#include "backends/postgresql/settings.hpp" +#include "db/dbsource.hpp" +#include "db/settings.hpp" #include "pq/connection.hpp" #include "helpers/infix_iterator.hpp" #include diff --git a/src/backends/postgresql/delete.cpp b/src/backends/postgresql/delete.cpp index 2d28d2b..9691bdc 100644 --- a/src/backends/postgresql/delete.cpp +++ b/src/backends/postgresql/delete.cpp @@ -15,8 +15,8 @@ * along with "dindexer". If not, see . */ -#include "backends/postgresql/delete.hpp" -#include "backends/postgresql/settings.hpp" +#include "db/delete.hpp" +#include "db/settings.hpp" #include "pq/connection.hpp" #include "helpers/infix_iterator.hpp" #include diff --git a/src/backends/postgresql/locate.cpp b/src/backends/postgresql/locate.cpp index 48da2b0..65d377a 100644 --- a/src/backends/postgresql/locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -15,8 +15,8 @@ * along with "dindexer". If not, see . */ -#include "backends/postgresql/locate.hpp" -#include "backends/postgresql/settings.hpp" +#include "db/locate.hpp" +#include "db/settings.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/tiger.hpp" #include diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index e3635f1..ad34f5d 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -15,8 +15,8 @@ * along with "dindexer". If not, see . */ -#include "backends/postgresql/scan.hpp" -#include "backends/postgresql/settings.hpp" +#include "db/scan.hpp" +#include "db/settings.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/recorddata.hpp" #include diff --git a/src/backends/postgresql/tag.cpp b/src/backends/postgresql/tag.cpp index 8cee222..9993ffc 100644 --- a/src/backends/postgresql/tag.cpp +++ b/src/backends/postgresql/tag.cpp @@ -15,10 +15,9 @@ * along with "dindexer". If not, see . */ -#include "backends/postgresql/tag.hpp" -#include "backends/postgresql/settings.hpp" +#include "db/tag.hpp" +#include "db/settings.hpp" #include "pq/connection.hpp" -#include "dindexer-common/settings.hpp" #include namespace dinbpostgres { From 8f98495049a70c432a37491995d137c4302c4ab4 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 24 May 2016 09:36:38 +0200 Subject: [PATCH 008/170] Make dindexer-common depend on postgre backend and fix build --- CMakeLists.txt | 1 + include/dindexer-common/settings.hpp | 2 +- src/backends/postgresql/CMakeLists.txt | 7 ++++--- src/common/CMakeLists.txt | 3 +++ src/delete/CMakeLists.txt | 1 - src/delete/main.cpp | 2 +- src/locate/CMakeLists.txt | 1 - src/locate/main.cpp | 2 +- src/navigate/CMakeLists.txt | 1 - src/navigate/listdircontent.cpp | 2 +- src/navigate/main.cpp | 2 +- src/scan/CMakeLists.txt | 1 - src/scan/main.cpp | 2 +- src/tag/CMakeLists.txt | 1 - src/tag/main.cpp | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cee3d5..4fd4155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ if(DINDEXER_NATIVE_RELEASE) else() set(march_flag "") endif() +set(DINDEXER_DB_BACKEND "PostgreSQL") set(DINDEXER_COPYRIGHT_YEARS "2015,2016") set(DINDEXER_ACTIONS_PATH "${CMAKE_CURRENT_BINARY_DIR}/src" CACHE STRING "Actions search path") string(REGEX MATCH "[^/].*" ACTIONS_PATH_INSTALL "${DINDEXER_ACTIONS_PATH}") diff --git a/include/dindexer-common/settings.hpp b/include/dindexer-common/settings.hpp index 86e7a2b..131ba11 100644 --- a/include/dindexer-common/settings.hpp +++ b/include/dindexer-common/settings.hpp @@ -19,7 +19,7 @@ #define idDC29E3C667BD4793BA0644AE7DC5BD3F #include -#include "backends/postgresql/settings.hpp" +#include "db/settings.hpp" namespace dinlib { struct Settings { diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 396b0e5..8238350 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -11,11 +11,12 @@ add_library(${PROJECT_NAME} STATIC target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/include/backends/postgresql ) -#target_include_directories(${PROJECT_NAME} SYSTEM -#) +target_include_directories(${PROJECT_NAME} SYSTEM + PUBLIC ${Boost_INCLUDE_DIRS} +) target_link_libraries(${PROJECT_NAME} - PRIVATE ${bare_name}-if + PRIVATE ${bare_name}-inc PRIVATE ${bare_name}-pq ) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 316497a..e41e3b5 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -19,10 +19,13 @@ target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${Readline_INCLUDE_DIR} ) +string(TOLOWER "${DINDEXER_DB_BACKEND}" DINDEXER_DB_BACKEND_LOWERCASE) + target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${YAMLCPP_LIBRARY} PRIVATE ${Readline_LIBRARY} + PUBLIC ${bare_name}-backend-${DINDEXER_DB_BACKEND_LOWERCASE} ) #install(TARGETS ${PROJECT_NAME} diff --git a/src/delete/CMakeLists.txt b/src/delete/CMakeLists.txt index 1563f35..88b71ad 100644 --- a/src/delete/CMakeLists.txt +++ b/src/delete/CMakeLists.txt @@ -12,7 +12,6 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common - PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/delete/main.cpp b/src/delete/main.cpp index 0162093..cf44f5b 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -18,7 +18,7 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "backends/postgresql/delete.hpp" +#include "db/delete.hpp" #include #include #include diff --git a/src/locate/CMakeLists.txt b/src/locate/CMakeLists.txt index cddde1d..3ace773 100644 --- a/src/locate/CMakeLists.txt +++ b/src/locate/CMakeLists.txt @@ -16,7 +16,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-common PRIVATE ${bare_name}-machinery PRIVATE glob2regex - PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/locate/main.cpp b/src/locate/main.cpp index 7055432..83aefb1 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -16,7 +16,7 @@ */ #include "commandline.hpp" -#include "backends/postgresql/locate.hpp" +#include "db/locate.hpp" #include "dindexer-common/settings.hpp" #include "dindexer-common/split_tags.hpp" #include "dindexerConfig.h" diff --git a/src/navigate/CMakeLists.txt b/src/navigate/CMakeLists.txt index 303b539..6e8cf88 100644 --- a/src/navigate/CMakeLists.txt +++ b/src/navigate/CMakeLists.txt @@ -16,7 +16,6 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common - PRIVATE ${bare_name}-backend-postgresql ) target_compile_features(${PROJECT_NAME} diff --git a/src/navigate/listdircontent.cpp b/src/navigate/listdircontent.cpp index e85cdcf..4953b23 100644 --- a/src/navigate/listdircontent.cpp +++ b/src/navigate/listdircontent.cpp @@ -17,7 +17,7 @@ #include "listdircontent.hpp" #include "entrypath.hpp" -#include "backends/postgresql/dbsource.hpp" +#include "db/dbsource.hpp" #include "helpers/infix_iterator.hpp" #include #include diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp index f52a0a9..65118e0 100644 --- a/src/navigate/main.cpp +++ b/src/navigate/main.cpp @@ -19,7 +19,7 @@ #include "commandprocessor.hpp" #include "dindexer-common/settings.hpp" #include "entrypath.hpp" -#include "backends/postgresql/dbsource.hpp" +#include "db/dbsource.hpp" #include "dindexerConfig.h" #include "linereader.hpp" #include "listdircontent.hpp" diff --git a/src/scan/CMakeLists.txt b/src/scan/CMakeLists.txt index b5e4d9e..0ac7189 100644 --- a/src/scan/CMakeLists.txt +++ b/src/scan/CMakeLists.txt @@ -15,7 +15,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common PRIVATE ${bare_name}-machinery - PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/scan/main.cpp b/src/scan/main.cpp index 2028f8f..77860f2 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -25,7 +25,7 @@ #include "dindexer-common/common_info.hpp" #include "dindexer-common/settings.hpp" #include "commandline.hpp" -#include "backends/postgresql/scan.hpp" +#include "db/scan.hpp" #include "dindexer-machinery/scantask/dirtree.hpp" #include "dindexer-machinery/scantask/mediatype.hpp" #include "dindexer-machinery/scantask/hashing.hpp" diff --git a/src/tag/CMakeLists.txt b/src/tag/CMakeLists.txt index 3a992c6..89d5ec9 100644 --- a/src/tag/CMakeLists.txt +++ b/src/tag/CMakeLists.txt @@ -15,7 +15,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${bare_name}-common PRIVATE glob2regex - PRIVATE ${bare_name}-backend-postgresql ) string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") diff --git a/src/tag/main.cpp b/src/tag/main.cpp index a838eed..f8fefc3 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -18,7 +18,7 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "backends/postgresql/tag.hpp" +#include "db/tag.hpp" #include "dindexer-common/split_tags.hpp" #include "glob2regex/glob2regex.hpp" #include "enum.h" From 45fc758915c3802c7c594ab2ea5f52229b15e218 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 24 May 2016 09:37:11 +0200 Subject: [PATCH 009/170] Print db backend name in --builtin view --- src/dindexerConfig.h.in | 2 ++ src/main/builtin_feats.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/dindexerConfig.h.in b/src/dindexerConfig.h.in index 7d2493c..8f1eae6 100644 --- a/src/dindexerConfig.h.in +++ b/src/dindexerConfig.h.in @@ -50,6 +50,8 @@ # define WITH_NICE_MEDIA_TYPES #endif +#define DB_BACKEND "@DINDEXER_DB_BACKEND@" + #define COPYRIGHT_YEARS_LIST @DINDEXER_COPYRIGHT_YEARS@ #endif diff --git a/src/main/builtin_feats.c b/src/main/builtin_feats.c index 9c6e851..0ffba59 100644 --- a/src/main/builtin_feats.c +++ b/src/main/builtin_feats.c @@ -52,6 +52,7 @@ void print_builtin_feats() { #else printf("WITH_NICE_MEDIA_TYPES = no\n"); #endif + printf("DB_BACKEND = \"%s\"\n", DB_BACKEND); } void print_version() { From 1fd51f75baa19369fd582e38d744e7723b3808a3 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 24 May 2016 09:42:29 +0200 Subject: [PATCH 010/170] Rename namespace dinbpostgres to dindb. It's so much better! --- include/backends/postgresql/db/dbsource.hpp | 4 ++-- include/backends/postgresql/db/delete.hpp | 4 ++-- include/backends/postgresql/db/locate.hpp | 4 ++-- include/backends/postgresql/db/scan.hpp | 4 ++-- include/backends/postgresql/db/settings.hpp | 4 ++-- include/backends/postgresql/db/tag.hpp | 4 ++-- include/dindexer-common/settings.hpp | 2 +- src/backends/postgresql/dbsource.cpp | 4 ++-- src/backends/postgresql/delete.cpp | 4 ++-- src/backends/postgresql/locate.cpp | 4 ++-- src/backends/postgresql/scan.cpp | 4 ++-- src/backends/postgresql/tag.cpp | 4 ++-- src/common/settings.cpp | 8 ++++---- src/delete/main.cpp | 6 +++--- src/locate/main.cpp | 16 +++++++-------- src/navigate/listdircontent.cpp | 6 +++--- src/navigate/listdircontent.hpp | 8 ++++---- src/navigate/main.cpp | 8 ++++---- src/scan/main.cpp | 8 ++++---- src/tag/main.cpp | 22 ++++++++++----------- 20 files changed, 64 insertions(+), 64 deletions(-) diff --git a/include/backends/postgresql/db/dbsource.hpp b/include/backends/postgresql/db/dbsource.hpp index 087435a..d0e5810 100644 --- a/include/backends/postgresql/db/dbsource.hpp +++ b/include/backends/postgresql/db/dbsource.hpp @@ -35,7 +35,7 @@ namespace pq { class Connection; } //namespace pq -namespace dinbpostgres { +namespace dindb { using dinhelp::MaxSizedArray; struct Settings; @@ -146,6 +146,6 @@ namespace dinbpostgres { this->query_files_in_dir(columns, parDir, parLevel, parSetID, std::bind(pback_func, &flat_list, std::placeholders::_1)); return list; } -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/backends/postgresql/db/delete.hpp b/include/backends/postgresql/db/delete.hpp index 85bba77..90d2c6a 100644 --- a/include/backends/postgresql/db/delete.hpp +++ b/include/backends/postgresql/db/delete.hpp @@ -24,13 +24,13 @@ #include #include -namespace dinbpostgres { +namespace dindb { struct Settings; using IDDescMap = std::map; using ConfirmDeleCallback = std::function; void delete_group_from_db ( const Settings& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf ); -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/backends/postgresql/db/locate.hpp b/include/backends/postgresql/db/locate.hpp index e982a17..51a595d 100644 --- a/include/backends/postgresql/db/locate.hpp +++ b/include/backends/postgresql/db/locate.hpp @@ -27,7 +27,7 @@ namespace mchlib { struct TigerHash; } //namespace mchlib -namespace dinbpostgres { +namespace dindb { struct Settings; struct LocatedItem { @@ -49,6 +49,6 @@ namespace dinbpostgres { std::vector locate_in_db ( const Settings& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags ); std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, bool parCaseInsensitive ); std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/backends/postgresql/db/scan.hpp b/include/backends/postgresql/db/scan.hpp index 6dee13f..877e1e0 100644 --- a/include/backends/postgresql/db/scan.hpp +++ b/include/backends/postgresql/db/scan.hpp @@ -29,11 +29,11 @@ namespace mchlib { struct TigerHash; } //namespace mchlib -namespace dinbpostgres { +namespace dindb { struct Settings;; void write_to_db ( const Settings& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const Settings& parDB, const mchlib::TigerHash& parHash ); -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/backends/postgresql/db/settings.hpp b/include/backends/postgresql/db/settings.hpp index 5c22c1a..3f384b2 100644 --- a/include/backends/postgresql/db/settings.hpp +++ b/include/backends/postgresql/db/settings.hpp @@ -21,7 +21,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { struct Settings { std::string address; std::string username; @@ -29,6 +29,6 @@ namespace dinbpostgres { std::string dbname; uint16_t port; }; -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/backends/postgresql/db/tag.hpp b/include/backends/postgresql/db/tag.hpp index 8a0af9f..509f6d3 100644 --- a/include/backends/postgresql/db/tag.hpp +++ b/include/backends/postgresql/db/tag.hpp @@ -22,7 +22,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { struct Settings; struct OwnerSetInfo { @@ -37,6 +37,6 @@ namespace dinbpostgres { void delete_tags ( const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); void delete_all_tags ( const Settings& parDB, const std::vector& parFiles, OwnerSetInfo parSet ); void delete_all_tags ( const Settings& parDB, const std::vector& parRegexes, OwnerSetInfo parSet ); -} //namespace dinbpostgres +} //namespace dindb #endif diff --git a/include/dindexer-common/settings.hpp b/include/dindexer-common/settings.hpp index 131ba11..0a689bc 100644 --- a/include/dindexer-common/settings.hpp +++ b/include/dindexer-common/settings.hpp @@ -23,7 +23,7 @@ namespace dinlib { struct Settings { - dinbpostgres::Settings db; + dindb::Settings db; }; bool load_settings ( const std::string& parPath, Settings& parOut, bool parExpand=true ); diff --git a/src/backends/postgresql/dbsource.cpp b/src/backends/postgresql/dbsource.cpp index 4d923c1..4d518c9 100644 --- a/src/backends/postgresql/dbsource.cpp +++ b/src/backends/postgresql/dbsource.cpp @@ -25,7 +25,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { namespace { const uint32_t g_files_query_limit = 500; @@ -180,4 +180,4 @@ namespace dinbpostgres { } return retval; } -} //namespace dinbpostgres +} //namespace dindb diff --git a/src/backends/postgresql/delete.cpp b/src/backends/postgresql/delete.cpp index 9691bdc..f75c54a 100644 --- a/src/backends/postgresql/delete.cpp +++ b/src/backends/postgresql/delete.cpp @@ -27,7 +27,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { namespace { IDDescMap fetch_existing_ids (pq::Connection& parConn, const std::vector& parIDs) { using boost::lexical_cast; @@ -72,4 +72,4 @@ namespace dinbpostgres { conn.query(oss.str()); } -} //namespace dinbpostgres +} //namespace dindb diff --git a/src/backends/postgresql/locate.cpp b/src/backends/postgresql/locate.cpp index 65d377a..9018b08 100644 --- a/src/backends/postgresql/locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -23,7 +23,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { namespace { const int g_max_results = 200; @@ -137,4 +137,4 @@ namespace dinbpostgres { auto result = conn.query(query, parSearch, parCaseInsensitive, parSets); return sets_result_to_vec(std::move(result)); } -} //namespace dinbpostgres +} //namespace dindb diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index ad34f5d..94fe4a8 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -28,7 +28,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { namespace { } //unnamed namespace @@ -144,4 +144,4 @@ namespace dinbpostgres { } conn.query("COMMIT;"); } -} //namespace dinbpostgres +} //namespace dindb diff --git a/src/backends/postgresql/tag.cpp b/src/backends/postgresql/tag.cpp index 9993ffc..79426b1 100644 --- a/src/backends/postgresql/tag.cpp +++ b/src/backends/postgresql/tag.cpp @@ -20,7 +20,7 @@ #include "pq/connection.hpp" #include -namespace dinbpostgres { +namespace dindb { void tag_files (const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); conn.connect(); @@ -152,4 +152,4 @@ namespace dinbpostgres { conn.query(query, parRegexes); } } -} //namespace dinbpostgres +} //namespace dindb diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 997bca4..cb50215 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -22,8 +22,8 @@ namespace YAML { template<> - struct convert { - static Node encode (const dinbpostgres::Settings& parSettings) { + struct convert { + static Node encode (const dindb::Settings& parSettings) { Node node; node["address"] = parSettings.address; node["username"] = parSettings.username; @@ -33,7 +33,7 @@ namespace YAML { return node; } - static bool decode (const Node& parNode, dinbpostgres::Settings& parSettings) { + static bool decode (const Node& parNode, dindb::Settings& parSettings) { if (not parNode.IsMap() or parNode.size() != 5) { return false; } @@ -60,7 +60,7 @@ namespace dinlib { auto settings = YAML::LoadFile(path); if (settings["db_settings"]) { - parOut.db = settings["db_settings"].as(); + parOut.db = settings["db_settings"].as(); return true; } } diff --git a/src/delete/main.cpp b/src/delete/main.cpp index cf44f5b..e3e17bf 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -26,7 +26,7 @@ #include namespace { - bool confirm_delete (const dinbpostgres::IDDescMap& parMap) { + bool confirm_delete (const dindb::IDDescMap& parMap) { for (const auto& itm : parMap) { std::cout << "ID " << itm.first << '\t' << itm.second << '\n'; } @@ -38,7 +38,7 @@ namespace { return (answer.empty() or "y" == answer or "Y" == answer); } - bool always_delete (const dinbpostgres::IDDescMap&) { + bool always_delete (const dindb::IDDescMap&) { return true; } } //unnamed namespace @@ -77,7 +77,7 @@ int main (int parArgc, char* parArgv[]) { const auto ids = vm["groupid"].as>(); auto confirm_func = (vm.count("confirm") ? &always_delete : &confirm_delete); - dinbpostgres::delete_group_from_db(settings.db, ids, confirm_func); + dindb::delete_group_from_db(settings.db, ids, confirm_func); return 0; } diff --git a/src/locate/main.cpp b/src/locate/main.cpp index 83aefb1..f8474e8 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -27,7 +27,7 @@ #include #include -namespace dinbpostgres { +namespace dindb { std::ostream& operator<< (std::ostream& parStream, const LocatedItem& parItem) { parStream << parItem.group_id << '\t' << parItem.id << '\t' << parItem.path; return parStream; @@ -41,7 +41,7 @@ namespace dinbpostgres { '\t' << parItem.files_count << '\t' << dircount; return parStream; } -} //namespace dinbpostgres +} //namespace dindb namespace { std::vector extract_tags (const boost::program_options::variables_map& parVM) { @@ -81,22 +81,22 @@ int main (int parArgc, char* parArgv[]) { } if (vm.count("set")) { - const auto results = dinbpostgres::locate_sets_in_db(settings.db, vm["substring"].as(), not not vm.count("case-insensitive")); - std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); + const auto results = dindb::locate_sets_in_db(settings.db, vm["substring"].as(), not not vm.count("case-insensitive")); + std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } else { - std::vector results; + std::vector results; const std::vector tags = extract_tags(vm); if (vm.count("byhash")) { const auto hash = din::hash(vm["substring"].as()); - results = dinbpostgres::locate_in_db(settings.db, hash, tags); + results = dindb::locate_in_db(settings.db, hash, tags); } else { const auto search_regex = g2r::convert(vm["substring"].as(), not vm.count("case-insensitive")); - results = dinbpostgres::locate_in_db(settings.db, search_regex, tags); + results = dindb::locate_in_db(settings.db, search_regex, tags); } - std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); + std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } return 0; } diff --git a/src/navigate/listdircontent.cpp b/src/navigate/listdircontent.cpp index 4953b23..bfda3fe 100644 --- a/src/navigate/listdircontent.cpp +++ b/src/navigate/listdircontent.cpp @@ -68,7 +68,7 @@ namespace din { } } //unnamed namespace - ListDirContent::ListDirContent (dinbpostgres::DBSource* parDB) : + ListDirContent::ListDirContent (dindb::DBSource* parDB) : m_cache(g_max_cached_lists), m_db(parDB) { @@ -86,13 +86,13 @@ namespace din { //Requested item is not cached, so we need to query the db now if (parDir.points_to_group()) { auto sets_ids = m_db->sets(); - auto sets_info = m_db->set_details(sets_ids); + auto sets_info = m_db->set_details(sets_ids); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(sets_info))); } else { auto path_prefix = parDir.file_path(); const auto set_id = parDir.group_id(); - auto files_info = m_db->file_details(set_id, parDir.level() + 1, path_prefix); + auto files_info = m_db->file_details(set_id, parDir.level() + 1, path_prefix); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(files_info))); } return last_cached_item(curr_path); diff --git a/src/navigate/listdircontent.hpp b/src/navigate/listdircontent.hpp index 37be26f..a3dfe19 100644 --- a/src/navigate/listdircontent.hpp +++ b/src/navigate/listdircontent.hpp @@ -23,9 +23,9 @@ #include #include -namespace dinbpostgres { +namespace dindb { class DBSource; -} //namespace dinbpostgres +} //namespace dindb namespace din { class EntryPath; @@ -34,7 +34,7 @@ namespace din { using ListType = std::vector; using CachedItemType = std::pair; public: - explicit ListDirContent ( dinbpostgres::DBSource* parDB ); + explicit ListDirContent ( dindb::DBSource* parDB ); ~ListDirContent ( void ) noexcept = default; const ListType& ls ( const EntryPath& parDir ) const; @@ -44,7 +44,7 @@ namespace din { const ListType& last_cached_item ( const std::string& parCurrPath ) const; mutable boost::circular_buffer m_cache; - dinbpostgres::DBSource* m_db; + dindb::DBSource* m_db; }; } //namespace din diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp index 65118e0..db02fed 100644 --- a/src/navigate/main.cpp +++ b/src/navigate/main.cpp @@ -31,7 +31,7 @@ #include namespace { - void do_navigation ( dinbpostgres::DBSource& parDB ); + void do_navigation ( dindb::DBSource& parDB ); bool on_exit ( void ); void on_pwd ( const din::EntryPath& parDirMan ); @@ -61,7 +61,7 @@ int main (int parArgc, char* parArgv[]) { } } - dinbpostgres::DBSource db_source(settings.db); + dindb::DBSource db_source(settings.db); do_navigation(db_source); return 0; @@ -81,7 +81,7 @@ namespace { boost::copy(ls_result, std::ostream_iterator(std::cout, "\n")); } - void do_navigation (dinbpostgres::DBSource& parDB) { + void do_navigation (dindb::DBSource& parDB) { const std::string prompt; din::ListDirContent ls(&parDB); din::LineReader lines(&ls); @@ -92,7 +92,7 @@ namespace { din::EntryPath dir_man; proc.add_command("exit", &on_exit, 0); proc.add_command("cd", std::function(std::bind(&din::EntryPath::push_piece, &dir_man, std::placeholders::_1)), 1); - proc.add_command("disconnect", std::function(std::bind(&dinbpostgres::DBSource::disconnect, &parDB)), 0); + proc.add_command("disconnect", std::function(std::bind(&dindb::DBSource::disconnect, &parDB)), 0); proc.add_command("pwd", std::function(std::bind(&on_pwd, std::ref(dir_man))), 0); proc.add_command("ls", std::function(std::bind(on_ls, std::ref(ls), std::ref(dir_man))), 0); do { diff --git a/src/scan/main.cpp b/src/scan/main.cpp index 77860f2..a948c07 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -41,7 +41,7 @@ #endif namespace { - bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinbpostgres::Settings& parDBSettings, bool parForce=false ); + bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dindb::Settings& parDBSettings, bool parForce=false ); #if defined(WITH_PROGRESS_FEEDBACK) void print_progress ( const boost::string_ref parPath, uint64_t parFileBytes, uint64_t parTotalBytes, uint32_t parFileNum, std::size_t& parClearCount ); #endif @@ -115,7 +115,7 @@ int main (int parArgc, char* parArgv[]) { } namespace { - bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dinbpostgres::Settings& parDBSettings, bool parForce) { + bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dindb::Settings& parDBSettings, bool parForce) { using mchlib::FileRecordData; using mchlib::SetRecordDataFull; using mchlib::SetRecordData; @@ -124,7 +124,7 @@ namespace { const auto& first_hash = parData.front().hash; FileRecordData itm; SetRecordDataFull set; - const bool already_in_db = dinbpostgres::read_from_db(itm, set, parDBSettings, first_hash); + const bool already_in_db = dindb::read_from_db(itm, set, parDBSettings, first_hash); if (already_in_db) { return false; } @@ -134,7 +134,7 @@ namespace { const auto app_signature = dinlib::dindexer_signature(); const auto lib_signature = mchlib::lib_signature(); const std::string signature = std::string(app_signature.data(), app_signature.size()) + "/" + std::string(lib_signature.data(), lib_signature.size()); - dinbpostgres::write_to_db(parDBSettings, parData, set_data, signature); + dindb::write_to_db(parDBSettings, parData, set_data, signature); return true; } diff --git a/src/tag/main.cpp b/src/tag/main.cpp index f8fefc3..66005c0 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -47,8 +47,8 @@ namespace { return retval; } - dinbpostgres::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) { - dinbpostgres::OwnerSetInfo set_info; + dindb::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) { + dindb::OwnerSetInfo set_info; if (parVM.count("set")) { set_info.is_valid = true; set_info.group_id = parVM["set"].as(); @@ -60,11 +60,11 @@ namespace { return set_info; } - int tag_files (const dinbpostgres::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int tag_files (const dindb::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; - const dinbpostgres::OwnerSetInfo set_info = make_owner_set_info(parVM); + const dindb::OwnerSetInfo set_info = make_owner_set_info(parVM); switch (parMode) { case TaggingMode::ID: @@ -73,14 +73,14 @@ namespace { std::vector ids; ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); - dinbpostgres::tag_files(parDB, ids, parTags, set_info); + dindb::tag_files(parDB, ids, parTags, set_info); return 0; } case TaggingMode::Glob: { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); - dinbpostgres::tag_files(parDB, regexes, parTags, set_info); + dindb::tag_files(parDB, regexes, parTags, set_info); return 0; } @@ -90,7 +90,7 @@ namespace { } } - int delete_tags (const dinbpostgres::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int delete_tags (const dindb::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; @@ -104,9 +104,9 @@ namespace { ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); if (parVM.count("alltags")) - dinbpostgres::delete_all_tags(parDB, ids, make_owner_set_info(parVM)); + dindb::delete_all_tags(parDB, ids, make_owner_set_info(parVM)); else - dinbpostgres::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM)); + dindb::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM)); return 0; } @@ -114,9 +114,9 @@ namespace { { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); if (parVM.count("alltags")) - dinbpostgres::delete_all_tags(parDB, regexes, make_owner_set_info(parVM)); + dindb::delete_all_tags(parDB, regexes, make_owner_set_info(parVM)); else - dinbpostgres::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM)); + dindb::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM)); return 0; } From 064fc0cf1a37d6d553053ee4f496a304d9244869 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 20:28:26 +0200 Subject: [PATCH 011/170] Create intermediate backend lib to help loading backend plugins. --- CMakeLists.txt | 2 +- include/backends/backend_loader.hpp | 59 ++++++++++ include/backends/db_backend.hpp | 49 ++++++++ include/backends/exposed_functions.hpp | 33 ++++++ src/backends/CMakeLists.txt | 28 +++++ src/backends/backend_loader.cpp | 107 ++++++++++++++++++ src/backends/postgresql/CMakeLists.txt | 1 + .../postgresql/backend_postgresql.cpp | 102 +++++++++++++++++ .../postgresql/backend_postgresql.hpp | 49 ++++++++ src/common/CMakeLists.txt | 2 - src/main/CMakeLists.txt | 1 - 11 files changed, 429 insertions(+), 4 deletions(-) create mode 100644 include/backends/backend_loader.hpp create mode 100644 include/backends/db_backend.hpp create mode 100644 include/backends/exposed_functions.hpp create mode 100644 src/backends/CMakeLists.txt create mode 100644 src/backends/backend_loader.cpp create mode 100644 src/backends/postgresql/backend_postgresql.cpp create mode 100644 src/backends/postgresql/backend_postgresql.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fd4155..75c121f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,7 +129,7 @@ add_subdirectory(src/common) add_subdirectory(src/machinery) add_subdirectory(lib/pbl) add_subdirectory(lib/glob2regex) -add_subdirectory(src/backends/postgresql) +add_subdirectory(src/backends) #Actions add_subdirectory(src/main) diff --git a/include/backends/backend_loader.hpp b/include/backends/backend_loader.hpp new file mode 100644 index 0000000..70bb592 --- /dev/null +++ b/include/backends/backend_loader.hpp @@ -0,0 +1,59 @@ +/* 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 id756A258A98B24B0DB2529BCEEC5137E2 +#define id756A258A98B24B0DB2529BCEEC5137E2 + +#include +#include +#include + +namespace YAML { + class Node; +} //namespace YAML + +namespace dindb { + class Backend; + + using BackendPtr = std::unique_ptr; + + class BackendPlugin { + public: + BackendPlugin ( void ); + BackendPlugin ( BackendPlugin&& ) = default; + BackendPlugin ( const std::string& parSOPath, const YAML::Node* parConfig ); + ~BackendPlugin ( void ) noexcept; + + const boost::string_ref& name ( void ) const; + Backend& backend ( void ); + const Backend& backend ( void ) const; + bool is_loaded ( void ) const; + + BackendPlugin& operator= ( BackendPlugin&& ) = default; + + private: + using SoHandle = std::unique_ptr; + + SoHandle m_lib; + BackendPtr m_backend; + boost::string_ref m_name; + }; + + std::string backend_name ( const std::string& parSOPath ); +} //namespace dindb + +#endif diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp new file mode 100644 index 0000000..cc79b43 --- /dev/null +++ b/include/backends/db_backend.hpp @@ -0,0 +1,49 @@ +/* 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 id7506CA9825454B80856154ACFE8A9DE2 +#define id7506CA9825454B80856154ACFE8A9DE2 + +#include "backends/backend_loader.hpp" +#include +#include +#include +#include + +namespace dindb { + using GroupIDType = uint32_t; + using FileIDType = uint64_t; + + constexpr const GroupIDType InvalidGroupID = 0; + constexpr const FileIDType InvalidFileID = 0; + + class Backend { + public: + Backend ( void ) = default; + virtual ~Backend ( void ) noexcept = default; + + virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const = 0; + virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const = 0; + virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const = 0; + virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const = 0; + virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) const = 0; + virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) const = 0; + + }; +} //namespace dindb + +#endif diff --git a/include/backends/exposed_functions.hpp b/include/backends/exposed_functions.hpp new file mode 100644 index 0000000..a1b21e9 --- /dev/null +++ b/include/backends/exposed_functions.hpp @@ -0,0 +1,33 @@ +/* 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 idA9E47E37E2FA49EE84C2E93FB701C368 +#define idA9E47E37E2FA49EE84C2E93FB701C368 + +namespace YAML { + class Node; +} //namespace YAML + +namespace dindb { + class Backend; +} //namespace dindb + +extern "C" dindb::Backend* dindexer_create_backend ( const YAML::Node* parConfig ); +extern "C" void dindexer_destroy_backend ( dindb::Backend* parDele ); +extern "C" const char* dindexer_backend_name ( void ); + +#endif diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt new file mode 100644 index 0000000..eae379f --- /dev/null +++ b/src/backends/CMakeLists.txt @@ -0,0 +1,28 @@ +project(${bare_name}-backend CXX) + +add_library(${PROJECT_NAME} STATIC + backend_loader.cpp +) + +target_include_directories(${PROJECT_NAME} + PUBLIC ${DINDEXER_PUB_INCLUDE_DIR} +) +target_include_directories(${PROJECT_NAME} SYSTEM + PUBLIC ${YAMLCPP_INCLUDE_DIR} +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE ${bare_name}-if + PUBLIC ${YAMLCPP_LIBRARY} + PUBLIC dl +) + +#install(TARGETS ${PROJECT_NAME} +# LIBRARY DESTINATION lib +# RUNTIME DESTINATION bin +# ARCHIVE DESTINATION lib/static +#) + +add_subdirectory(postgresql) + +add_dependencies(${PROJECT_NAME} ${bare_name}-backend-postgresql) diff --git a/src/backends/backend_loader.cpp b/src/backends/backend_loader.cpp new file mode 100644 index 0000000..a6eba27 --- /dev/null +++ b/src/backends/backend_loader.cpp @@ -0,0 +1,107 @@ +/* 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 . + */ + +//See: +// http://stackoverflow.com/questions/496664/c-dynamic-shared-library-on-linux + +#include "backends/backend_loader.hpp" +#include "backends/exposed_functions.hpp" +#include +#include +#include + +namespace dindb { + namespace { + BackendPtr load_backend (void* parSOHandle, const YAML::Node* parConfig) { + typedef decltype(&dindexer_create_backend) CreateBackendFun; + typedef decltype(&dindexer_destroy_backend) DeleteBackendFun; + + assert(parSOHandle); + assert(parConfig); + + auto create = reinterpret_cast(dlsym(parSOHandle, "dindexer_create_backend")); + auto destroy = reinterpret_cast(dlsym(parSOHandle, "dindexer_destroy_backend")); + + return BackendPtr(create(parConfig), destroy); + } + + const char* backend_name (void* parSOHandle) { + typedef decltype(&dindexer_backend_name) GetNameFun; + + assert(parSOHandle); + + auto get_name = reinterpret_cast(dlsym(parSOHandle, "dindexer_backend_name")); + return get_name(); + } + + void nop_destroy (Backend*) { + } + } //unnamed namespace + + std::string backend_name (const std::string& parSOPath) { + assert(not parSOPath.empty()); + using SoHandle = std::unique_ptr; + + auto handle = SoHandle(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose); + return backend_name(handle.get()); + } + + BackendPlugin::BackendPlugin() : + m_lib(nullptr, &dlclose), + m_backend(nullptr, &nop_destroy), + m_name() + { + } + + BackendPlugin::BackendPlugin (const std::string& parSOPath, const YAML::Node* parConfig) : + m_lib(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose), + m_backend(load_backend(m_lib.get(), parConfig)), + m_name(backend_name(m_lib.get())) + { + } + + BackendPlugin::~BackendPlugin() noexcept { + } + + const boost::string_ref& BackendPlugin::name() const { + return m_name; + } + + Backend& BackendPlugin::backend() { + assert(m_lib); + assert(m_backend); + if (not m_backend) { + throw std::bad_function_call(); + } + + return *m_backend; + } + + const Backend& BackendPlugin::backend() const { + assert(m_lib); + assert(m_backend); + if (not m_backend) { + throw std::bad_function_call(); + } + + return *m_backend; + } + + bool BackendPlugin::is_loaded() const { + return static_cast(m_backend); + } +} //namespace dindb diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 8238350..40eb8e3 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(${PROJECT_NAME} STATIC locate.cpp scan.cpp dbsource.cpp + backend_postgresql.cpp ) target_include_directories(${PROJECT_NAME} diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp new file mode 100644 index 0000000..7ccf8cc --- /dev/null +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -0,0 +1,102 @@ +/* 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_postgresql.hpp" +#include "backends/exposed_functions.hpp" +#include "pq/connection.hpp" +#include +#include +#include +#include + +namespace YAML { + template<> + struct convert { + static Node encode (const dindb::Settings& parSettings) { + Node node; + node["address"] = parSettings.address; + node["username"] = parSettings.username; + node["password"] = parSettings.password; + node["port"] = parSettings.port; + node["dbname"] = parSettings.dbname; + return node; + } + + static bool decode (const Node& parNode, dindb::Settings& parSettings) { + if (not parNode.IsMap() or parNode.size() != 5) { + return false; + } + + parSettings.address = parNode["address"].as(); + parSettings.username = parNode["username"].as(); + parSettings.password = parNode["password"].as(); + parSettings.dbname = parNode["dbname"].as(); + parSettings.port = parNode["port"].as(); + return true; + } + }; +} //namespace YAML + +namespace dindb { + BackendPostgreSql::BackendPostgreSql (std::string&& parUser, std::string&& parPass, std::string&& parDB, std::string&& parAddr, uint16_t parPort) : + m_conn(new pq::Connection(std::move(parUser), std::move(parPass), std::move(parDB), std::move(parAddr), parPort)) + { + assert(m_conn); + m_conn->connect(); + } + + BackendPostgreSql::~BackendPostgreSql() noexcept { + m_conn->disconnect(); + } + + void BackendPostgreSql::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) const { + if (InvalidGroupID != parSet) { + const std::string query = + "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2) AND \"group_id\"=$3;"; + m_conn->query(query, parTags, parFiles, parSet); + } + else { + const std::string query = + "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2);"; + m_conn->query(query, parTags, parFiles); + } + } + + void BackendPostgreSql::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) const { + } + + void BackendPostgreSql::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) const { + } + + void BackendPostgreSql::delete_tags (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) const { + } + + void BackendPostgreSql::delete_all_tags (const std::vector& parFiles, GroupIDType parSet) const { + } + + void BackendPostgreSql::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) const { + } +} //namespace dindb + +extern "C" dindb::Backend* create_backend (const YAML::Node*) { + return new dindb::BackendPostgreSql("A", "B", "C", "D", 1); +} + +extern "C" void destroy_backend (dindb::Backend* parDele) { + if (parDele) + delete parDele; +} diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp new file mode 100644 index 0000000..bce0e7c --- /dev/null +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -0,0 +1,49 @@ +/* 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 idBE5BBAFEC7334F39AC9338F193703341 +#define idBE5BBAFEC7334F39AC9338F193703341 + +#include "backends/db_backend.hpp" +#include +#include +#include + +namespace pq { + class Connection; +} //namespace pq + +namespace dindb { + class BackendPostgreSql : public Backend { + public: + BackendPostgreSql ( BackendPostgreSql&& ) = default; + BackendPostgreSql ( std::string&& parUser, std::string&& parPass, std::string&& parDB, std::string&& parAddr, uint16_t parPort ); + virtual ~BackendPostgreSql ( void ) noexcept; + + virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const override; + virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const override; + virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const override; + virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const override; + virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) const override; + virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) const override; + + private: + std::unique_ptr m_conn; + }; +} //namespace dindb + +#endif diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e41e3b5..724d45f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -19,8 +19,6 @@ target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${Readline_INCLUDE_DIR} ) -string(TOLOWER "${DINDEXER_DB_BACKEND}" DINDEXER_DB_BACKEND_LOWERCASE) - target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${YAMLCPP_LIBRARY} diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 1b16abb..8f0f1d8 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -12,7 +12,6 @@ add_executable(${PROJECT_NAME} make_timestamp(${bare_name} timestamp.h.in) target_include_directories(${PROJECT_NAME} - PRIVATE ${CMAKE_SOURCE_DIR}/include PRIVATE ${CMAKE_SOURCE_DIR}/lib/pbl/pbl/src/src PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ) From c97a08860feb99e87a1093bbd54aaa4a442f6688 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 20:29:32 +0200 Subject: [PATCH 012/170] Get rid of the DB_BACKEND build setting. --- CMakeLists.txt | 1 - src/dindexerConfig.h.in | 2 -- src/main/builtin_feats.c | 1 - 3 files changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75c121f..8149f6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ if(DINDEXER_NATIVE_RELEASE) else() set(march_flag "") endif() -set(DINDEXER_DB_BACKEND "PostgreSQL") set(DINDEXER_COPYRIGHT_YEARS "2015,2016") set(DINDEXER_ACTIONS_PATH "${CMAKE_CURRENT_BINARY_DIR}/src" CACHE STRING "Actions search path") string(REGEX MATCH "[^/].*" ACTIONS_PATH_INSTALL "${DINDEXER_ACTIONS_PATH}") diff --git a/src/dindexerConfig.h.in b/src/dindexerConfig.h.in index 8f1eae6..7d2493c 100644 --- a/src/dindexerConfig.h.in +++ b/src/dindexerConfig.h.in @@ -50,8 +50,6 @@ # define WITH_NICE_MEDIA_TYPES #endif -#define DB_BACKEND "@DINDEXER_DB_BACKEND@" - #define COPYRIGHT_YEARS_LIST @DINDEXER_COPYRIGHT_YEARS@ #endif diff --git a/src/main/builtin_feats.c b/src/main/builtin_feats.c index 0ffba59..9c6e851 100644 --- a/src/main/builtin_feats.c +++ b/src/main/builtin_feats.c @@ -52,7 +52,6 @@ void print_builtin_feats() { #else printf("WITH_NICE_MEDIA_TYPES = no\n"); #endif - printf("DB_BACKEND = \"%s\"\n", DB_BACKEND); } void print_version() { From 20b2a8695eefbf743dcd519376d6da8cbb16d442 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 20:31:07 +0200 Subject: [PATCH 013/170] Load postgresql plugin and use that in tag. Only partially implemented. --- dindexer.yml | 3 +- include/dindexer-common/settings.hpp | 6 ++- src/backends/postgresql/CMakeLists.txt | 4 +- .../postgresql/backend_postgresql.cpp | 38 +++++++++++--- src/common/CMakeLists.txt | 2 +- src/common/settings.cpp | 50 ++++++++----------- src/pq/CMakeLists.txt | 3 ++ src/tag/main.cpp | 42 +++++++--------- 8 files changed, 83 insertions(+), 65 deletions(-) diff --git a/dindexer.yml b/dindexer.yml index 1d3b7a9..d13cd0d 100644 --- a/dindexer.yml +++ b/dindexer.yml @@ -1,6 +1,7 @@ %YAML 1.2 --- -db_settings: +db_backend_name: postgresql +db_backend_settings: username: your_username password: your_password dbname: dindexer diff --git a/include/dindexer-common/settings.hpp b/include/dindexer-common/settings.hpp index 0a689bc..11f295f 100644 --- a/include/dindexer-common/settings.hpp +++ b/include/dindexer-common/settings.hpp @@ -19,11 +19,13 @@ #define idDC29E3C667BD4793BA0644AE7DC5BD3F #include -#include "db/settings.hpp" +#include "backends/backend_loader.hpp" +#include "backends/db_backend.hpp" namespace dinlib { struct Settings { - dindb::Settings db; + std::string backend_name; + dindb::BackendPlugin backend_plugin; }; bool load_settings ( const std::string& parPath, Settings& parOut, bool parExpand=true ); diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 40eb8e3..cdf8915 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -1,6 +1,6 @@ project(${bare_name}-backend-postgresql CXX) -add_library(${PROJECT_NAME} STATIC +add_library(${PROJECT_NAME} SHARED tag.cpp delete.cpp locate.cpp @@ -10,7 +10,7 @@ add_library(${PROJECT_NAME} STATIC ) target_include_directories(${PROJECT_NAME} - PUBLIC ${CMAKE_SOURCE_DIR}/include/backends/postgresql + PUBLIC ${DINDEXER_PUB_INCLUDE_DIR}/backends/postgresql ) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS} diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index 7ccf8cc..cab4487 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -23,10 +23,22 @@ #include #include +namespace dindb { + namespace { + struct PostgreConnectionSettings { + std::string address; + std::string username; + std::string password; + std::string dbname; + uint16_t port; + }; + } //unnamed namespace +} //namespace dindb + namespace YAML { template<> - struct convert { - static Node encode (const dindb::Settings& parSettings) { + struct convert { + static Node encode (const dindb::PostgreConnectionSettings& parSettings) { Node node; node["address"] = parSettings.address; node["username"] = parSettings.username; @@ -36,7 +48,7 @@ namespace YAML { return node; } - static bool decode (const Node& parNode, dindb::Settings& parSettings) { + static bool decode (const Node& parNode, dindb::PostgreConnectionSettings& parSettings) { if (not parNode.IsMap() or parNode.size() != 5) { return false; } @@ -92,11 +104,25 @@ namespace dindb { } } //namespace dindb -extern "C" dindb::Backend* create_backend (const YAML::Node*) { - return new dindb::BackendPostgreSql("A", "B", "C", "D", 1); +extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { + if (not parConfig) + return nullptr; + + auto config = parConfig->as(); + return new dindb::BackendPostgreSql( + std::move(config.username), + std::move(config.password), + std::move(config.dbname), + std::move(config.address), + config.port + ); } -extern "C" void destroy_backend (dindb::Backend* parDele) { +extern "C" void dindexer_destroy_backend (dindb::Backend* parDele) { if (parDele) delete parDele; } + +extern "C" const char* dindexer_backend_name() { + return "postgresql"; +} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 724d45f..d8a1ebd 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -23,7 +23,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if PRIVATE ${YAMLCPP_LIBRARY} PRIVATE ${Readline_LIBRARY} - PUBLIC ${bare_name}-backend-${DINDEXER_DB_BACKEND_LOWERCASE} + ${bare_name}-backend ) #install(TARGETS ${PROJECT_NAME} diff --git a/src/common/settings.cpp b/src/common/settings.cpp index cb50215..811a0f4 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -16,41 +16,15 @@ */ #include "dindexer-common/settings.hpp" +#include "dindexerConfig.h" #include #include #include -namespace YAML { - template<> - struct convert { - static Node encode (const dindb::Settings& parSettings) { - Node node; - node["address"] = parSettings.address; - node["username"] = parSettings.username; - node["password"] = parSettings.password; - node["port"] = parSettings.port; - node["dbname"] = parSettings.dbname; - return node; - } - - static bool decode (const Node& parNode, dindb::Settings& parSettings) { - if (not parNode.IsMap() or parNode.size() != 5) { - return false; - } - - parSettings.address = parNode["address"].as(); - parSettings.username = parNode["username"].as(); - parSettings.password = parNode["password"].as(); - parSettings.dbname = parNode["dbname"].as(); - parSettings.port = parNode["port"].as(); - return true; - } - }; -} //namespace YAML - namespace dinlib { namespace { std::string expand ( const char* parString ); + std::string find_plugin_by_name ( const std::string& parName ); } //unnamed namespace bool load_settings (const std::string& parPath, dinlib::Settings& parOut, bool parExpand) { @@ -59,8 +33,14 @@ namespace dinlib { try { auto settings = YAML::LoadFile(path); - if (settings["db_settings"]) { - parOut.db = settings["db_settings"].as(); + if (not settings["db_backend_name"]) { + return false; + } + parOut.backend_name = settings["db_backend_name"].as(); + if (settings["db_backend_settings"]) { + //parOut.db = settings["db_backend_settings"].as(); + auto settings_node = settings["db_backend_settings"]; + parOut.backend_plugin = dindb::BackendPlugin(find_plugin_by_name(parOut.backend_name), &settings_node); return true; } } @@ -83,5 +63,15 @@ namespace dinlib { wordfree(&p); return oss.str(); } + + std::string find_plugin_by_name (const std::string& parName) { + //assert(false); //not implemented + //TODO: write a proper implementation + std::string path = ACTIONS_SEARCH_PATH; + path += "/backends/postgresql/libdindexer-backend-postgresql.so"; + + assert(dindb::backend_name(path) == parName); + return path; + } } //unnamed namespace } //namespace dinlib diff --git a/src/pq/CMakeLists.txt b/src/pq/CMakeLists.txt index 543e6e3..6bda657 100644 --- a/src/pq/CMakeLists.txt +++ b/src/pq/CMakeLists.txt @@ -1,5 +1,8 @@ project(${bare_name}-pq CXX) +set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC") +set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fPIC") + add_library(${PROJECT_NAME} STATIC connection.cpp databaseexception.cpp diff --git a/src/tag/main.cpp b/src/tag/main.cpp index 66005c0..5195640 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -18,7 +18,6 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "db/tag.hpp" #include "dindexer-common/split_tags.hpp" #include "glob2regex/glob2regex.hpp" #include "enum.h" @@ -47,24 +46,18 @@ namespace { return retval; } - dindb::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) { - dindb::OwnerSetInfo set_info; - if (parVM.count("set")) { - set_info.is_valid = true; - set_info.group_id = parVM["set"].as(); - } - else { - set_info.is_valid = false; - set_info.group_id = 0; - } - return set_info; + dindb::GroupIDType make_owner_set_info (const boost::program_options::variables_map& parVM) { + if (parVM.count("set")) + return parVM["set"].as(); + else + return dindb::InvalidGroupID; } - int tag_files (const dindb::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int tag_files (dindb::Backend& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; - const dindb::OwnerSetInfo set_info = make_owner_set_info(parVM); + const auto set_info = make_owner_set_info(parVM); switch (parMode) { case TaggingMode::ID: @@ -73,14 +66,14 @@ namespace { std::vector ids; ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); - dindb::tag_files(parDB, ids, parTags, set_info); + parDB.tag_files(ids, parTags, set_info); return 0; } case TaggingMode::Glob: { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); - dindb::tag_files(parDB, regexes, parTags, set_info); + parDB.tag_files(regexes, parTags, set_info); return 0; } @@ -90,7 +83,7 @@ namespace { } } - int delete_tags (const dindb::Settings& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { + int delete_tags (dindb::Backend& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector& parTags) { using boost::lexical_cast; using boost::string_ref; @@ -104,9 +97,9 @@ namespace { ids.reserve(ids_string.size()); std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast); if (parVM.count("alltags")) - dindb::delete_all_tags(parDB, ids, make_owner_set_info(parVM)); + parDB.delete_all_tags(ids, make_owner_set_info(parVM)); else - dindb::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM)); + parDB.delete_tags(ids, parTags, make_owner_set_info(parVM)); return 0; } @@ -114,9 +107,9 @@ namespace { { const auto regexes(globs_to_regex_list(parVM["globs"].as>())); if (parVM.count("alltags")) - dindb::delete_all_tags(parDB, regexes, make_owner_set_info(parVM)); + parDB.delete_all_tags(regexes, make_owner_set_info(parVM)); else - dindb::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM)); + parDB.delete_tags(regexes, parTags, make_owner_set_info(parVM)); return 0; } @@ -160,6 +153,9 @@ int main (int parArgc, char* parArgv[]) { std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; return 1; } + //TODO: throw if plugin loading failed + assert(settings.backend_plugin.name() == settings.backend_name); + assert(settings.backend_plugin.is_loaded()); } const auto master_tags_string = vm["tags"].as(); @@ -167,7 +163,7 @@ int main (int parArgc, char* parArgv[]) { const auto mode = (glob_mode ? TaggingMode::Glob : TaggingMode::ID); if (not vm.count("delete")) - return tag_files(settings.db, mode, vm, tags); + return tag_files(settings.backend_plugin.backend(), mode, vm, tags); else - return delete_tags(settings.db, mode, vm, tags); + return delete_tags(settings.backend_plugin.backend(), mode, vm, tags); } From 3927f945ca73481508de46d038b6d29813b56714 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 21:49:50 +0200 Subject: [PATCH 014/170] Move postgresql header files to the src directory They are private, and anyways no client needs to include anything at all from the various backends. --- include/backends/postgresql/db/settings.hpp | 34 ------------------- src/backends/postgresql/CMakeLists.txt | 3 -- .../backends/postgresql}/dbsource.hpp | 0 .../db => src/backends/postgresql}/delete.hpp | 0 .../db => src/backends/postgresql}/locate.hpp | 0 .../db => src/backends/postgresql}/scan.hpp | 0 .../db => src/backends/postgresql}/tag.hpp | 0 7 files changed, 37 deletions(-) delete mode 100644 include/backends/postgresql/db/settings.hpp rename {include/backends/postgresql/db => src/backends/postgresql}/dbsource.hpp (100%) rename {include/backends/postgresql/db => src/backends/postgresql}/delete.hpp (100%) rename {include/backends/postgresql/db => src/backends/postgresql}/locate.hpp (100%) rename {include/backends/postgresql/db => src/backends/postgresql}/scan.hpp (100%) rename {include/backends/postgresql/db => src/backends/postgresql}/tag.hpp (100%) diff --git a/include/backends/postgresql/db/settings.hpp b/include/backends/postgresql/db/settings.hpp deleted file mode 100644 index 3f384b2..0000000 --- a/include/backends/postgresql/db/settings.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 idC895D12FEB324387A37FF631E0C09560 -#define idC895D12FEB324387A37FF631E0C09560 - -#include -#include - -namespace dindb { - struct Settings { - std::string address; - std::string username; - std::string password; - std::string dbname; - uint16_t port; - }; -} //namespace dindb - -#endif diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index cdf8915..bd84007 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -9,9 +9,6 @@ add_library(${PROJECT_NAME} SHARED backend_postgresql.cpp ) -target_include_directories(${PROJECT_NAME} - PUBLIC ${DINDEXER_PUB_INCLUDE_DIR}/backends/postgresql -) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS} ) diff --git a/include/backends/postgresql/db/dbsource.hpp b/src/backends/postgresql/dbsource.hpp similarity index 100% rename from include/backends/postgresql/db/dbsource.hpp rename to src/backends/postgresql/dbsource.hpp diff --git a/include/backends/postgresql/db/delete.hpp b/src/backends/postgresql/delete.hpp similarity index 100% rename from include/backends/postgresql/db/delete.hpp rename to src/backends/postgresql/delete.hpp diff --git a/include/backends/postgresql/db/locate.hpp b/src/backends/postgresql/locate.hpp similarity index 100% rename from include/backends/postgresql/db/locate.hpp rename to src/backends/postgresql/locate.hpp diff --git a/include/backends/postgresql/db/scan.hpp b/src/backends/postgresql/scan.hpp similarity index 100% rename from include/backends/postgresql/db/scan.hpp rename to src/backends/postgresql/scan.hpp diff --git a/include/backends/postgresql/db/tag.hpp b/src/backends/postgresql/tag.hpp similarity index 100% rename from include/backends/postgresql/db/tag.hpp rename to src/backends/postgresql/tag.hpp From c009c07c9d21e6c47d28d3fa39d6a38f7015bacc Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 21:50:09 +0200 Subject: [PATCH 015/170] Temporarily disable broken stuff --- CMakeLists.txt | 10 +++++----- src/backends/postgresql/CMakeLists.txt | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8149f6f..a636901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,11 +132,11 @@ add_subdirectory(src/backends) #Actions add_subdirectory(src/main) -add_subdirectory(src/scan) -add_subdirectory(src/delete) -add_subdirectory(src/query) -add_subdirectory(src/locate) -add_subdirectory(src/navigate) +#add_subdirectory(src/scan) +#add_subdirectory(src/delete) +#add_subdirectory(src/query) +#add_subdirectory(src/locate) +#add_subdirectory(src/navigate) add_subdirectory(src/tag) #Tests diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index bd84007..6b840e4 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -2,10 +2,10 @@ project(${bare_name}-backend-postgresql CXX) add_library(${PROJECT_NAME} SHARED tag.cpp - delete.cpp - locate.cpp - scan.cpp - dbsource.cpp + #delete.cpp + #locate.cpp + #scan.cpp + #dbsource.cpp backend_postgresql.cpp ) From df2e04a02920fec5c2ba45ed779c44db02643341 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 27 May 2016 21:51:15 +0200 Subject: [PATCH 016/170] Fix tagging. Tag functions are now fully available through the new plugin. --- include/backends/db_backend.hpp | 12 +-- .../postgresql/backend_postgresql.cpp | 29 +++--- .../postgresql/backend_postgresql.hpp | 12 +-- src/backends/postgresql/tag.cpp | 90 +++++++++---------- src/backends/postgresql/tag.hpp | 23 ++--- 5 files changed, 79 insertions(+), 87 deletions(-) diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index cc79b43..9744ff0 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -36,12 +36,12 @@ namespace dindb { Backend ( void ) = default; virtual ~Backend ( void ) noexcept = default; - virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const = 0; - virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const = 0; - virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const = 0; - virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const = 0; - virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) const = 0; - virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) const = 0; + virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) = 0; + virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) = 0; + virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) = 0; + virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) = 0; + virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) = 0; + virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) = 0; }; } //namespace dindb diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index cab4487..f51d0b3 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -17,6 +17,7 @@ #include "backend_postgresql.hpp" #include "backends/exposed_functions.hpp" +#include "tag.hpp" #include "pq/connection.hpp" #include #include @@ -75,32 +76,28 @@ namespace dindb { m_conn->disconnect(); } - void BackendPostgreSql::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) const { - if (InvalidGroupID != parSet) { - const std::string query = - "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2) AND \"group_id\"=$3;"; - m_conn->query(query, parTags, parFiles, parSet); - } - else { - const std::string query = - "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2);"; - m_conn->query(query, parTags, parFiles); - } + void BackendPostgreSql::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + dindb::tag_files(*m_conn, parFiles, parTags, parSet); } - void BackendPostgreSql::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) const { + void BackendPostgreSql::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + dindb::tag_files(*m_conn, parRegexes, parTags, parSet); } - void BackendPostgreSql::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) const { + void BackendPostgreSql::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + dindb::delete_tags(*m_conn, parFiles, parTags, parSet); } - void BackendPostgreSql::delete_tags (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) const { + void BackendPostgreSql::delete_tags (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + dindb::delete_tags(*m_conn, parRegexes, parTags, parSet); } - void BackendPostgreSql::delete_all_tags (const std::vector& parFiles, GroupIDType parSet) const { + void BackendPostgreSql::delete_all_tags (const std::vector& parFiles, GroupIDType parSet) { + dindb::delete_all_tags(*m_conn, parFiles, parSet); } - void BackendPostgreSql::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) const { + void BackendPostgreSql::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) { + dindb::delete_all_tags(*m_conn, parRegexes, parSet); } } //namespace dindb diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index bce0e7c..bc87c4a 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -34,12 +34,12 @@ namespace dindb { BackendPostgreSql ( std::string&& parUser, std::string&& parPass, std::string&& parDB, std::string&& parAddr, uint16_t parPort ); virtual ~BackendPostgreSql ( void ) noexcept; - virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const override; - virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const override; - virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) const override; - virtual void delete_tags ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) const override; - virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) const override; - virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) const 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; private: std::unique_ptr m_conn; diff --git a/src/backends/postgresql/tag.cpp b/src/backends/postgresql/tag.cpp index 79426b1..7f0e999 100644 --- a/src/backends/postgresql/tag.cpp +++ b/src/backends/postgresql/tag.cpp @@ -15,141 +15,135 @@ * along with "dindexer". If not, see . */ -#include "db/tag.hpp" -#include "db/settings.hpp" +#include "tag.hpp" #include "pq/connection.hpp" #include +#include namespace dindb { - void tag_files (const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void tag_files (pq::Connection& parDB, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + assert(parDB.is_connected()); - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2) AND \"group_id\"=$3;"; - conn.query(query, parTags, parFiles, parSet.group_id); + parDB.query(query, parTags, parFiles, parSet); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"id\"=ANY($2);"; - conn.query(query, parTags, parFiles); + parDB.query(query, parTags, parFiles); } } - void tag_files (const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void tag_files (pq::Connection& parDB, const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + assert(parDB.is_connected()); - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { if (parRegexes.size() == 1) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"group_id\"=$2 AND \"path\" ~ $3;"; - conn.query(query, parTags, parSet.group_id, parRegexes.front()); + parDB.query(query, parTags, parSet, parRegexes.front()); } else if (parRegexes.size() > 1) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"group_id\"=$2 AND \"path\" ~ ANY($3);"; - conn.query(query, parTags, parSet.group_id, parRegexes); + parDB.query(query, parTags, parSet, parRegexes); } else if (parRegexes.size() == 0) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) WHERE \"group_id\"=$2 ORDER BY 1);"; - conn.query(query, parTags, parSet.group_id); + parDB.query(query, parTags, parSet); } } else { if (parRegexes.size() == 1) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"path\" ~ $2;"; - conn.query(query, parTags, parRegexes.front()); + parDB.query(query, parTags, parRegexes.front()); } else if (parRegexes.size() > 1) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"path\" ~ ANY($2);"; - conn.query(query, parTags, parRegexes); + parDB.query(query, parTags, parRegexes); } else if (parRegexes.size() == 0) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1);"; - conn.query(query, parTags); + parDB.query(query, parTags); } } } - void delete_tags (const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void delete_tags (pq::Connection& parDB, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { + assert(parDB.is_connected()); if (parTags.size() == 1) { - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"id\" = ANY($2) AND \"group_id\" = $3;"; - conn.query(query, parTags.front(), parFiles, parSet.group_id); + parDB.query(query, parTags.front(), parFiles, parSet); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"id\" = ANY($2);"; - conn.query(query, parTags.front(), parFiles); + parDB.query(query, parTags.front(), parFiles); } } else { - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT UNNEST(\"tags\") EXCEPT SELECT UNNEST($1)) WHERE \"id\" = ANY($2) AND \"group_id\" = $3;"; - conn.query(query, parTags, parFiles, parSet.group_id); + parDB.query(query, parTags, parFiles, parSet); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT UNNEST(\"tags\") EXCEPT SELECT UNNEST($1)) WHERE \"id\" = ANY($2);"; - conn.query(query, parTags, parFiles); + parDB.query(query, parTags, parFiles); } } } - void delete_tags (const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void delete_tags (pq::Connection& parDB, const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + assert(parDB.is_connected()); if (parTags.size() == 1) { - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"group_id\" = $3 AND \"path\" ~ ANY($3);"; - conn.query(query, parTags.front(), parSet.group_id, parRegexes); + parDB.query(query, parTags.front(), parSet, parRegexes); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"path\" ~ ANY($2);"; - conn.query(query, parTags.front(), parRegexes); + parDB.query(query, parTags.front(), parRegexes); } } else { - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT UNNEST(\"tags\") EXCEPT SELECT UNNEST($1)) WHERE \"group_id\" = $2 AND \"path\" ~ ANY($3);"; - conn.query(query, parTags, parSet.group_id, parRegexes); + parDB.query(query, parTags, parSet, parRegexes); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY(SELECT UNNEST(\"tags\") EXCEPT SELECT UNNEST($1)) WHERE \"path\" = ANY($2);"; - conn.query(query, parTags, parRegexes); + parDB.query(query, parTags, parRegexes); } } } - void delete_all_tags (const Settings& parDB, const std::vector& parFiles, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void delete_all_tags (pq::Connection& parDB, const std::vector& parFiles, GroupIDType parSet) { + assert(parDB.is_connected()); - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"id\"=ANY($1) AND \"group_id\"=$2;"; - conn.query(query, parFiles, parSet.group_id); + parDB.query(query, parFiles, parSet); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"id\"=ANY($1);"; - conn.query(query, parFiles); + parDB.query(query, parFiles); } } - void delete_all_tags (const Settings& parDB, const std::vector& parRegexes, OwnerSetInfo parSet) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + void delete_all_tags (pq::Connection& parDB, const std::vector& parRegexes, GroupIDType parSet) { + assert(parDB.is_connected()); - if (parSet.is_valid) { + if (InvalidGroupID != parSet) { const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"group_id\"=$1 AND \"path\" ~ ANY($2);"; - conn.query(query, parSet.group_id, parRegexes); + parDB.query(query, parSet, parRegexes); } else { const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"path\" ~ ANY($2);"; - conn.query(query, parRegexes); + parDB.query(query, parRegexes); } } } //namespace dindb diff --git a/src/backends/postgresql/tag.hpp b/src/backends/postgresql/tag.hpp index 509f6d3..ed5b7e4 100644 --- a/src/backends/postgresql/tag.hpp +++ b/src/backends/postgresql/tag.hpp @@ -18,25 +18,26 @@ #ifndef idE1E1650A8CAA4949BD6D4D58BF2599F5 #define idE1E1650A8CAA4949BD6D4D58BF2599F5 +#include "backends/db_backend.hpp" #include #include #include +#include + +namespace pq { + class Connection; +} //namespace pq namespace dindb { struct Settings; - struct OwnerSetInfo { - uint32_t group_id; - bool is_valid; - }; + void tag_files ( pq::Connection& parDB, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ); + void tag_files ( pq::Connection& parDB, const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ); - void tag_files ( const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); - void tag_files ( const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); - - void delete_tags ( const Settings& parDB, const std::vector& parFiles, const std::vector& parTags, OwnerSetInfo parSet ); - void delete_tags ( const Settings& parDB, const std::vector& parRegexes, const std::vector& parTags, OwnerSetInfo parSet ); - void delete_all_tags ( const Settings& parDB, const std::vector& parFiles, OwnerSetInfo parSet ); - void delete_all_tags ( const Settings& parDB, const std::vector& parRegexes, OwnerSetInfo parSet ); + void delete_tags ( pq::Connection& parDB, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ); + void delete_tags ( pq::Connection& parDB, const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ); + void delete_all_tags ( pq::Connection& parDB, const std::vector& parFiles, GroupIDType parSet ); + void delete_all_tags ( pq::Connection& parDB, const std::vector& parRegexes, GroupIDType parSet ); } //namespace dindb #endif From 8f51f82abc5bf5b16f01bd34fd110f988bda1471 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 31 May 2016 10:30:16 +0200 Subject: [PATCH 017/170] Re-enable delete subcommand --- CMakeLists.txt | 2 +- include/backends/db_backend.hpp | 5 +++++ src/backends/postgresql/CMakeLists.txt | 2 +- src/backends/postgresql/backend_postgresql.cpp | 5 +++++ src/backends/postgresql/backend_postgresql.hpp | 2 ++ src/backends/postgresql/delete.cpp | 14 +++++++------- src/backends/postgresql/delete.hpp | 9 ++++++--- src/delete/main.cpp | 6 ++++-- 8 files changed, 31 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a636901..d2711e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,7 +133,7 @@ add_subdirectory(src/backends) #Actions add_subdirectory(src/main) #add_subdirectory(src/scan) -#add_subdirectory(src/delete) +add_subdirectory(src/delete) #add_subdirectory(src/query) #add_subdirectory(src/locate) #add_subdirectory(src/navigate) diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index 9744ff0..aadb962 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -23,10 +23,14 @@ #include #include #include +#include +#include namespace dindb { using GroupIDType = uint32_t; using FileIDType = uint64_t; + using IDDescMap = std::map; + using ConfirmDeleCallback = std::function; constexpr const GroupIDType InvalidGroupID = 0; constexpr const FileIDType InvalidFileID = 0; @@ -43,6 +47,7 @@ namespace dindb { virtual void delete_all_tags ( const std::vector& parFiles, GroupIDType parSet ) = 0; virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) = 0; + virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) = 0; }; } //namespace dindb diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 6b840e4..8196219 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -2,7 +2,7 @@ project(${bare_name}-backend-postgresql CXX) add_library(${PROJECT_NAME} SHARED tag.cpp - #delete.cpp + delete.cpp #locate.cpp #scan.cpp #dbsource.cpp diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index f51d0b3..7de7b4a 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -18,6 +18,7 @@ #include "backend_postgresql.hpp" #include "backends/exposed_functions.hpp" #include "tag.hpp" +#include "delete.hpp" #include "pq/connection.hpp" #include #include @@ -99,6 +100,10 @@ namespace dindb { void BackendPostgreSql::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) { dindb::delete_all_tags(*m_conn, parRegexes, parSet); } + + void BackendPostgreSql::delete_group (const std::vector& parIDs, ConfirmDeleCallback parConf) { + dindb::delete_group_from_db(*m_conn, parIDs, parConf); + } } //namespace dindb extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index bc87c4a..15cb0e4 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -41,6 +41,8 @@ namespace dindb { 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; + private: std::unique_ptr m_conn; }; diff --git a/src/backends/postgresql/delete.cpp b/src/backends/postgresql/delete.cpp index f75c54a..a87fda4 100644 --- a/src/backends/postgresql/delete.cpp +++ b/src/backends/postgresql/delete.cpp @@ -15,8 +15,7 @@ * along with "dindexer". If not, see . */ -#include "db/delete.hpp" -#include "db/settings.hpp" +#include "delete.hpp" #include "pq/connection.hpp" #include "helpers/infix_iterator.hpp" #include @@ -26,6 +25,7 @@ #include #include #include +#include namespace dindb { namespace { @@ -50,10 +50,10 @@ namespace dindb { } } //unnamed namespace - void delete_group_from_db (const Settings& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf) { - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); - const auto dele_ids = fetch_existing_ids(conn, parIDs); + void delete_group_from_db (pq::Connection& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf) { + assert(parDB.is_connected()); + + const auto dele_ids = fetch_existing_ids(parDB, parIDs); if (dele_ids.empty()) { return; } @@ -70,6 +70,6 @@ namespace dindb { boost::copy(dele_ids | boost::adaptors::map_keys, infix_ostream_iterator(oss, " OR \"id\"=")); oss << ";\nCOMMIT;"; - conn.query(oss.str()); + parDB.query(oss.str()); } } //namespace dindb diff --git a/src/backends/postgresql/delete.hpp b/src/backends/postgresql/delete.hpp index 90d2c6a..341cc47 100644 --- a/src/backends/postgresql/delete.hpp +++ b/src/backends/postgresql/delete.hpp @@ -18,19 +18,22 @@ #ifndef idB070B86E0E4047B1AF4144DEF2759F3C #define idB070B86E0E4047B1AF4144DEF2759F3C +#include "backends/db_backend.hpp" #include #include #include #include #include -namespace dindb { - struct Settings; +namespace pq { + class Connection; +} //namespace pq +namespace dindb { using IDDescMap = std::map; using ConfirmDeleCallback = std::function; - void delete_group_from_db ( const Settings& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf ); + void delete_group_from_db ( pq::Connection& parDB, const std::vector& parIDs, ConfirmDeleCallback parConf ); } //namespace dindb #endif diff --git a/src/delete/main.cpp b/src/delete/main.cpp index e3e17bf..0c42fb2 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -18,7 +18,6 @@ #include "commandline.hpp" #include "dindexer-common/settings.hpp" #include "dindexerConfig.h" -#include "db/delete.hpp" #include #include #include @@ -69,6 +68,9 @@ int main (int parArgc, char* parArgv[]) { return 1; } } + //TODO: throw if plugin loading failed + assert(settings.backend_plugin.name() == settings.backend_name); + assert(settings.backend_plugin.is_loaded()); if (not vm.count("groupid")) { std::cerr << "No IDs specified\n"; @@ -77,7 +79,7 @@ int main (int parArgc, char* parArgv[]) { const auto ids = vm["groupid"].as>(); auto confirm_func = (vm.count("confirm") ? &always_delete : &confirm_delete); - dindb::delete_group_from_db(settings.db, ids, confirm_func); + settings.backend_plugin.backend().delete_group(ids, confirm_func); return 0; } From 3608d7b76c39d903d080c4c4aa04a985c0399cd4 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 31 May 2016 20:03:31 +0200 Subject: [PATCH 018/170] Re-enable scan in the postgre plugin. This also adds a public dependency to machinery in the header-only backend project. This is because the backend does need functionality from machinery, such as FileRecordData and TigerHash. --- CMakeLists.txt | 2 +- include/backends/db_backend.hpp | 4 +++ src/backends/CMakeLists.txt | 5 ++-- src/backends/postgresql/CMakeLists.txt | 2 +- .../postgresql/backend_postgresql.cpp | 9 ++++++ .../postgresql/backend_postgresql.hpp | 3 ++ src/backends/postgresql/scan.cpp | 28 +++++++++---------- src/backends/postgresql/scan.hpp | 8 ++++-- src/scan/main.cpp | 14 ++++++---- 9 files changed, 48 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2711e8..575583d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ add_subdirectory(src/backends) #Actions add_subdirectory(src/main) -#add_subdirectory(src/scan) +add_subdirectory(src/scan) add_subdirectory(src/delete) #add_subdirectory(src/query) #add_subdirectory(src/locate) diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index aadb962..c2856de 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -19,6 +19,7 @@ #define id7506CA9825454B80856154ACFE8A9DE2 #include "backends/backend_loader.hpp" +#include "dindexer-machinery/recorddata.hpp" #include #include #include @@ -48,6 +49,9 @@ namespace dindb { virtual void delete_all_tags ( const std::vector& parRegexes, GroupIDType parSet ) = 0; virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) = 0; + + virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ) = 0; + virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ) = 0; }; } //namespace dindb diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt index eae379f..0ac6613 100644 --- a/src/backends/CMakeLists.txt +++ b/src/backends/CMakeLists.txt @@ -13,8 +13,9 @@ target_include_directories(${PROJECT_NAME} SYSTEM target_link_libraries(${PROJECT_NAME} PRIVATE ${bare_name}-if - PUBLIC ${YAMLCPP_LIBRARY} - PUBLIC dl + INTERFACE ${YAMLCPP_LIBRARY} + INTERFACE dl + INTERFACE ${bare_name}-machinery ) #install(TARGETS ${PROJECT_NAME} diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 8196219..bb3041c 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -4,7 +4,7 @@ add_library(${PROJECT_NAME} SHARED tag.cpp delete.cpp #locate.cpp - #scan.cpp + scan.cpp #dbsource.cpp backend_postgresql.cpp ) diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index 7de7b4a..fbabb9c 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -19,6 +19,7 @@ #include "backends/exposed_functions.hpp" #include "tag.hpp" #include "delete.hpp" +#include "scan.hpp" #include "pq/connection.hpp" #include #include @@ -104,6 +105,14 @@ namespace dindb { void BackendPostgreSql::delete_group (const std::vector& parIDs, ConfirmDeleCallback parConf) { dindb::delete_group_from_db(*m_conn, parIDs, parConf); } + + void BackendPostgreSql::write_files (const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { + dindb::write_to_db(*m_conn, parData, parSetData, parSignature); + } + + bool BackendPostgreSql::search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { + return dindb::read_from_db(parItem, parSet, *m_conn, parHash); + } } //namespace dindb extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index 15cb0e4..1160ef1 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -43,6 +43,9 @@ namespace dindb { virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) override; + virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); + virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ); + private: std::unique_ptr m_conn; }; diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index 94fe4a8..fd533ed 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -15,8 +15,7 @@ * along with "dindexer". If not, see . */ -#include "db/scan.hpp" -#include "db/settings.hpp" +#include "scan.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/recorddata.hpp" #include @@ -27,20 +26,20 @@ #include #include #include +#include namespace dindb { namespace { } //unnamed namespace - bool read_from_db (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const Settings& parDB, const mchlib::TigerHash& parHash) { + bool read_from_db (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, pq::Connection& parDB, const mchlib::TigerHash& parHash) { using boost::lexical_cast; - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); + assert(parDB.is_connected()); uint32_t group_id; { - auto resultset = conn.query( + auto resultset = parDB.query( "SELECT path,level,group_id,is_directory,is_symlink,size FROM files WHERE hash=$1 LIMIT 1;", tiger_to_string(parHash, true) ); @@ -64,7 +63,7 @@ namespace dindb { } { - auto resultset = conn.query( + auto resultset = parDB.query( "SELECT \"desc\",\"type\",\"disk_number\" FROM sets WHERE \"id\"=$1;", group_id ); @@ -82,21 +81,20 @@ namespace dindb { return true; } - void write_to_db (const Settings& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { + void write_to_db (pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { using std::chrono::system_clock; using boost::lexical_cast; + assert(parDB.is_connected()); + if (parData.empty()) { return; } - pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - conn.connect(); - - conn.query("BEGIN;"); + parDB.query("BEGIN;"); uint32_t new_group_id; { - auto id_res = conn.query("INSERT INTO \"sets\" " + auto id_res = parDB.query("INSERT INTO \"sets\" " "(\"desc\",\"type\",\"app_name\"" ",\"content_type\") " "VALUES ($1, $2, $3, $4) RETURNING \"id\";", @@ -126,7 +124,7 @@ namespace dindb { const auto& itm = parData[z]; assert(itm.path().data()); - conn.query(query, + parDB.query(query, (itm.path().empty() ? empty_path_string : itm.path()), tiger_to_string(itm.hash), itm.level, @@ -142,6 +140,6 @@ namespace dindb { itm.mime_charset() ); } - conn.query("COMMIT;"); + parDB.query("COMMIT;"); } } //namespace dindb diff --git a/src/backends/postgresql/scan.hpp b/src/backends/postgresql/scan.hpp index 877e1e0..72521d7 100644 --- a/src/backends/postgresql/scan.hpp +++ b/src/backends/postgresql/scan.hpp @@ -29,11 +29,15 @@ namespace mchlib { struct TigerHash; } //namespace mchlib +namespace pq { + class Connection; +} //namespace pq + namespace dindb { struct Settings;; - void write_to_db ( const Settings& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); - bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const Settings& parDB, const mchlib::TigerHash& parHash ); + void write_to_db ( pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); + bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, pq::Connection& parDB, const mchlib::TigerHash& parHash ); } //namespace dindb #endif diff --git a/src/scan/main.cpp b/src/scan/main.cpp index a948c07..d739066 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -25,7 +25,6 @@ #include "dindexer-common/common_info.hpp" #include "dindexer-common/settings.hpp" #include "commandline.hpp" -#include "db/scan.hpp" #include "dindexer-machinery/scantask/dirtree.hpp" #include "dindexer-machinery/scantask/mediatype.hpp" #include "dindexer-machinery/scantask/hashing.hpp" @@ -41,7 +40,7 @@ #endif namespace { - bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dindb::Settings& parDBSettings, bool parForce=false ); + bool add_to_db ( const std::vector& parData, const mchlib::SetRecordDataFull& parSet, dindb::Backend& parDB, bool parForce=false ); #if defined(WITH_PROGRESS_FEEDBACK) void print_progress ( const boost::string_ref parPath, uint64_t parFileBytes, uint64_t parTotalBytes, uint32_t parFileNum, std::size_t& parClearCount ); #endif @@ -81,6 +80,9 @@ int main (int parArgc, char* parArgv[]) { return 1; } } + //TODO: throw if plugin loading failed + assert(settings.backend_plugin.name() == settings.backend_name); + assert(settings.backend_plugin.is_loaded()); bool ignore_read_errors = (vm.count("ignore-errors") > 0); const std::string search_path(vm["search-path"].as()); @@ -104,7 +106,7 @@ int main (int parArgc, char* parArgv[]) { ); #endif - const bool added_to_db = add_to_db(filerecdata->get_or_create(), setrecdata->get_or_create(), settings.db); + const bool added_to_db = add_to_db(filerecdata->get_or_create(), setrecdata->get_or_create(), settings.backend_plugin.backend()); #if defined(WITH_PROGRESS_FEEDBACK) std::cout << '\n'; #endif @@ -115,7 +117,7 @@ int main (int parArgc, char* parArgv[]) { } namespace { - bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, const dindb::Settings& parDBSettings, bool parForce) { + bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, dindb::Backend& parDB, bool parForce) { using mchlib::FileRecordData; using mchlib::SetRecordDataFull; using mchlib::SetRecordData; @@ -124,7 +126,7 @@ namespace { const auto& first_hash = parData.front().hash; FileRecordData itm; SetRecordDataFull set; - const bool already_in_db = dindb::read_from_db(itm, set, parDBSettings, first_hash); + const bool already_in_db = parDB.search_file_by_hash(itm, set, first_hash); if (already_in_db) { return false; } @@ -134,7 +136,7 @@ namespace { const auto app_signature = dinlib::dindexer_signature(); const auto lib_signature = mchlib::lib_signature(); const std::string signature = std::string(app_signature.data(), app_signature.size()) + "/" + std::string(lib_signature.data(), lib_signature.size()); - dindb::write_to_db(parDBSettings, parData, set_data, signature); + parDB.write_files(parData, set_data, signature); return true; } From 470738fc1b6bb2a4e8659cd7b51d1df597edfb6d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 1 Jun 2016 10:08:56 +0200 Subject: [PATCH 019/170] Fix typo - correct type is 16 bit int, not 64 --- include/dindexer-machinery/recorddata.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dindexer-machinery/recorddata.hpp b/include/dindexer-machinery/recorddata.hpp index 54b1a77..3afc127 100644 --- a/include/dindexer-machinery/recorddata.hpp +++ b/include/dindexer-machinery/recorddata.hpp @@ -34,7 +34,7 @@ namespace mchlib { typedef boost::flyweight mime_string; FileRecordData ( void ) = default; - FileRecordData ( const char* parPath, std::time_t parATime, std::time_t parMTime, uint64_t parLevel, bool parIsDir, bool parIsSymLink ) : + FileRecordData ( const char* parPath, std::time_t parATime, std::time_t parMTime, uint16_t parLevel, bool parIsDir, bool parIsSymLink ) : hash {}, abs_path(parPath), mime_full(), From 780cd9b0cad7bce773894d640b3aed5e36a84c5b Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 1 Jun 2016 10:27:09 +0200 Subject: [PATCH 020/170] Re-enable locate in the postgre plugin. --- CMakeLists.txt | 2 +- include/backends/db_backend.hpp | 27 ++++++++++++- src/backends/postgresql/CMakeLists.txt | 2 +- .../postgresql/backend_postgresql.cpp | 17 ++++++++ .../postgresql/backend_postgresql.hpp | 5 +++ src/backends/postgresql/locate.cpp | 39 +++++++------------ src/backends/postgresql/locate.hpp | 33 ++++------------ src/locate/main.cpp | 11 ++++-- 8 files changed, 80 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 575583d..c4b7e0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,7 +135,7 @@ add_subdirectory(src/main) add_subdirectory(src/scan) add_subdirectory(src/delete) #add_subdirectory(src/query) -#add_subdirectory(src/locate) +add_subdirectory(src/locate) #add_subdirectory(src/navigate) add_subdirectory(src/tag) diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index c2856de..c3e1527 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -19,7 +19,6 @@ #define id7506CA9825454B80856154ACFE8A9DE2 #include "backends/backend_loader.hpp" -#include "dindexer-machinery/recorddata.hpp" #include #include #include @@ -27,15 +26,36 @@ #include #include +namespace mchlib { + struct TigerHash; + struct FileRecordData; + struct SetRecordData; + struct SetRecordDataFull; +} //namespace mchlib + namespace dindb { using GroupIDType = uint32_t; using FileIDType = uint64_t; using IDDescMap = std::map; using ConfirmDeleCallback = std::function; + using TagList = std::vector; constexpr const GroupIDType InvalidGroupID = 0; constexpr const FileIDType InvalidFileID = 0; + struct LocatedItem { + std::string path; + FileIDType id; + GroupIDType group_id; + }; + + struct LocatedSet { + std::string desc; + GroupIDType id; + uint32_t files_count; + uint32_t dir_count; + }; + class Backend { public: Backend ( void ) = default; @@ -52,6 +72,11 @@ namespace dindb { virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ) = 0; virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ) = 0; + + virtual std::vector locate_in_db ( const std::string& parSearch, const TagList& parTags ) = 0; + virtual std::vector locate_in_db ( const mchlib::TigerHash& parSearch, const TagList& parTags ) = 0; + virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ) = 0; + virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ) = 0; }; } //namespace dindb diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index bb3041c..c605c77 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -3,7 +3,7 @@ project(${bare_name}-backend-postgresql CXX) add_library(${PROJECT_NAME} SHARED tag.cpp delete.cpp - #locate.cpp + locate.cpp scan.cpp #dbsource.cpp backend_postgresql.cpp diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index fbabb9c..f530d01 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -20,6 +20,7 @@ #include "tag.hpp" #include "delete.hpp" #include "scan.hpp" +#include "locate.hpp" #include "pq/connection.hpp" #include #include @@ -113,6 +114,22 @@ namespace dindb { bool BackendPostgreSql::search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { return dindb::read_from_db(parItem, parSet, *m_conn, parHash); } + + std::vector BackendPostgreSql::locate_in_db (const std::string& parSearch, const TagList& parTags) { + return dindb::locate_in_db(*m_conn, parSearch, parTags); + } + + std::vector BackendPostgreSql::locate_in_db (const mchlib::TigerHash& parSearch, const TagList& parTags) { + return dindb::locate_in_db(*m_conn, parSearch, parTags); + } + + std::vector BackendPostgreSql::locate_sets_in_db (const std::string& parSearch, bool parCaseInsensitive) { + return dindb::locate_sets_in_db(*m_conn, parSearch, parCaseInsensitive); + } + + std::vector BackendPostgreSql::locate_sets_in_db (const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { + return dindb::locate_sets_in_db(*m_conn, parSearch, parSets, parCaseInsensitive); + } } //namespace dindb extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index 1160ef1..ab6bb8a 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -46,6 +46,11 @@ namespace dindb { virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ); + virtual std::vector locate_in_db ( const std::string& parSearch, const TagList& parTags ); + virtual std::vector locate_in_db ( const mchlib::TigerHash& parSearch, const TagList& parTags ); + virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ); + virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); + private: std::unique_ptr m_conn; }; diff --git a/src/backends/postgresql/locate.cpp b/src/backends/postgresql/locate.cpp index 9018b08..82d26ed 100644 --- a/src/backends/postgresql/locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -15,28 +15,19 @@ * along with "dindexer". If not, see . */ -#include "db/locate.hpp" -#include "db/settings.hpp" +#include "locate.hpp" +#include "dindexer-machinery/recorddata.hpp" #include "pq/connection.hpp" #include "dindexer-machinery/tiger.hpp" #include #include #include +#include namespace dindb { namespace { const int g_max_results = 200; - pq::Connection make_pq_conn ( const Settings& parDB, bool parOpen=true ); - - pq::Connection make_pq_conn (const Settings& parDB, bool parOpen) { - auto conn = pq::Connection(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port); - if (parOpen) { - conn.connect(); - } - return conn; - } - std::vector sets_result_to_vec (pq::ResultSet&& parResult) { using boost::lexical_cast; @@ -95,21 +86,21 @@ namespace dindb { } } //unnamed namespace - std::vector locate_in_db (const Settings& parDB, const std::string& parSearch, const TagList& parTags) { - auto conn = make_pq_conn(parDB); + std::vector locate_in_db (pq::Connection& parDB, const std::string& parSearch, const TagList& parTags) { + assert(parDB.is_connected()); const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"path\" ~ $1"; - return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, parSearch); + return locate_in_db(parDB, base_query, sizeof(base_query) - 1, "$2", parTags, parSearch); } - std::vector locate_in_db (const Settings& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags) { - auto conn = make_pq_conn(parDB); + std::vector locate_in_db (pq::Connection& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags) { + assert(parDB.is_connected()); const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"hash\"=$1"; - return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, mchlib::tiger_to_string(parSearch, true)); + return locate_in_db(parDB, base_query, sizeof(base_query) - 1, "$2", parTags, mchlib::tiger_to_string(parSearch, true)); } - std::vector locate_sets_in_db (const Settings& parDB, const std::string& parSearch, bool parCaseInsensitive) { - auto conn = make_pq_conn(parDB); + std::vector locate_sets_in_db (pq::Connection& parDB, const std::string& parSearch, bool parCaseInsensitive) { + assert(parDB.is_connected()); const std::string query = std::string("SELECT \"id\", \"desc\", " "(SELECT COUNT(*) FROM \"files\" WHERE \"group_id\"=\"sets\".\"id\" AND NOT \"is_directory\") as \"file_count\", " @@ -117,16 +108,16 @@ namespace dindb { "FROM \"sets\" WHERE str_match_partial(\"desc\", $1, $2) LIMIT " ) + std::to_string(g_max_results) + ";"; - auto result = conn.query(query, parSearch, parCaseInsensitive); + auto result = parDB.query(query, parSearch, parCaseInsensitive); return sets_result_to_vec(std::move(result)); } - std::vector locate_sets_in_db (const Settings& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { + std::vector locate_sets_in_db (pq::Connection& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { if (parSets.empty()) { return locate_sets_in_db(parDB, parSearch, parCaseInsensitive); } - auto conn = make_pq_conn(parDB); + assert(parDB.is_connected()); const std::string query = std::string("SELECT \"id\", \"desc\", " "(SELECT COUNT(*) FROM \"files\" WHERE \"group_id\"=\"sets\".\"id\" AND NOT \"is_directory\") as \"file_count\", " @@ -134,7 +125,7 @@ namespace dindb { "FROM \"sets\" WHERE \"id\" = ANY($1) AND str_match_partial(\"desc\", $3, $2) LIMIT " ) + std::to_string(g_max_results) + ";"; - auto result = conn.query(query, parSearch, parCaseInsensitive, parSets); + auto result = parDB.query(query, parSearch, parCaseInsensitive, parSets); return sets_result_to_vec(std::move(result)); } } //namespace dindb diff --git a/src/backends/postgresql/locate.hpp b/src/backends/postgresql/locate.hpp index 51a595d..fd58ed1 100644 --- a/src/backends/postgresql/locate.hpp +++ b/src/backends/postgresql/locate.hpp @@ -21,34 +21,17 @@ #include #include #include -#include +#include "backends/db_backend.hpp" -namespace mchlib { - struct TigerHash; -} //namespace mchlib +namespace pq { + class Connection; +} //namespace pq namespace dindb { - struct Settings; - - struct LocatedItem { - std::string path; - uint64_t id; - uint32_t group_id; - }; - - struct LocatedSet { - std::string desc; - uint32_t id; - uint32_t files_count; - uint32_t dir_count; - }; - - using TagList = std::vector; - - std::vector locate_in_db ( const Settings& parDB, const std::string& parSearch, const TagList& parTags ); - std::vector locate_in_db ( const Settings& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags ); - std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, bool parCaseInsensitive ); - std::vector locate_sets_in_db ( const Settings& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); + std::vector locate_in_db ( pq::Connection& parDB, const std::string& parSearch, const TagList& parTags ); + std::vector locate_in_db ( pq::Connection& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags ); + std::vector locate_sets_in_db ( pq::Connection& parDB, const std::string& parSearch, bool parCaseInsensitive ); + std::vector locate_sets_in_db ( pq::Connection& parDB, const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); } //namespace dindb #endif diff --git a/src/locate/main.cpp b/src/locate/main.cpp index f8474e8..34edb87 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -16,7 +16,6 @@ */ #include "commandline.hpp" -#include "db/locate.hpp" #include "dindexer-common/settings.hpp" #include "dindexer-common/split_tags.hpp" #include "dindexerConfig.h" @@ -79,9 +78,13 @@ int main (int parArgc, char* parArgv[]) { return 1; } } + //TODO: throw if plugin loading failed + assert(settings.backend_plugin.name() == settings.backend_name); + assert(settings.backend_plugin.is_loaded()); + auto& db = settings.backend_plugin.backend(); if (vm.count("set")) { - const auto results = dindb::locate_sets_in_db(settings.db, vm["substring"].as(), not not vm.count("case-insensitive")); + const auto results = db.locate_sets_in_db(vm["substring"].as(), not not vm.count("case-insensitive")); std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } else { @@ -90,11 +93,11 @@ int main (int parArgc, char* parArgv[]) { if (vm.count("byhash")) { const auto hash = din::hash(vm["substring"].as()); - results = dindb::locate_in_db(settings.db, hash, tags); + results = db.locate_in_db(hash, tags); } else { const auto search_regex = g2r::convert(vm["substring"].as(), not vm.count("case-insensitive")); - results = dindb::locate_in_db(settings.db, search_regex, tags); + results = db.locate_in_db(search_regex, tags); } std::copy(results.begin(), results.end(), std::ostream_iterator(std::cout, "\n")); } From dfe36552967229d83040cdfbe37a9bc59a649518 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 09:35:33 +0200 Subject: [PATCH 021/170] Re-enable navigate in the postgre plugin. --- CMakeLists.txt | 2 +- include/backends/db_backend.hpp | 9 + src/backends/postgresql/CMakeLists.txt | 2 +- .../postgresql/backend_postgresql.cpp | 25 +++ .../postgresql/backend_postgresql.hpp | 8 + src/backends/postgresql/dbsource.cpp | 183 ------------------ src/backends/postgresql/navigate.cpp | 152 +++++++++++++++ .../postgresql/{dbsource.hpp => navigate.hpp} | 63 +++--- src/navigate/listdircontent.cpp | 12 +- src/navigate/listdircontent.hpp | 6 +- src/navigate/main.cpp | 14 +- 11 files changed, 238 insertions(+), 238 deletions(-) delete mode 100644 src/backends/postgresql/dbsource.cpp create mode 100644 src/backends/postgresql/navigate.cpp rename src/backends/postgresql/{dbsource.hpp => navigate.hpp} (68%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4b7e0f..b0d7662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,7 +136,7 @@ add_subdirectory(src/scan) add_subdirectory(src/delete) #add_subdirectory(src/query) add_subdirectory(src/locate) -#add_subdirectory(src/navigate) +add_subdirectory(src/navigate) add_subdirectory(src/tag) #Tests diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index c3e1527..07aec9c 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -19,6 +19,7 @@ #define id7506CA9825454B80856154ACFE8A9DE2 #include "backends/backend_loader.hpp" +#include "helpers/MaxSizedArray.hpp" #include #include #include @@ -61,6 +62,9 @@ namespace dindb { Backend ( void ) = default; virtual ~Backend ( void ) noexcept = default; + virtual void connect ( void ) = 0; + virtual void disconnect ( void ) = 0; + virtual void tag_files ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) = 0; virtual void tag_files ( const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet ) = 0; virtual void delete_tags ( const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet ) = 0; @@ -77,6 +81,11 @@ namespace dindb { virtual std::vector locate_in_db ( const mchlib::TigerHash& parSearch, const TagList& parTags ) = 0; virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ) = 0; virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ) = 0; + + virtual std::vector find_all_sets ( void ) = 0; + virtual std::vector> find_set_details ( const std::vector& parSets ) = 0; + virtual std::vector> find_file_details ( GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ) = 0; + virtual std::vector find_paths_starting_by ( GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ) = 0; }; } //namespace dindb diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index c605c77..89b8680 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(${PROJECT_NAME} SHARED delete.cpp locate.cpp scan.cpp - #dbsource.cpp + navigate.cpp backend_postgresql.cpp ) diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index f530d01..95e6332 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -21,6 +21,7 @@ #include "delete.hpp" #include "scan.hpp" #include "locate.hpp" +#include "navigate.hpp" #include "pq/connection.hpp" #include #include @@ -79,6 +80,14 @@ namespace dindb { m_conn->disconnect(); } + void BackendPostgreSql::connect() { + m_conn->connect(); + } + + void BackendPostgreSql::disconnect() { + m_conn->disconnect(); + } + void BackendPostgreSql::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { dindb::tag_files(*m_conn, parFiles, parTags, parSet); } @@ -130,6 +139,22 @@ namespace dindb { std::vector BackendPostgreSql::locate_sets_in_db (const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive) { return dindb::locate_sets_in_db(*m_conn, parSearch, parSets, parCaseInsensitive); } + + std::vector BackendPostgreSql::find_all_sets() { + return dindb::find_all_sets(*m_conn); + } + + std::vector> BackendPostgreSql::find_set_details (const std::vector& parSets) { + return dindb::find_set_details(*m_conn, parSets); + } + + std::vector> BackendPostgreSql::find_file_details (GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir) { + return dindb::find_file_details(*m_conn, parSetID, parLevel, parDir); + } + + std::vector BackendPostgreSql::find_paths_starting_by (GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath) { + return dindb::find_paths_starting_by(*m_conn, parGroupID, parLevel, parPath); + } } //namespace dindb extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index ab6bb8a..7a5468b 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -34,6 +34,9 @@ namespace dindb { BackendPostgreSql ( std::string&& parUser, std::string&& parPass, std::string&& parDB, std::string&& parAddr, uint16_t parPort ); virtual ~BackendPostgreSql ( void ) noexcept; + virtual void connect ( void ); + virtual void disconnect ( void ); + 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; @@ -51,6 +54,11 @@ namespace dindb { virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ); virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); + virtual std::vector find_all_sets ( void ); + virtual std::vector> find_set_details ( const std::vector& parSets ); + virtual std::vector> find_file_details ( GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ); + virtual std::vector find_paths_starting_by ( GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ); + private: std::unique_ptr m_conn; }; diff --git a/src/backends/postgresql/dbsource.cpp b/src/backends/postgresql/dbsource.cpp deleted file mode 100644 index 4d518c9..0000000 --- a/src/backends/postgresql/dbsource.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* 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 "db/dbsource.hpp" -#include "db/settings.hpp" -#include "pq/connection.hpp" -#include "helpers/infix_iterator.hpp" -#include -#include -#include -#include -#include - -namespace dindb { - namespace { - const uint32_t g_files_query_limit = 500; - - std::ostream& operator<< (std::ostream& parOut, const std::vector& parCols) { - parOut << '"'; - boost::copy(parCols, infix_ostream_iterator(parOut, "\", \"")); - parOut << '"'; - return parOut; - } - } //unnamed namespace - - const DBSource::SetDetailsMap DBSource::m_set_details_map { - {SetDetail_Desc, "desc"}, - {SetDetail_Type, "type"}, - {SetDetail_CreeationDate, "creation"}, - {SetDetail_AppName, "app_name"}, - {SetDetail_ID, "id"} - }; - const DBSource::FileDetailsMap DBSource::m_file_details_map { - {FileDetail_ID, "id"}, - {FileDetail_Path, "path"}, - {FileDetail_Level, "level"}, - {FileDetail_GroupID, "group_id"}, - {FileDetail_IsDir, "is_directory"}, - {FileDetail_IsSymLink, "is_symlink"}, - {FileDetail_Size, "size"}, - {FileDetail_Hash, "hash"}, - {FileDetail_IsHashValid, "is_hash_valid"}, - {FileDetail_ATime, "access_time"}, - {FileDetail_MTime, "modify_time"}, - {FileDetail_Unreadable, "unreadable"}, - {FileDetail_MimeType, "mimetype"}, - {FileDetail_Charset, "charset"} - }; - - struct DBSource::LocalData { - explicit LocalData ( const Settings& parDBSettings ) : - conn( - std::string(parDBSettings.username), - std::string(parDBSettings.password), - std::string(parDBSettings.dbname), - std::string(parDBSettings.address), - parDBSettings.port - ) - { - } - - pq::Connection conn; - }; - - DBSource::DBSource (const Settings& parDBSettings) : - m_local_data(new LocalData(parDBSettings)) - { - assert(not m_local_data->conn.is_connected()); - } - - DBSource::~DBSource() noexcept { - } - - void DBSource::disconnect() { - if (m_local_data->conn.is_connected()) { - m_local_data->conn.disconnect(); - } - } - - pq::Connection& DBSource::get_conn() { - if (not m_local_data->conn.is_connected()) { - m_local_data->conn.connect(); - } - return m_local_data->conn; - } - - std::vector DBSource::sets() { - using boost::lexical_cast; - - auto& conn = get_conn(); - const std::string query = "SELECT \"id\" FROM \"sets\";"; - auto res = conn.query(query); - std::vector retval; - - retval.reserve(res.size()); - for (const auto& row : res) { - retval.push_back(lexical_cast(row[0])); - } - return retval; - } - - void DBSource::query_no_conditions (const ColumnList& parCols, boost::string_ref parTable, const std::vector& parIDs, std::function parCallback) { - std::ostringstream oss; - oss << "SELECT " << parCols << ' ' << - "FROM \"" << parTable << "\" " << - "WHERE \"id\"=ANY($1) " << - "ORDER BY \"desc\" ASC " << - "LIMIT " << g_files_query_limit << ';'; - - auto& conn = get_conn(); - auto result = conn.query(oss.str(), parIDs); - for (auto row : result) { - for (auto val : row) { - parCallback(std::move(val)); - } - } - } - - void DBSource::query_files_in_dir (const ColumnList& parCols, boost::string_ref parDir, uint16_t parLevel, uint32_t parGroupID, QueryCallback parCallback) { - std::ostringstream oss; - oss << "SELECT " << parCols << ' ' << - "FROM \"files\" WHERE " << - "\"level\"=$1 " << - "AND \"group_id\"=$2 " << - "AND str_begins_with(\"path\", COALESCE($3, '')) " << - "ORDER BY \"is_directory\" DESC, \"path\" ASC " << - "LIMIT " << g_files_query_limit << ';'; - - auto& conn = get_conn(); - auto result = conn.query( - oss.str(), - parLevel, - parGroupID, - parDir - ); - for (auto row : result) { - for (auto val : row) { - parCallback(std::move(val)); - } - } - } - - std::vector DBSource::paths_starting_by (uint32_t parGroupID, uint16_t parLevel, boost::string_ref parPath) { - std::ostringstream oss; - oss << "SELECT \"path\" ||\n" << - "(SELECT CASE \"is_directory\"\n" << - "WHEN TRUE THEN '/'\n" << - "ELSE ''\n" << - "END) as path FROM \"files\" WHERE \"group_id\"=$1 AND " << - "\"level\"=$2 AND str_begins_with(\"path\", COALESCE($3, '')) " << - "ORDER BY \"is_directory\" DESC, \"path\" ASC LIMIT " << - g_files_query_limit << ';'; - - auto& conn = get_conn(); - auto result = conn.query( - oss.str(), - parGroupID, - parLevel, - parPath - ); - std::vector retval; - retval.reserve(retval.size()); - for (auto row : result) { - assert(not row.empty()); - retval.push_back(row[0]); - } - return retval; - } -} //namespace dindb diff --git a/src/backends/postgresql/navigate.cpp b/src/backends/postgresql/navigate.cpp new file mode 100644 index 0000000..9b23e42 --- /dev/null +++ b/src/backends/postgresql/navigate.cpp @@ -0,0 +1,152 @@ +/* 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 "navigate.hpp" +#include "pq/connection.hpp" +#include "helpers/infix_iterator.hpp" +#include +#include +#include +#include +#include +#include + +namespace dindb { + namespace { + const uint32_t g_files_query_limit = 500; + + std::ostream& operator<< (std::ostream& parOut, const std::vector& parCols) { + parOut << '"'; + boost::copy(parCols, infix_ostream_iterator(parOut, "\", \"")); + parOut << '"'; + return parOut; + } + } //unnamed namespace + + namespace implem { + const SetDetailsMap g_set_details_map { + {SetDetail_Desc, "desc"}, + {SetDetail_Type, "type"}, + {SetDetail_CreeationDate, "creation"}, + {SetDetail_AppName, "app_name"}, + {SetDetail_ID, "id"} + }; + const FileDetailsMap g_file_details_map { + {FileDetail_ID, "id"}, + {FileDetail_Path, "path"}, + {FileDetail_Level, "level"}, + {FileDetail_GroupID, "group_id"}, + {FileDetail_IsDir, "is_directory"}, + {FileDetail_IsSymLink, "is_symlink"}, + {FileDetail_Size, "size"}, + {FileDetail_Hash, "hash"}, + {FileDetail_IsHashValid, "is_hash_valid"}, + {FileDetail_ATime, "access_time"}, + {FileDetail_MTime, "modify_time"}, + {FileDetail_Unreadable, "unreadable"}, + {FileDetail_MimeType, "mimetype"}, + {FileDetail_Charset, "charset"} + }; + + void query_no_conditions (pq::Connection& parDB, const ColumnList& parCols, boost::string_ref parTable, const std::vector& parIDs, std::function parCallback) { + assert(parDB.is_connected()); + + std::ostringstream oss; + oss << "SELECT " << parCols << ' ' << + "FROM \"" << parTable << "\" " << + "WHERE \"id\"=ANY($1) " << + "ORDER BY \"desc\" ASC " << + "LIMIT " << g_files_query_limit << ';'; + + auto result = parDB.query(oss.str(), parIDs); + for (auto row : result) { + for (auto val : row) { + parCallback(std::move(val)); + } + } + } + + void query_files_in_dir (pq::Connection& parDB, const ColumnList& parCols, boost::string_ref parDir, uint16_t parLevel, GroupIDType parGroupID, QueryCallback parCallback) { + assert(parDB.is_connected()); + + std::ostringstream oss; + oss << "SELECT " << parCols << ' ' << + "FROM \"files\" WHERE " << + "\"level\"=$1 " << + "AND \"group_id\"=$2 " << + "AND str_begins_with(\"path\", COALESCE($3, '')) " << + "ORDER BY \"is_directory\" DESC, \"path\" ASC " << + "LIMIT " << g_files_query_limit << ';'; + + auto result = parDB.query( + oss.str(), + parLevel, + parGroupID, + parDir + ); + for (auto row : result) { + for (auto val : row) { + parCallback(std::move(val)); + } + } + } + } //namespace implem + + std::vector find_all_sets (pq::Connection& parDB) { + using boost::lexical_cast; + + assert(parDB.is_connected()); + + const std::string query = "SELECT \"id\" FROM \"sets\";"; + auto res = parDB.query(query); + std::vector retval; + + retval.reserve(res.size()); + for (const auto& row : res) { + retval.push_back(lexical_cast(row[0])); + } + return retval; + } + + std::vector find_paths_starting_by (pq::Connection& parDB, GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath) { + assert(parDB.is_connected()); + + std::ostringstream oss; + oss << "SELECT \"path\" ||\n" << + "(SELECT CASE \"is_directory\"\n" << + "WHEN TRUE THEN '/'\n" << + "ELSE ''\n" << + "END) as path FROM \"files\" WHERE \"group_id\"=$1 AND " << + "\"level\"=$2 AND str_begins_with(\"path\", COALESCE($3, '')) " << + "ORDER BY \"is_directory\" DESC, \"path\" ASC LIMIT " << + g_files_query_limit << ';'; + + auto result = parDB.query( + oss.str(), + parGroupID, + parLevel, + parPath + ); + std::vector retval; + retval.reserve(retval.size()); + for (auto row : result) { + assert(not row.empty()); + retval.push_back(row[0]); + } + return retval; + } +} //namespace dindb diff --git a/src/backends/postgresql/dbsource.hpp b/src/backends/postgresql/navigate.hpp similarity index 68% rename from src/backends/postgresql/dbsource.hpp rename to src/backends/postgresql/navigate.hpp index d0e5810..d52ecd7 100644 --- a/src/backends/postgresql/dbsource.hpp +++ b/src/backends/postgresql/navigate.hpp @@ -21,6 +21,7 @@ #include "dindexer-machinery/recorddata.hpp" #include "helpers/flatinsertin2dlist.hpp" #include "helpers/MaxSizedArray.hpp" +#include "backends/db_backend.hpp" #include #include #include @@ -38,8 +39,6 @@ namespace pq { namespace dindb { using dinhelp::MaxSizedArray; - struct Settings; - enum SetDetails { SetDetail_Desc = 0x01, SetDetail_Type = 0x02, @@ -65,40 +64,25 @@ namespace dindb { FileDetail_Charset = 0x2000 }; - class DBSource { - public: - explicit DBSource ( const Settings& parDBSettings ); - ~DBSource ( void ) noexcept; + std::vector find_all_sets ( pq::Connection& parDB ); - void disconnect ( void ); - std::vector sets ( void ); + template + auto find_set_details ( pq::Connection& parDB, const std::vector& parIDs ) -> std::vector>; - template - auto set_details ( const std::vector& parIDs ) -> std::vector>; + template + auto find_file_details ( pq::Connection& parDB, GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ) -> std::vector>; - template - auto file_details ( uint32_t parSetID, uint16_t parLevel, boost::string_ref parDir ) -> std::vector>; - - std::vector paths_starting_by ( uint32_t parGroupID, uint16_t parLevel, boost::string_ref parPath ); - - private: - struct LocalData; - typedef std::map SetDetailsMap; - typedef std::map FileDetailsMap; - typedef std::vector ColumnList; - typedef std::function QueryCallback; - - pq::Connection& get_conn ( void ); - void query_no_conditions ( const ColumnList& parCols, boost::string_ref parTable, const std::vector& parIDs, QueryCallback parCallback ); - void query_files_in_dir ( const ColumnList& parCols, boost::string_ref parDir, uint16_t parLevel, uint32_t parGroupID, QueryCallback parCallback ); - - static const SetDetailsMap m_set_details_map; - static const FileDetailsMap m_file_details_map; - - std::unique_ptr m_local_data; - }; + std::vector find_paths_starting_by ( pq::Connection& parDB, GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ); namespace implem { + typedef std::vector ColumnList; + typedef std::function QueryCallback; + typedef std::map SetDetailsMap; + typedef std::map FileDetailsMap; + + extern const SetDetailsMap g_set_details_map; + extern const FileDetailsMap g_file_details_map; + template inline std::vector make_columns_vec (const std::map& parDic) { @@ -115,35 +99,40 @@ namespace dindb { } return columns; } + + void query_no_conditions ( pq::Connection& parDB, const ColumnList& parCols, boost::string_ref parTable, const std::vector& parIDs, QueryCallback parCallback ); + void query_files_in_dir ( pq::Connection& parDB, const ColumnList& parCols, boost::string_ref parDir, uint16_t parLevel, GroupIDType parGroupID, QueryCallback parCallback ); } //namespace implem template - auto DBSource::set_details (const std::vector& parIDs) -> std::vector> { + inline + auto find_set_details (pq::Connection& parDB, const std::vector& parIDs) -> std::vector> { using dinhelp::FlatInsertIn2DList; typedef std::vector> ReturnType; typedef void(FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); - const auto columns = implem::make_columns_vec(m_set_details_map); + const auto columns = implem::make_columns_vec(implem::g_set_details_map); ReturnType list; FlatInsertIn2DList flat_list(&list, sizeof...(D)); FlatPushBackFunc pback_func = &FlatInsertIn2DList::push_back; - this->query_no_conditions(columns, "sets", parIDs, std::bind(pback_func, &flat_list, std::placeholders::_1)); + implem::query_no_conditions(parDB, columns, "sets", parIDs, std::bind(pback_func, &flat_list, std::placeholders::_1)); return list; } template - auto DBSource::file_details (uint32_t parSetID, uint16_t parLevel, boost::string_ref parDir) -> std::vector> { + inline + auto find_file_details (pq::Connection& parDB, GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir) -> std::vector> { using dinhelp::FlatInsertIn2DList; typedef std::vector> ReturnType; typedef void(FlatInsertIn2DList::*FlatPushBackFunc)(std::string&&); - const auto columns = implem::make_columns_vec(m_file_details_map); + const auto columns = implem::make_columns_vec(implem::g_file_details_map); ReturnType list; FlatInsertIn2DList flat_list(&list, sizeof...(D)); FlatPushBackFunc pback_func = &FlatInsertIn2DList::push_back; - this->query_files_in_dir(columns, parDir, parLevel, parSetID, std::bind(pback_func, &flat_list, std::placeholders::_1)); + implem::query_files_in_dir(parDB, columns, parDir, parLevel, parSetID, std::bind(pback_func, &flat_list, std::placeholders::_1)); return list; } } //namespace dindb diff --git a/src/navigate/listdircontent.cpp b/src/navigate/listdircontent.cpp index bfda3fe..d7be0ac 100644 --- a/src/navigate/listdircontent.cpp +++ b/src/navigate/listdircontent.cpp @@ -17,7 +17,7 @@ #include "listdircontent.hpp" #include "entrypath.hpp" -#include "db/dbsource.hpp" +#include "backends/db_backend.hpp" #include "helpers/infix_iterator.hpp" #include #include @@ -68,7 +68,7 @@ namespace din { } } //unnamed namespace - ListDirContent::ListDirContent (dindb::DBSource* parDB) : + ListDirContent::ListDirContent (dindb::Backend* parDB) : m_cache(g_max_cached_lists), m_db(parDB) { @@ -85,14 +85,14 @@ namespace din { //Requested item is not cached, so we need to query the db now if (parDir.points_to_group()) { - auto sets_ids = m_db->sets(); - auto sets_info = m_db->set_details(sets_ids); + auto sets_ids = m_db->find_all_sets(); + auto sets_info = m_db->find_set_details(sets_ids); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(sets_info))); } else { auto path_prefix = parDir.file_path(); const auto set_id = parDir.group_id(); - auto files_info = m_db->file_details(set_id, parDir.level() + 1, path_prefix); + auto files_info = m_db->find_file_details(set_id, parDir.level() + 1, path_prefix); m_cache.push_back(std::make_pair(curr_path, db_result_to_vec(files_info))); } return last_cached_item(curr_path); @@ -115,7 +115,7 @@ namespace din { else { const auto set_id = parDir.group_id(); const auto path_prefix = parDir.file_path(); - auto file_list = m_db->paths_starting_by(set_id, parDir.level(), path_prefix); + auto file_list = m_db->find_paths_starting_by(set_id, parDir.level(), path_prefix); for (auto& file_item : file_list) { file_item = EntryPath(file_item)[return_level]; } diff --git a/src/navigate/listdircontent.hpp b/src/navigate/listdircontent.hpp index a3dfe19..ad20f27 100644 --- a/src/navigate/listdircontent.hpp +++ b/src/navigate/listdircontent.hpp @@ -24,7 +24,7 @@ #include namespace dindb { - class DBSource; + class Backend; } //namespace dindb namespace din { @@ -34,7 +34,7 @@ namespace din { using ListType = std::vector; using CachedItemType = std::pair; public: - explicit ListDirContent ( dindb::DBSource* parDB ); + explicit ListDirContent ( dindb::Backend* parDB ); ~ListDirContent ( void ) noexcept = default; const ListType& ls ( const EntryPath& parDir ) const; @@ -44,7 +44,7 @@ namespace din { const ListType& last_cached_item ( const std::string& parCurrPath ) const; mutable boost::circular_buffer m_cache; - dindb::DBSource* m_db; + dindb::Backend* m_db; }; } //namespace din diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp index db02fed..fdcb835 100644 --- a/src/navigate/main.cpp +++ b/src/navigate/main.cpp @@ -19,7 +19,6 @@ #include "commandprocessor.hpp" #include "dindexer-common/settings.hpp" #include "entrypath.hpp" -#include "db/dbsource.hpp" #include "dindexerConfig.h" #include "linereader.hpp" #include "listdircontent.hpp" @@ -31,7 +30,7 @@ #include namespace { - void do_navigation ( dindb::DBSource& parDB ); + void do_navigation ( dindb::Backend& parDB ); bool on_exit ( void ); void on_pwd ( const din::EntryPath& parDirMan ); @@ -60,10 +59,11 @@ int main (int parArgc, char* parArgv[]) { return 1; } } + //TODO: throw if plugin loading failed + assert(settings.backend_plugin.name() == settings.backend_name); + assert(settings.backend_plugin.is_loaded()); - dindb::DBSource db_source(settings.db); - - do_navigation(db_source); + do_navigation(settings.backend_plugin.backend()); return 0; } @@ -81,7 +81,7 @@ namespace { boost::copy(ls_result, std::ostream_iterator(std::cout, "\n")); } - void do_navigation (dindb::DBSource& parDB) { + void do_navigation (dindb::Backend& parDB) { const std::string prompt; din::ListDirContent ls(&parDB); din::LineReader lines(&ls); @@ -92,7 +92,7 @@ namespace { din::EntryPath dir_man; proc.add_command("exit", &on_exit, 0); proc.add_command("cd", std::function(std::bind(&din::EntryPath::push_piece, &dir_man, std::placeholders::_1)), 1); - proc.add_command("disconnect", std::function(std::bind(&dindb::DBSource::disconnect, &parDB)), 0); + proc.add_command("disconnect", std::function(std::bind(&dindb::Backend::disconnect, std::ref(parDB))), 0); proc.add_command("pwd", std::function(std::bind(&on_pwd, std::ref(dir_man))), 0); proc.add_command("ls", std::function(std::bind(on_ls, std::ref(ls), std::ref(dir_man))), 0); do { From 0cb91fb9cae0aa7996feb3307781c05c099b38f5 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 09:42:32 +0200 Subject: [PATCH 022/170] Put LIMIT number into a common header. --- src/backends/postgresql/locate.cpp | 3 ++- src/backends/postgresql/navigate.cpp | 3 ++- src/backends/postgresql/query_count_limit.hpp | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/backends/postgresql/query_count_limit.hpp diff --git a/src/backends/postgresql/locate.cpp b/src/backends/postgresql/locate.cpp index 82d26ed..259f5c7 100644 --- a/src/backends/postgresql/locate.cpp +++ b/src/backends/postgresql/locate.cpp @@ -18,6 +18,7 @@ #include "locate.hpp" #include "dindexer-machinery/recorddata.hpp" #include "pq/connection.hpp" +#include "query_count_limit.hpp" #include "dindexer-machinery/tiger.hpp" #include #include @@ -26,7 +27,7 @@ namespace dindb { namespace { - const int g_max_results = 200; + const int g_max_results = g_query_count_limit; std::vector sets_result_to_vec (pq::ResultSet&& parResult) { using boost::lexical_cast; diff --git a/src/backends/postgresql/navigate.cpp b/src/backends/postgresql/navigate.cpp index 9b23e42..43af1f2 100644 --- a/src/backends/postgresql/navigate.cpp +++ b/src/backends/postgresql/navigate.cpp @@ -18,6 +18,7 @@ #include "navigate.hpp" #include "pq/connection.hpp" #include "helpers/infix_iterator.hpp" +#include "query_count_limit.hpp" #include #include #include @@ -27,7 +28,7 @@ namespace dindb { namespace { - const uint32_t g_files_query_limit = 500; + const uint32_t g_files_query_limit = g_query_count_limit; std::ostream& operator<< (std::ostream& parOut, const std::vector& parCols) { parOut << '"'; diff --git a/src/backends/postgresql/query_count_limit.hpp b/src/backends/postgresql/query_count_limit.hpp new file mode 100644 index 0000000..193fa91 --- /dev/null +++ b/src/backends/postgresql/query_count_limit.hpp @@ -0,0 +1,25 @@ +/* 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 id367C9335A3444BC0846EF4E2A27AB9A9 +#define id367C9335A3444BC0846EF4E2A27AB9A9 + +namespace dindb { + constexpr const uint32_t g_query_count_limit = 500; +}; + +#endif From e2275ce5dbc3d1558185fc6b3f2d6bde7a01d49b Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 10:01:19 +0200 Subject: [PATCH 023/170] Add a backend interface version number for eventual future changes. Note that the interface is still a work in progress and might change while still keeping the same interface version. This is going to be true until the first stable release of this project (non beta). --- include/backends/backend_loader.hpp | 3 +++ include/backends/backend_version.hpp | 25 +++++++++++++++++++ include/backends/exposed_functions.hpp | 1 + src/backends/backend_loader.cpp | 23 ++++++++++++++++- .../postgresql/backend_postgresql.cpp | 5 ++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 include/backends/backend_version.hpp diff --git a/include/backends/backend_loader.hpp b/include/backends/backend_loader.hpp index 70bb592..7795d0c 100644 --- a/include/backends/backend_loader.hpp +++ b/include/backends/backend_loader.hpp @@ -42,6 +42,8 @@ namespace dindb { Backend& backend ( void ); const Backend& backend ( void ) const; bool is_loaded ( void ) const; + int backend_interface_version ( void ) const; + int max_supported_interface_version ( void ) const; BackendPlugin& operator= ( BackendPlugin&& ) = default; @@ -51,6 +53,7 @@ namespace dindb { SoHandle m_lib; BackendPtr m_backend; boost::string_ref m_name; + int m_iface_ver; }; std::string backend_name ( const std::string& parSOPath ); diff --git a/include/backends/backend_version.hpp b/include/backends/backend_version.hpp new file mode 100644 index 0000000..8b31e82 --- /dev/null +++ b/include/backends/backend_version.hpp @@ -0,0 +1,25 @@ +/* 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 idAA27B58429DB41C2AF53204CC5010E94 +#define idAA27B58429DB41C2AF53204CC5010E94 + +namespace dindb { + constexpr const int g_current_iface_version = 1; +} //namespace dindb + +#endif diff --git a/include/backends/exposed_functions.hpp b/include/backends/exposed_functions.hpp index a1b21e9..ef174d3 100644 --- a/include/backends/exposed_functions.hpp +++ b/include/backends/exposed_functions.hpp @@ -29,5 +29,6 @@ namespace dindb { extern "C" dindb::Backend* dindexer_create_backend ( const YAML::Node* parConfig ); extern "C" void dindexer_destroy_backend ( dindb::Backend* parDele ); extern "C" const char* dindexer_backend_name ( void ); +extern "C" int dindexer_backend_iface_version ( void ); #endif diff --git a/src/backends/backend_loader.cpp b/src/backends/backend_loader.cpp index a6eba27..3aa8547 100644 --- a/src/backends/backend_loader.cpp +++ b/src/backends/backend_loader.cpp @@ -20,6 +20,7 @@ #include "backends/backend_loader.hpp" #include "backends/exposed_functions.hpp" +#include "backends/backend_version.hpp" #include #include #include @@ -50,6 +51,13 @@ namespace dindb { void nop_destroy (Backend*) { } + + int backend_iface_version (void* parSOHandle) { + typedef decltype(&dindexer_backend_iface_version) GetVersionFun; + + auto get_version = reinterpret_cast(dlsym(parSOHandle, "dindexer_backend_iface_version")); + return get_version(); + } } //unnamed namespace std::string backend_name (const std::string& parSOPath) { @@ -70,8 +78,13 @@ namespace dindb { BackendPlugin::BackendPlugin (const std::string& parSOPath, const YAML::Node* parConfig) : m_lib(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose), m_backend(load_backend(m_lib.get(), parConfig)), - m_name(backend_name(m_lib.get())) + m_name(backend_name(m_lib.get())), + m_iface_ver(backend_iface_version(m_lib.get())) { + if (g_current_iface_version != m_iface_ver) { + m_backend.reset(); + m_lib.reset(); + } } BackendPlugin::~BackendPlugin() noexcept { @@ -104,4 +117,12 @@ namespace dindb { bool BackendPlugin::is_loaded() const { return static_cast(m_backend); } + + int BackendPlugin::backend_interface_version() const { + return m_iface_ver; + } + + int BackendPlugin::max_supported_interface_version() const { + return g_current_iface_version; + } } //namespace dindb diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index 95e6332..68577ec 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -17,6 +17,7 @@ #include "backend_postgresql.hpp" #include "backends/exposed_functions.hpp" +#include "backends/backend_version.hpp" #include "tag.hpp" #include "delete.hpp" #include "scan.hpp" @@ -179,3 +180,7 @@ extern "C" void dindexer_destroy_backend (dindb::Backend* parDele) { extern "C" const char* dindexer_backend_name() { return "postgresql"; } + +extern "C" int dindexer_backend_iface_version() { + return dindb::g_current_iface_version; +} From 4aceccbf4d5db0bd6d56462e43c31087b858bb6b Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 18:29:37 +0200 Subject: [PATCH 024/170] New Diaspora post --- docs/posts/04_whats_cooking.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/posts/04_whats_cooking.md diff --git a/docs/posts/04_whats_cooking.md b/docs/posts/04_whats_cooking.md new file mode 100644 index 0000000..2a084d8 --- /dev/null +++ b/docs/posts/04_whats_cooking.md @@ -0,0 +1,11 @@ +### What's cooking? ### + +It's been roughly a month since I released version 0.1.5b and most of the activity has been on the [dev branch](https://bitbucket.org/King_DuckZ/dindexer/branch/dev) since then. It's still a bit too early to make a new release, but if you want to get a peek at the new features this is the right moment as commit e2275ce should give you a working version of #dindexer. + +Most notably, you will have a `tag` command, that will allow you to tag files. You should also be able to list files by tag, using the `dindexer locate --tags ` command. + +The less evident change (although that's what took up most of my time) is the separation of the PostgreSQL code from the CL client. You have been asking for Sqlite support, I heard you and I'm getting everything ready so that an Sqlite plugin can be implemented! Currently, PostgreSQL is still the only backend you can choose, so please be patient... or even better, step in and contribute to dindexer! :) + +[bitbucket.org/King_DuckZ/dindexer](https://bitbucket.org/King_DuckZ/dindexer) + +\#dindexer #linux #opensource #cpp #sqlite From 7de71943ad6c5cc9b41aca61bd6b1edfa00d3547 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 18:38:40 +0200 Subject: [PATCH 025/170] Name backend settings section in yml using the backend name itself. --- dindexer.yml | 4 ++-- src/common/settings.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dindexer.yml b/dindexer.yml index d13cd0d..38242d4 100644 --- a/dindexer.yml +++ b/dindexer.yml @@ -1,7 +1,7 @@ %YAML 1.2 --- -db_backend_name: postgresql -db_backend_settings: +backend_name: postgresql +postgresql_settings: username: your_username password: your_password dbname: dindexer diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 811a0f4..fa65122 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -33,13 +33,13 @@ namespace dinlib { try { auto settings = YAML::LoadFile(path); - if (not settings["db_backend_name"]) { + if (not settings["backend_name"]) { return false; } - parOut.backend_name = settings["db_backend_name"].as(); - if (settings["db_backend_settings"]) { - //parOut.db = settings["db_backend_settings"].as(); - auto settings_node = settings["db_backend_settings"]; + parOut.backend_name = settings["backend_name"].as(); + const std::string backend_settings_section = parOut.backend_name + "_settings"; + if (settings[backend_settings_section]) { + auto settings_node = settings[backend_settings_section]; parOut.backend_plugin = dindb::BackendPlugin(find_plugin_by_name(parOut.backend_name), &settings_node); return true; } From 61b0b586cf77a211ffbcb2fe4dd59bb6b0e4f876 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 21:16:19 +0200 Subject: [PATCH 026/170] Clean up code to handle failed attempts at loading backend plugins. --- include/dindexer-common/settings.hpp | 2 +- src/common/settings.cpp | 55 +++++++++++++++++++--------- src/delete/main.cpp | 16 ++++---- src/locate/main.cpp | 16 ++++---- src/navigate/main.cpp | 17 ++++----- src/scan/main.cpp | 15 ++++---- src/tag/main.cpp | 16 ++++---- 7 files changed, 74 insertions(+), 63 deletions(-) diff --git a/include/dindexer-common/settings.hpp b/include/dindexer-common/settings.hpp index 11f295f..d115c9a 100644 --- a/include/dindexer-common/settings.hpp +++ b/include/dindexer-common/settings.hpp @@ -28,7 +28,7 @@ namespace dinlib { dindb::BackendPlugin backend_plugin; }; - bool load_settings ( const std::string& parPath, Settings& parOut, bool parExpand=true ); + void load_settings ( const std::string& parPath, Settings& parOut, bool parExpand=true ); } //namespace dinlib #endif diff --git a/src/common/settings.cpp b/src/common/settings.cpp index fa65122..23eeb7d 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -20,35 +20,32 @@ #include #include #include +#include +#include namespace dinlib { namespace { std::string expand ( const char* parString ); std::string find_plugin_by_name ( const std::string& parName ); + void throw_if_plugin_failed ( const dindb::BackendPlugin& parPlugin, const std::string& parPluginPath, const std::string& parIntendedName ); } //unnamed namespace - bool load_settings (const std::string& parPath, dinlib::Settings& parOut, bool parExpand) { + void load_settings (const std::string& parPath, dinlib::Settings& parOut, bool parExpand) { const std::string path = (parExpand ? expand(parPath.c_str()) : parPath); - try { - auto settings = YAML::LoadFile(path); + auto settings = YAML::LoadFile(path); - if (not settings["backend_name"]) { - return false; - } - parOut.backend_name = settings["backend_name"].as(); - const std::string backend_settings_section = parOut.backend_name + "_settings"; - if (settings[backend_settings_section]) { - auto settings_node = settings[backend_settings_section]; - parOut.backend_plugin = dindb::BackendPlugin(find_plugin_by_name(parOut.backend_name), &settings_node); - return true; - } + if (not settings["backend_name"]) { + throw std::runtime_error("No backend_name given in the config file"); } - catch (const std::exception&) { - return false; + parOut.backend_name = settings["backend_name"].as(); + const std::string backend_settings_section = parOut.backend_name + "_settings"; + if (settings[backend_settings_section]) { + auto settings_node = settings[backend_settings_section]; + const std::string plugin_path = find_plugin_by_name(parOut.backend_name); + parOut.backend_plugin = dindb::BackendPlugin(plugin_path, &settings_node); + throw_if_plugin_failed(parOut.backend_plugin, plugin_path, parOut.backend_name); } - - return false; } namespace { @@ -73,5 +70,29 @@ namespace dinlib { assert(dindb::backend_name(path) == parName); return path; } + + void throw_if_plugin_failed (const dindb::BackendPlugin& parPlugin, const std::string& parPluginPath, const std::string& parIntendedName) { + if (not parPlugin.is_loaded()) { + std::ostringstream oss; + oss << "Unable to load plugin \"" << parIntendedName << + "\" found at path \"" << parPluginPath << '"'; + throw std::runtime_error(oss.str()); + } + if (parPlugin.name() != parIntendedName) { + std::ostringstream oss; + oss << "Plugin \"" << parIntendedName << "\" not found." << + " Plugin at path \"" << parPluginPath << "\" reports \"" << + parPlugin.name() << "\" as its name"; + throw std::runtime_error(oss.str()); + } + if (parPlugin.max_supported_interface_version() < parPlugin.backend_interface_version()) { + std::ostringstream oss; + oss << "Plugin \"" << parPlugin.name() << "\" at path \"" << + parPluginPath << "\" uses interface version " << parPlugin.backend_interface_version() << + " but the maximum supported interface version is " << + parPlugin.max_supported_interface_version(); + throw std::runtime_error(oss.str()); + } + } } //unnamed namespace } //namespace dinlib diff --git a/src/delete/main.cpp b/src/delete/main.cpp index 0c42fb2..1e458ab 100644 --- a/src/delete/main.cpp +++ b/src/delete/main.cpp @@ -61,16 +61,14 @@ int main (int parArgc, char* parArgv[]) { } dinlib::Settings settings; - { - const bool loaded = dinlib::load_settings(CONFIG_FILE_PATH, settings); - if (not loaded) { - std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; - return 1; - } + try { + dinlib::load_settings(CONFIG_FILE_PATH, settings); + } + catch (const std::runtime_error& err) { + std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ":\n"; + std::cerr << err.what() << '\n'; + return 1; } - //TODO: throw if plugin loading failed - assert(settings.backend_plugin.name() == settings.backend_name); - assert(settings.backend_plugin.is_loaded()); if (not vm.count("groupid")) { std::cerr << "No IDs specified\n"; diff --git a/src/locate/main.cpp b/src/locate/main.cpp index 34edb87..860a7a5 100644 --- a/src/locate/main.cpp +++ b/src/locate/main.cpp @@ -71,16 +71,14 @@ int main (int parArgc, char* parArgv[]) { } dinlib::Settings settings; - { - const bool loaded = dinlib::load_settings(CONFIG_FILE_PATH, settings); - if (not loaded) { - std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; - return 1; - } + try { + dinlib::load_settings(CONFIG_FILE_PATH, settings); + } + catch (const std::runtime_error& err) { + std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ":\n"; + std::cerr << err.what() << '\n'; + return 1; } - //TODO: throw if plugin loading failed - assert(settings.backend_plugin.name() == settings.backend_name); - assert(settings.backend_plugin.is_loaded()); auto& db = settings.backend_plugin.backend(); if (vm.count("set")) { diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp index fdcb835..c0436d5 100644 --- a/src/navigate/main.cpp +++ b/src/navigate/main.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include namespace { @@ -52,16 +51,14 @@ int main (int parArgc, char* parArgv[]) { } dinlib::Settings settings; - { - const bool loaded = dinlib::load_settings(CONFIG_FILE_PATH, settings); - if (not loaded) { - std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; - return 1; - } + try { + dinlib::load_settings(CONFIG_FILE_PATH, settings); + } + catch (const std::runtime_error& err) { + std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ":\n"; + std::cerr << err.what() << '\n'; + return 1; } - //TODO: throw if plugin loading failed - assert(settings.backend_plugin.name() == settings.backend_name); - assert(settings.backend_plugin.is_loaded()); do_navigation(settings.backend_plugin.backend()); return 0; diff --git a/src/scan/main.cpp b/src/scan/main.cpp index d739066..e500e02 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -73,16 +73,15 @@ int main (int parArgc, char* parArgv[]) { #endif dinlib::Settings settings; - { - const bool loaded = dinlib::load_settings(CONFIG_FILE_PATH, settings); - if (not loaded) { - std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; - return 1; + try { + if (din::parse_commandline(parArgc, parArgv, vm)) { + return 0; } } - //TODO: throw if plugin loading failed - assert(settings.backend_plugin.name() == settings.backend_name); - assert(settings.backend_plugin.is_loaded()); + catch (const std::invalid_argument& err) { + std::cerr << err.what() << "\nUse --help for help" << std::endl; + return 2; + } bool ignore_read_errors = (vm.count("ignore-errors") > 0); const std::string search_path(vm["search-path"].as()); diff --git a/src/tag/main.cpp b/src/tag/main.cpp index 5195640..454bc43 100644 --- a/src/tag/main.cpp +++ b/src/tag/main.cpp @@ -147,15 +147,13 @@ int main (int parArgc, char* parArgv[]) { assert(id_mode xor glob_mode); dinlib::Settings settings; - { - const bool loaded = dinlib::load_settings(CONFIG_FILE_PATH, settings); - if (not loaded) { - std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ", quitting\n"; - return 1; - } - //TODO: throw if plugin loading failed - assert(settings.backend_plugin.name() == settings.backend_name); - assert(settings.backend_plugin.is_loaded()); + try { + dinlib::load_settings(CONFIG_FILE_PATH, settings); + } + catch (const std::runtime_error& err) { + std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ":\n"; + std::cerr << err.what() << '\n'; + return 1; } const auto master_tags_string = vm["tags"].as(); From 29c98c0154e8737f9e3c3d1d2f35369ec25a05ca Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 2 Jun 2016 22:49:49 +0100 Subject: [PATCH 027/170] Add module to find Redis C library --- cmake/Modules/Findhiredis.cmake | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 cmake/Modules/Findhiredis.cmake diff --git a/cmake/Modules/Findhiredis.cmake b/cmake/Modules/Findhiredis.cmake new file mode 100644 index 0000000..c8d0336 --- /dev/null +++ b/cmake/Modules/Findhiredis.cmake @@ -0,0 +1,55 @@ +#Find libhiredis +# +# HIREDIS_INCLUDE_DIRS - where to find hiredis/hiredis.h +# HIREDIS_LIBRARIES - list of libraries when using libhiredis +# HIREDIS_FOUND - true if libhiredis found +# HIREDIS_VERSION_STRING - the version of the libhiredis found +# + +find_path(HIREDIS_INCLUDE_DIR NAMES hiredis/hiredis.h) + +find_library(HIREDIS_LIBRARY NAMES + hiredis +) + +if(HIREDIS_INCLUDE_DIR) + if(EXISTS "${HIREDIS_INCLUDE_DIR}/hiredis/hiredis.h") + set(hiredis_ver_tmp_major 0) + set(hiredis_ver_tmp_minor 0) + set(hiredis_ver_tmp_patch 0) + file(STRINGS "${HIREDIS_INCLUDE_DIR}/hiredis/hiredis.h" hiredis_version_nums REGEX "^#define[\t ]+HIREDIS_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+") + foreach(hiredis_version_def IN LISTS hiredis_version_nums) + if ("${hiredis_version_def}" MATCHES "HIREDIS_MAJOR") + string(REGEX REPLACE "^#define[\t ]+HIREDIS_MAJOR[\t ]+([0-9]+).*" "\\1" hiredis_ver_tmp_major "${hiredis_version_def}") + elseif ("${hiredis_version_def}" MATCHES "HIREDIS_MINOR") + string(REGEX REPLACE "^#define[\t ]+HIREDIS_MINOR[\t ]+([0-9]+).*" "\\1" hiredis_ver_tmp_minor "${hiredis_version_def}") + elseif ("${hiredis_version_def}" MATCHES "HIREDIS_PATCH") + string(REGEX REPLACE "^#define[\t ]+HIREDIS_PATCH[\t ]+([0-9]+).*" "\\1" hiredis_ver_tmp_patch "${hiredis_version_def}") + endif() + endforeach() + + unset(hiredis_version_nums) + unset(hiredis_version_def) + set(HIREDIS_VERSION_STRING "${hiredis_ver_tmp_major}.${hiredis_ver_tmp_minor}.${hiredis_ver_tmp_patch}") + unset(hiredis_ver_tmp_major) + unset(hiredis_ver_tmp_minor) + unset(hiredis_ver_tmp_patch) + endif() +endif() + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(hiredis + REQUIRED_VARS HIREDIS_LIBRARY HIREDIS_INCLUDE_DIR + VERSION_VAR HIREDIS_VERSION_STRING +) + +if(HIREDIS_FOUND) + set(HIREDIS_LIBRARIES ${HIREDIS_LIBRARY}) + set(HIREDIS_INCLUDE_DIRS ${HIREDIS_INCLUDE_DIR}) +endif() + +mark_as_advanced( + HIREDIS_ROOT_DIR + HIREDIS_INCLUDE_DIR + HIREDIS_LIBRARY +) From 742d024bfb76c7de7a232dceb58d12d409134d24 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 3 Jun 2016 20:26:54 +0200 Subject: [PATCH 028/170] Implement label and uuid retrieval for the disk being scanned. --- CMakeLists.txt | 2 +- src/machinery/discinfo.cpp | 52 ++++++++++++++++++++++++++++++++++++++ src/machinery/discinfo.hpp | 4 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0d7662..b3f19f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ if ("${DINDEXER_CONFIG_FILE}" STREQUAL "") endif() message(STATUS "Config file set to \"${DINDEXER_CONFIG_FILE}\"") -find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options) +find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options filesystem) find_package(PostgreSQL 8.3 REQUIRED) find_package(YamlCpp 0.5.1 REQUIRED) import_libpqtypes_project("${PostgreSQL_INCLUDE_DIRS}" "-O3 ${march_flag}") diff --git a/src/machinery/discinfo.cpp b/src/machinery/discinfo.cpp index 3993c30..521da49 100644 --- a/src/machinery/discinfo.cpp +++ b/src/machinery/discinfo.cpp @@ -35,6 +35,10 @@ # include #endif #include +#include +#include + +namespace fs = boost::filesystem; namespace mchlib { namespace { @@ -167,6 +171,41 @@ namespace mchlib { return static_cast(retval); } #endif + + std::string find_with_same_inode (const std::string& parWhat, const char* parWhere) { + using boost::make_iterator_range; + + struct stat st; + if (stat(parWhat.c_str(), &st)) + return std::string(); + + const auto& inode = st.st_ino; + + fs::path p(parWhere); + if (not fs::exists(p) or not fs::is_directory(p)) { + throw std::runtime_error( + std::string("Search path \"") + p.string() + + "\" doesn't exist"); + } + + for (const fs::directory_entry& itm : make_iterator_range(fs::directory_iterator(p), fs::directory_iterator())) { + struct stat curr_st; + if (stat(itm.path().c_str(), &curr_st) and inode == curr_st.st_ino) + return fs::basename(itm); + } + + return std::string(); + } + + //Get disc label by doing the equivalent of: + //find -L /dev/disk/by-label -inum $(stat -c %i /dev/sda1) -print + std::string retrieve_label (const std::string& parMountpoint) { + return find_with_same_inode(parMountpoint, "/dev/disk/by-label"); + } + + std::string retrieve_uuid (const std::string& parMountpoint) { + return find_with_same_inode(parMountpoint, "/dev/disk/by-uuid"); + } } //unnamed namespace DiscInfo::DiscInfo (std::string&& parPath) : @@ -187,6 +226,11 @@ namespace mchlib { } input_path.pop_right(); } while(input_path.atom_count() > 0); + + if (mountpoint_found()) { + m_label = retrieve_label(mountpoint()); + m_uuid = retrieve_uuid(mountpoint()); + } } bool DiscInfo::mountpoint_found() const { @@ -329,4 +373,12 @@ namespace mchlib { }; } #endif + + const std::string& DiscInfo::label() const { + return m_label; + } + + const std::string& DiscInfo::filesystem_uuid() const { + return m_uuid; + } } //namespace mchlib diff --git a/src/machinery/discinfo.hpp b/src/machinery/discinfo.hpp index b4b4e25..0093d1f 100644 --- a/src/machinery/discinfo.hpp +++ b/src/machinery/discinfo.hpp @@ -52,11 +52,15 @@ namespace mchlib { OpticalTypes optical_type ( void ) const; DriveTypes drive_type ( void ) const; #endif + const std::string& label ( void ) const; + const std::string& filesystem_uuid ( void ) const; private: const std::string m_initial_path; std::string m_mountpoint; std::string m_device; + std::string m_label; + std::string m_uuid; }; } //namespace mchlib From 5e1dfe37499865010ca1c6b8e03a392dd029e172 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 3 Jun 2016 20:27:07 +0200 Subject: [PATCH 029/170] Warning fix in clang. --- .../postgresql/backend_postgresql.hpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index 7a5468b..103c532 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -34,8 +34,8 @@ namespace dindb { BackendPostgreSql ( std::string&& parUser, std::string&& parPass, std::string&& parDB, std::string&& parAddr, uint16_t parPort ); virtual ~BackendPostgreSql ( void ) noexcept; - virtual void connect ( void ); - virtual void disconnect ( void ); + 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; @@ -46,18 +46,18 @@ namespace dindb { virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) override; - virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); - virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ); + virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& 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 ); - virtual std::vector locate_in_db ( const mchlib::TigerHash& parSearch, const TagList& parTags ); - virtual std::vector locate_sets_in_db ( const std::string& parSearch, bool parCaseInsensitive ); - virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ); + 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 ); - virtual std::vector> find_set_details ( const std::vector& parSets ); - virtual std::vector> find_file_details ( GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ); - virtual std::vector find_paths_starting_by ( GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ); + 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: std::unique_ptr m_conn; From f0e67f1c97912ebdfd698131b1a0990f9631ac93 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 3 Jun 2016 21:50:45 +0200 Subject: [PATCH 030/170] Fix wrong block of code Backend plugin was not being initialized due to some copy paste error. --- src/scan/main.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/scan/main.cpp b/src/scan/main.cpp index e500e02..e6e8e3f 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -74,13 +74,12 @@ int main (int parArgc, char* parArgv[]) { dinlib::Settings settings; try { - if (din::parse_commandline(parArgc, parArgv, vm)) { - return 0; - } + dinlib::load_settings(CONFIG_FILE_PATH, settings); } - catch (const std::invalid_argument& err) { - std::cerr << err.what() << "\nUse --help for help" << std::endl; - return 2; + catch (const std::runtime_error& err) { + std::cerr << "Can't load settings from " << CONFIG_FILE_PATH << ":\n"; + std::cerr << err.what() << '\n'; + return 1; } bool ignore_read_errors = (vm.count("ignore-errors") > 0); From 55a61526dced8ce3df7dd94b42de90ea2619a547 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 4 Jun 2016 01:02:37 +0200 Subject: [PATCH 031/170] Fix DiscInfo and make it find label and uuid correctly. It's not the mountpoint's inode that I needed, but that of the dev! --- src/machinery/discinfo.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/machinery/discinfo.cpp b/src/machinery/discinfo.cpp index 521da49..ee96b6d 100644 --- a/src/machinery/discinfo.cpp +++ b/src/machinery/discinfo.cpp @@ -190,7 +190,7 @@ namespace mchlib { for (const fs::directory_entry& itm : make_iterator_range(fs::directory_iterator(p), fs::directory_iterator())) { struct stat curr_st; - if (stat(itm.path().c_str(), &curr_st) and inode == curr_st.st_ino) + if (not stat(itm.path().c_str(), &curr_st) and inode == curr_st.st_ino) return fs::basename(itm); } @@ -199,12 +199,12 @@ namespace mchlib { //Get disc label by doing the equivalent of: //find -L /dev/disk/by-label -inum $(stat -c %i /dev/sda1) -print - std::string retrieve_label (const std::string& parMountpoint) { - return find_with_same_inode(parMountpoint, "/dev/disk/by-label"); + std::string retrieve_label (const std::string& parDev) { + return find_with_same_inode(parDev, "/dev/disk/by-label"); } - std::string retrieve_uuid (const std::string& parMountpoint) { - return find_with_same_inode(parMountpoint, "/dev/disk/by-uuid"); + std::string retrieve_uuid (const std::string& parDev) { + return find_with_same_inode(parDev, "/dev/disk/by-uuid"); } } //unnamed namespace @@ -228,8 +228,8 @@ namespace mchlib { } while(input_path.atom_count() > 0); if (mountpoint_found()) { - m_label = retrieve_label(mountpoint()); - m_uuid = retrieve_uuid(mountpoint()); + m_label = retrieve_label(m_device); + m_uuid = retrieve_uuid(m_device); } } From 7117ff7be266f934e97a5430b4a6023c65b3af10 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 4 Jun 2016 01:03:20 +0200 Subject: [PATCH 032/170] Save and read label and uuid to the database --- dindexer.sql.in | 6 ++++-- include/backends/db_backend.hpp | 4 ++-- include/dindexer-machinery/recorddata.hpp | 2 ++ src/backends/postgresql/backend_postgresql.cpp | 11 ++++++++--- src/backends/postgresql/backend_postgresql.hpp | 4 ++-- src/backends/postgresql/navigate.cpp | 4 +++- src/backends/postgresql/navigate.hpp | 4 +++- src/backends/postgresql/scan.cpp | 14 +++++++++----- src/backends/postgresql/scan.hpp | 2 +- src/machinery/scantask/mediatype.cpp | 7 +++++++ src/scan/main.cpp | 4 +--- 11 files changed, 42 insertions(+), 20 deletions(-) diff --git a/dindexer.sql.in b/dindexer.sql.in index a5a905a..355ba9d 100644 --- a/dindexer.sql.in +++ b/dindexer.sql.in @@ -5,7 +5,7 @@ -- Dumped from database version 9.5.2 -- Dumped by pg_dump version 9.5.2 --- Started on 2016-05-18 00:47:01 CEST +-- Started on 2016-06-03 20:30:32 CEST SET statement_timeout = 0; SET lock_timeout = 0; @@ -160,6 +160,8 @@ CREATE TABLE sets ( creation timestamp with time zone DEFAULT now() NOT NULL, app_name character varying NOT NULL, content_type character(1) DEFAULT 'G'::bpchar NOT NULL, + disk_label text NOT NULL, + fs_uuid text NOT NULL, CONSTRAINT chk_sets_type CHECK (((type = 'C'::bpchar) OR (type = 'D'::bpchar) OR (type = 'V'::bpchar) OR (type = 'B'::bpchar) OR (type = 'F'::bpchar) OR (type = 'H'::bpchar) OR (type = 'Z'::bpchar) OR (type = 'O'::bpchar))) ); @@ -309,7 +311,7 @@ GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO PUBLIC; --- Completed on 2016-05-18 00:47:01 CEST +-- Completed on 2016-06-03 20:30:33 CEST -- -- PostgreSQL database dump complete diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index 07aec9c..a87596d 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -74,7 +74,7 @@ namespace dindb { virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) = 0; - virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ) = 0; + virtual void write_files ( const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature ) = 0; virtual bool search_file_by_hash ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash ) = 0; virtual std::vector locate_in_db ( const std::string& parSearch, const TagList& parTags ) = 0; @@ -83,7 +83,7 @@ namespace dindb { virtual std::vector locate_sets_in_db ( const std::string& parSearch, const std::vector& parSets, bool parCaseInsensitive ) = 0; virtual std::vector find_all_sets ( void ) = 0; - virtual std::vector> find_set_details ( const std::vector& parSets ) = 0; + virtual std::vector> find_set_details ( const std::vector& parSets ) = 0; virtual std::vector> find_file_details ( GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir ) = 0; virtual std::vector find_paths_starting_by ( GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath ) = 0; }; diff --git a/include/dindexer-machinery/recorddata.hpp b/include/dindexer-machinery/recorddata.hpp index 3afc127..29bb653 100644 --- a/include/dindexer-machinery/recorddata.hpp +++ b/include/dindexer-machinery/recorddata.hpp @@ -138,6 +138,8 @@ namespace mchlib { struct SetRecordDataFull : public SetRecordData { std::string name; + std::string disk_label; + std::string fs_uuid; uint32_t disk_number; }; diff --git a/src/backends/postgresql/backend_postgresql.cpp b/src/backends/postgresql/backend_postgresql.cpp index 68577ec..933a9ce 100644 --- a/src/backends/postgresql/backend_postgresql.cpp +++ b/src/backends/postgresql/backend_postgresql.cpp @@ -117,7 +117,7 @@ namespace dindb { dindb::delete_group_from_db(*m_conn, parIDs, parConf); } - void BackendPostgreSql::write_files (const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { + void BackendPostgreSql::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { dindb::write_to_db(*m_conn, parData, parSetData, parSignature); } @@ -145,8 +145,13 @@ namespace dindb { return dindb::find_all_sets(*m_conn); } - std::vector> BackendPostgreSql::find_set_details (const std::vector& parSets) { - return dindb::find_set_details(*m_conn, parSets); + std::vector> BackendPostgreSql::find_set_details (const std::vector& parSets) { + return dindb::find_set_details< + dindb::SetDetail_ID, + dindb::SetDetail_Desc, + dindb::SetDetail_CreeationDate, + dindb::SetDetail_DiskLabel + >(*m_conn, parSets); } std::vector> BackendPostgreSql::find_file_details (GroupIDType parSetID, uint16_t parLevel, boost::string_ref parDir) { diff --git a/src/backends/postgresql/backend_postgresql.hpp b/src/backends/postgresql/backend_postgresql.hpp index 103c532..3b0b872 100644 --- a/src/backends/postgresql/backend_postgresql.hpp +++ b/src/backends/postgresql/backend_postgresql.hpp @@ -46,7 +46,7 @@ namespace dindb { virtual void delete_group ( const std::vector& parIDs, ConfirmDeleCallback parConf ) override; - virtual void write_files ( const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ) 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; @@ -55,7 +55,7 @@ namespace dindb { 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_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; diff --git a/src/backends/postgresql/navigate.cpp b/src/backends/postgresql/navigate.cpp index 43af1f2..ae06f75 100644 --- a/src/backends/postgresql/navigate.cpp +++ b/src/backends/postgresql/navigate.cpp @@ -44,7 +44,9 @@ namespace dindb { {SetDetail_Type, "type"}, {SetDetail_CreeationDate, "creation"}, {SetDetail_AppName, "app_name"}, - {SetDetail_ID, "id"} + {SetDetail_ID, "id"}, + {SetDetail_DiskLabel, "disk_label"}, + {SetDetail_FSUuid, "fs_uuid"} }; const FileDetailsMap g_file_details_map { {FileDetail_ID, "id"}, diff --git a/src/backends/postgresql/navigate.hpp b/src/backends/postgresql/navigate.hpp index d52ecd7..cc732ba 100644 --- a/src/backends/postgresql/navigate.hpp +++ b/src/backends/postgresql/navigate.hpp @@ -44,7 +44,9 @@ namespace dindb { SetDetail_Type = 0x02, SetDetail_CreeationDate = 0x04, SetDetail_AppName = 0x08, - SetDetail_ID = 0x10 + SetDetail_ID = 0x10, + SetDetail_DiskLabel = 0x20, + SetDetail_FSUuid = 0x40 }; enum FileDetails { diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index fd533ed..ca5e09b 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -64,7 +64,7 @@ namespace dindb { { auto resultset = parDB.query( - "SELECT \"desc\",\"type\",\"disk_number\" FROM sets WHERE \"id\"=$1;", + "SELECT \"desc\",\"type\",\"disk_number\",\"fs_uuid\",\"disk_label\" FROM sets WHERE \"id\"=$1;", group_id ); if (resultset.empty()) { @@ -77,11 +77,13 @@ namespace dindb { parSet.type = lexical_cast(row["type"]); parSet.name = row["desc"]; parSet.disk_number = lexical_cast(row["disk_number"]); + parSet.fs_uuid = row["fs_uuid"]; + parSet.disk_label = row["disk_label"]; } return true; } - void write_to_db (pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature) { + void write_to_db (pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { using std::chrono::system_clock; using boost::lexical_cast; @@ -96,12 +98,14 @@ namespace dindb { { auto id_res = parDB.query("INSERT INTO \"sets\" " "(\"desc\",\"type\",\"app_name\"" - ",\"content_type\") " - "VALUES ($1, $2, $3, $4) RETURNING \"id\";", + ",\"content_type\",\"fs_uuid\",\"disk_label\") " + "VALUES ($1, $2, $3, $4, $5, $6) RETURNING \"id\";", parSetData.name, boost::string_ref(&parSetData.type, 1), parSignature, - boost::string_ref(&parSetData.content_type, 1) + boost::string_ref(&parSetData.content_type, 1), + parSetData.fs_uuid, + parSetData.disk_label ); assert(id_res.size() == 1); assert(id_res[0].size() == 1); diff --git a/src/backends/postgresql/scan.hpp b/src/backends/postgresql/scan.hpp index 72521d7..b8f7482 100644 --- a/src/backends/postgresql/scan.hpp +++ b/src/backends/postgresql/scan.hpp @@ -36,7 +36,7 @@ namespace pq { namespace dindb { struct Settings;; - void write_to_db ( pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordData& parSetData, const std::string& parSignature ); + void write_to_db ( pq::Connection& parDB, const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature ); bool read_from_db ( mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, pq::Connection& parDB, const mchlib::TigerHash& parHash ); } //namespace dindb diff --git a/src/machinery/scantask/mediatype.cpp b/src/machinery/scantask/mediatype.cpp index 1374c3f..ddd244a 100644 --- a/src/machinery/scantask/mediatype.cpp +++ b/src/machinery/scantask/mediatype.cpp @@ -21,6 +21,7 @@ # include "dindexer-machinery/mediatype.hpp" #endif #include "dindexer-machinery/recorddata.hpp" +#include "discinfo.hpp" #include namespace mchlib { @@ -57,6 +58,12 @@ namespace mchlib { #else data.type = media_type_to_char(m_default); #endif + + { + DiscInfo info((std::string(m_search_path))); + data.disk_label = info.label(); + data.fs_uuid = info.filesystem_uuid(); + } } } //namespace scantask } //namespace mchlib diff --git a/src/scan/main.cpp b/src/scan/main.cpp index e6e8e3f..207feec 100644 --- a/src/scan/main.cpp +++ b/src/scan/main.cpp @@ -118,7 +118,6 @@ namespace { bool add_to_db (const std::vector& parData, const mchlib::SetRecordDataFull& parSet, dindb::Backend& parDB, bool parForce) { using mchlib::FileRecordData; using mchlib::SetRecordDataFull; - using mchlib::SetRecordData; if (not parForce) { const auto& first_hash = parData.front().hash; @@ -130,11 +129,10 @@ namespace { } } - const SetRecordData& set_data {parSet.name, parSet.type, parSet.content_type }; const auto app_signature = dinlib::dindexer_signature(); const auto lib_signature = mchlib::lib_signature(); const std::string signature = std::string(app_signature.data(), app_signature.size()) + "/" + std::string(lib_signature.data(), lib_signature.size()); - parDB.write_files(parData, set_data, signature); + parDB.write_files(parData, parSet, signature); return true; } From 2057c797cb4f4e2bfc3d83d422405b6ed9f24cd5 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 4 Jun 2016 01:13:26 +0200 Subject: [PATCH 033/170] SetRecordData is not really needed anymore so get rid of it Always use SetRecordDataFull now. --- include/backends/db_backend.hpp | 1 - include/dindexer-machinery/recorddata.hpp | 10 +++------- src/backends/postgresql/scan.hpp | 1 - src/machinery/scantask/setbasic.cpp | 2 -- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/include/backends/db_backend.hpp b/include/backends/db_backend.hpp index a87596d..b195f78 100644 --- a/include/backends/db_backend.hpp +++ b/include/backends/db_backend.hpp @@ -30,7 +30,6 @@ namespace mchlib { struct TigerHash; struct FileRecordData; - struct SetRecordData; struct SetRecordDataFull; } //namespace mchlib diff --git a/include/dindexer-machinery/recorddata.hpp b/include/dindexer-machinery/recorddata.hpp index 29bb653..8ecf5ce 100644 --- a/include/dindexer-machinery/recorddata.hpp +++ b/include/dindexer-machinery/recorddata.hpp @@ -130,17 +130,13 @@ namespace mchlib { bool hash_valid; }; - struct SetRecordData { - boost::string_ref name; - char type; - char content_type; - }; - - struct SetRecordDataFull : public SetRecordData { + struct SetRecordDataFull { std::string name; std::string disk_label; std::string fs_uuid; uint32_t disk_number; + char type; + char content_type; }; #if !defined(NDEBUG) diff --git a/src/backends/postgresql/scan.hpp b/src/backends/postgresql/scan.hpp index b8f7482..b270c1a 100644 --- a/src/backends/postgresql/scan.hpp +++ b/src/backends/postgresql/scan.hpp @@ -24,7 +24,6 @@ namespace mchlib { struct FileRecordData; - struct SetRecordData; struct SetRecordDataFull; struct TigerHash; } //namespace mchlib diff --git a/src/machinery/scantask/setbasic.cpp b/src/machinery/scantask/setbasic.cpp index 0538aed..f9f4e29 100644 --- a/src/machinery/scantask/setbasic.cpp +++ b/src/machinery/scantask/setbasic.cpp @@ -29,13 +29,11 @@ namespace mchlib { } void SetBasic::on_data_destroy (SetRecordDataFull& parData) { - static_cast(parData).name.clear(); parData.name.clear(); } void SetBasic::on_data_create (SetRecordDataFull& parData) { parData.name = m_set_name; - static_cast(parData).name = parData.name; } } //namespace scantask } //namespace mchlib From d5cf8e21b220495aec3323270d51e9a42d3edd8d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 4 Jun 2016 01:13:47 +0200 Subject: [PATCH 034/170] Add cleaning of the new uuid and label properties --- src/machinery/scantask/setbasic.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machinery/scantask/setbasic.cpp b/src/machinery/scantask/setbasic.cpp index f9f4e29..53a5f97 100644 --- a/src/machinery/scantask/setbasic.cpp +++ b/src/machinery/scantask/setbasic.cpp @@ -30,10 +30,14 @@ namespace mchlib { void SetBasic::on_data_destroy (SetRecordDataFull& parData) { parData.name.clear(); + parData.fs_uuid.clear(); + parData.disk_label.clear(); } void SetBasic::on_data_create (SetRecordDataFull& parData) { parData.name = m_set_name; + parData.fs_uuid.clear(); + parData.disk_label.clear(); } } //namespace scantask } //namespace mchlib From a1490c30968118b4c69f6837966b3986a47177fe Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 6 Jun 2016 19:52:42 +0200 Subject: [PATCH 035/170] Make split_tags a bit more generic so I can reuse it I need it in an upcoming commit where I want to split on ':' --- include/dindexer-common/split_tags.hpp | 1 + src/common/split_tags.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/dindexer-common/split_tags.hpp b/include/dindexer-common/split_tags.hpp index 149cc25..3005751 100644 --- a/include/dindexer-common/split_tags.hpp +++ b/include/dindexer-common/split_tags.hpp @@ -24,6 +24,7 @@ #include "helpers/compatibility.h" namespace dinlib { + std::vector split_and_trim ( const std::string& parList, char parSeparator ) a_pure; std::vector split_tags ( const std::string& parCommaSeparatedList ) a_pure; } //namespace dinlib diff --git a/src/common/split_tags.cpp b/src/common/split_tags.cpp index 4ba7275..931a8d5 100644 --- a/src/common/split_tags.cpp +++ b/src/common/split_tags.cpp @@ -26,6 +26,10 @@ namespace dinlib { std::vector split_tags (const std::string& parCommaSeparatedList) { + return split_and_trim(parCommaSeparatedList, ','); + } + + std::vector split_and_trim (const std::string& parList, char parSeparator) { using OutRange = boost::iterator_range; using boost::token_finder; using boost::adaptors::transformed; @@ -42,7 +46,7 @@ namespace dinlib { //http://www.boost.org/doc/libs/1_60_0/doc/html/boost/algorithm/token_finder.html //https://stackoverflow.com/questions/20781090/difference-between-boostsplit-vs-boostiter-split return boost::copy_range>( - iter_split(out_range, parCommaSeparatedList, token_finder([](char c){return ','==c;})) | + iter_split(out_range, parList, token_finder([parSeparator](char c){return parSeparator==c;})) | transformed([](const OutRange& r){return trim_copy(r);}) | transformed([](const OutRange& r){return string_ref(&*r.begin(), r.size());}) | filtered([](const string_ref& r){return not r.empty();}) From 624bba121f746c3a6fb7ae343a001cf4bda68efc Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 6 Jun 2016 19:54:20 +0200 Subject: [PATCH 036/170] Remove hardcoded path to postgresql backend and make the search dynamic --- CMakeLists.txt | 2 +- src/backends/backend_loader.cpp | 23 ++++++++++++++++--- src/common/settings.cpp | 39 +++++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3f19f6..f0dd066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ if ("${DINDEXER_CONFIG_FILE}" STREQUAL "") endif() message(STATUS "Config file set to \"${DINDEXER_CONFIG_FILE}\"") -find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options filesystem) +find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options filesystem system) find_package(PostgreSQL 8.3 REQUIRED) find_package(YamlCpp 0.5.1 REQUIRED) import_libpqtypes_project("${PostgreSQL_INCLUDE_DIRS}" "-O3 ${march_flag}") diff --git a/src/backends/backend_loader.cpp b/src/backends/backend_loader.cpp index 3aa8547..05b5909 100644 --- a/src/backends/backend_loader.cpp +++ b/src/backends/backend_loader.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace dindb { namespace { @@ -34,9 +35,22 @@ namespace dindb { assert(parSOHandle); assert(parConfig); - auto create = reinterpret_cast(dlsym(parSOHandle, "dindexer_create_backend")); - auto destroy = reinterpret_cast(dlsym(parSOHandle, "dindexer_destroy_backend")); + const char* const fun_name_create = "dindexer_create_backend"; + const char* const fun_name_destroy = "dindexer_destroy_backend"; + auto create = reinterpret_cast(dlsym(parSOHandle, fun_name_create)); + auto destroy = reinterpret_cast(dlsym(parSOHandle, fun_name_destroy)); + + if (not create) { + std::ostringstream oss; + oss << "Unable to find function " << fun_name_create; + throw std::runtime_error(oss.str()); + } + if (not destroy) { + std::ostringstream oss; + oss << "Unable to find function " << fun_name_destroy; + throw std::runtime_error(oss.str()); + } return BackendPtr(create(parConfig), destroy); } @@ -65,7 +79,10 @@ namespace dindb { using SoHandle = std::unique_ptr; auto handle = SoHandle(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose); - return backend_name(handle.get()); + if (handle) + return backend_name(handle.get()); + else + return std::string(); } BackendPlugin::BackendPlugin() : diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 23eeb7d..cf68d48 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -16,33 +16,40 @@ */ #include "dindexer-common/settings.hpp" +#include "dindexer-common/split_tags.hpp" #include "dindexerConfig.h" #include #include #include #include #include +#include +#include namespace dinlib { namespace { std::string expand ( const char* parString ); - std::string find_plugin_by_name ( const std::string& parName ); + std::string find_plugin_by_name ( const std::vector& parSearchPaths, const std::string& parName ); void throw_if_plugin_failed ( const dindb::BackendPlugin& parPlugin, const std::string& parPluginPath, const std::string& parIntendedName ); } //unnamed namespace void load_settings (const std::string& parPath, dinlib::Settings& parOut, bool parExpand) { const std::string path = (parExpand ? expand(parPath.c_str()) : parPath); + std::string search_paths(ACTIONS_SEARCH_PATH); auto settings = YAML::LoadFile(path); - if (not settings["backend_name"]) { + if (not settings["backend_name"]) throw std::runtime_error("No backend_name given in the config file"); - } + if (settings["backend_paths"]) + search_paths += ":" + settings["backend_paths"].as(); parOut.backend_name = settings["backend_name"].as(); const std::string backend_settings_section = parOut.backend_name + "_settings"; if (settings[backend_settings_section]) { auto settings_node = settings[backend_settings_section]; - const std::string plugin_path = find_plugin_by_name(parOut.backend_name); + const std::string plugin_path = find_plugin_by_name(split_and_trim(search_paths, ':'), parOut.backend_name); + if (plugin_path.empty()) + throw std::runtime_error(std::string("Unable to find any suitable plugin with the specified name \"") + parOut.backend_name + "\""); parOut.backend_plugin = dindb::BackendPlugin(plugin_path, &settings_node); throw_if_plugin_failed(parOut.backend_plugin, plugin_path, parOut.backend_name); } @@ -61,14 +68,24 @@ namespace dinlib { return oss.str(); } - std::string find_plugin_by_name (const std::string& parName) { - //assert(false); //not implemented - //TODO: write a proper implementation - std::string path = ACTIONS_SEARCH_PATH; - path += "/backends/postgresql/libdindexer-backend-postgresql.so"; + std::string find_plugin_by_name (const std::vector& parSearchPaths, const std::string& parName) { + using boost::filesystem::path; + using boost::filesystem::is_directory; + using boost::filesystem::directory_iterator; + using boost::filesystem::directory_entry; + using boost::make_iterator_range; - assert(dindb::backend_name(path) == parName); - return path; + for (auto search_path : parSearchPaths) { + const std::string search_path_cpy(search_path.begin(), search_path.end()); + path curr_path(search_path_cpy); + auto listing = make_iterator_range(directory_iterator(curr_path), directory_iterator()); + for (const directory_entry& entry : listing) { + auto current_full_path = entry.path().string(); + if (not is_directory(entry) and dindb::backend_name(current_full_path) == parName) + return current_full_path; + } + } + return std::string(); } void throw_if_plugin_failed (const dindb::BackendPlugin& parPlugin, const std::string& parPluginPath, const std::string& parIntendedName) { From 3fe962a8e515fb3fc96b3c10b8f9810557868c34 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 6 Jun 2016 20:24:05 +0200 Subject: [PATCH 037/170] Make symlink to postgresql backend This is helpful so when running dindexer in a dev environment you don't need to list all the possible paths to every backend. Symlinks to all backends will all be in the same place. --- dindexer.yml | 1 + src/backends/CMakeLists.txt | 10 +++++++++- src/backends/postgresql/CMakeLists.txt | 1 + src/common/settings.cpp | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dindexer.yml b/dindexer.yml index 38242d4..0f1330f 100644 --- a/dindexer.yml +++ b/dindexer.yml @@ -7,3 +7,4 @@ postgresql_settings: dbname: dindexer port: 5432 address: 200.100.200.100 +backend_paths: path to your build_dir/src/backend diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt index 0ac6613..302b2e8 100644 --- a/src/backends/CMakeLists.txt +++ b/src/backends/CMakeLists.txt @@ -1,5 +1,14 @@ project(${bare_name}-backend CXX) +set(BACKEND_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") +function(ln_backend backend_name) + add_custom_command(TARGET "${backend_name}" POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink $ ${BACKEND_BINARY_DIR}/$ + DEPENDS ${BACKEND_BINARY_DIR}/$ + COMMENT "Creating symlink to ${backend_name}" + ) +endfunction() + add_library(${PROJECT_NAME} STATIC backend_loader.cpp ) @@ -25,5 +34,4 @@ target_link_libraries(${PROJECT_NAME} #) add_subdirectory(postgresql) - add_dependencies(${PROJECT_NAME} ${bare_name}-backend-postgresql) diff --git a/src/backends/postgresql/CMakeLists.txt b/src/backends/postgresql/CMakeLists.txt index 89b8680..486d5b0 100644 --- a/src/backends/postgresql/CMakeLists.txt +++ b/src/backends/postgresql/CMakeLists.txt @@ -23,3 +23,4 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib/static ) +ln_backend(${PROJECT_NAME}) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index cf68d48..95b6b45 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -35,7 +35,7 @@ namespace dinlib { void load_settings (const std::string& parPath, dinlib::Settings& parOut, bool parExpand) { const std::string path = (parExpand ? expand(parPath.c_str()) : parPath); - std::string search_paths(ACTIONS_SEARCH_PATH); + std::string search_paths; auto settings = YAML::LoadFile(path); From 0ab66fa1f14f402afa29f0229b9ae43f283367e8 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 7 Jun 2016 22:45:30 +0100 Subject: [PATCH 038/170] 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} From db23dcea3ff441f67504efdbb9a4744971166577 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 7 Jun 2016 23:13:24 +0100 Subject: [PATCH 039/170] Add missing implementation and fix crashes in redis backend. With this you can insert a new set (set only, no files) with dindexer-scan. --- src/backends/redis/CMakeLists.txt | 3 +- src/backends/redis/backend_redis.cpp | 59 +++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/backends/redis/CMakeLists.txt b/src/backends/redis/CMakeLists.txt index 8535712..634774d 100644 --- a/src/backends/redis/CMakeLists.txt +++ b/src/backends/redis/CMakeLists.txt @@ -21,4 +21,5 @@ install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib/static -) \ No newline at end of file +) +ln_backend(${PROJECT_NAME}) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 8ddfb66..7c9ccc6 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -17,6 +17,8 @@ #include "backend_redis.hpp" #include "dindexer-machinery/recorddata.hpp" +#include "backends/exposed_functions.hpp" +#include "backends/backend_version.hpp" #include #include #include @@ -24,12 +26,42 @@ #include #include #include +#include namespace dindb { namespace { using RedisReply = std::unique_ptr; - } //unnamed namespace + struct RedisConnectionSettings { + std::string address; + uint16_t port; + }; + } //unnamed namespace +} //namespace dindb + +namespace YAML { + template<> + struct convert { + static Node encode (const dindb::RedisConnectionSettings& parSettings) { + Node node; + node["address"] = parSettings.address; + node["port"] = parSettings.port; + return node; + } + + static bool decode (const Node& parNode, dindb::RedisConnectionSettings& parSettings) { + if (not parNode.IsMap() or parNode.size() != 2) { + return false; + } + + parSettings.address = parNode["address"].as(); + parSettings.port = parNode["port"].as(); + return true; + } + }; +} //namespace YAML + +namespace dindb { BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, bool parConnect) : m_conn(nullptr, &redisFree), @@ -156,3 +188,28 @@ namespace dindb { return m_conn and not m_conn->err; } } //namespace dindb + +extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { + if (not parConfig) + return nullptr; + + auto config = parConfig->as(); + return new dindb::BackendRedis( + std::move(config.address), + config.port, + true + ); +} + +extern "C" void dindexer_destroy_backend (dindb::Backend* parDele) { + if (parDele) + delete parDele; +} + +extern "C" const char* dindexer_backend_name() { + return "redis"; +} + +extern "C" int dindexer_backend_iface_version() { + return dindb::g_current_iface_version; +} From f7a7015c651c9e4bbb556b6d8dd76e20c4c4d505 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 9 Jun 2016 19:24:08 +0200 Subject: [PATCH 040/170] Start putting Redis stuff in a wrapper class. Nonworking, but the project builds. --- src/backends/redis/CMakeLists.txt | 1 + src/backends/redis/backend_redis.cpp | 71 ++---------------- src/backends/redis/backend_redis.hpp | 12 +-- src/backends/redis/command.cpp | 105 +++++++++++++++++++++++++++ src/backends/redis/command.hpp | 73 +++++++++++++++++++ 5 files changed, 188 insertions(+), 74 deletions(-) create mode 100644 src/backends/redis/command.cpp create mode 100644 src/backends/redis/command.hpp diff --git a/src/backends/redis/CMakeLists.txt b/src/backends/redis/CMakeLists.txt index 634774d..8a614df 100644 --- a/src/backends/redis/CMakeLists.txt +++ b/src/backends/redis/CMakeLists.txt @@ -4,6 +4,7 @@ find_package(hiredis 0.11.0 REQUIRED) add_library(${PROJECT_NAME} SHARED backend_redis.cpp + command.cpp ) target_include_directories(${PROJECT_NAME} SYSTEM diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 7c9ccc6..ec02fe0 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -20,18 +20,10 @@ #include "backends/exposed_functions.hpp" #include "backends/backend_version.hpp" #include -#include -#include -#include -#include -#include -#include #include namespace dindb { namespace { - using RedisReply = std::unique_ptr; - struct RedisConnectionSettings { std::string address; uint16_t port; @@ -62,42 +54,20 @@ namespace YAML { } //namespace YAML namespace dindb { - 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(std::string &&parAddress, uint16_t parPort, bool parConnect) : + m_redis(std::move(parAddress), parPort, parConnect) + { } 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); - } - } + m_redis.connect(); + } void BackendRedis::disconnect() { - m_conn.reset(); + m_redis.disconnect(); } void BackendRedis::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { @@ -122,30 +92,7 @@ namespace dindb { } 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 - ); + //TODO: run command } bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { @@ -183,10 +130,6 @@ namespace dindb { 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 extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) { diff --git a/src/backends/redis/backend_redis.hpp b/src/backends/redis/backend_redis.hpp index 3ab92a0..1e32ba9 100644 --- a/src/backends/redis/backend_redis.hpp +++ b/src/backends/redis/backend_redis.hpp @@ -19,12 +19,10 @@ #define idB2F92EE07A004D5293FD0657EEE8F75B #include "backends/db_backend.hpp" -#include +#include "command.hpp" #include #include -struct redisContext; - namespace dindb { class BackendRedis : public Backend { public: @@ -58,13 +56,7 @@ namespace dindb { 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; + redis::Command m_redis; }; } //namespace dindb diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp new file mode 100644 index 0000000..5b53b64 --- /dev/null +++ b/src/backends/redis/command.cpp @@ -0,0 +1,105 @@ +/* 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 "command.hpp" +#include +#include +#include +#include +#include +#include + +namespace redis { + namespace { + using RedisReply = std::unique_ptr; + } //unnamed namespace + + Command::Command (std::string&& parAddress, uint16_t parPort, bool parConnect) : + m_conn(nullptr, &redisFree), + m_address(std::move(parAddress)), + m_port(parPort) + { + if (parConnect) + this->connect(); + } + + Command::~Command() noexcept { + } + + void Command::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 Command::disconnect() { + m_conn.reset(); + } + + void Command::run (const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths) { + assert(is_connected()); + + RedisReply reply( + static_cast(redisCommandArgv(m_conn.get(), parArgc, parArgv, parLengths)), + &freeReplyObject + ); + + //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 Command::is_connected() const { + return m_conn and not m_conn->err; + } +} //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp new file mode 100644 index 0000000..fe327ed --- /dev/null +++ b/src/backends/redis/command.hpp @@ -0,0 +1,73 @@ +/* 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 idD83EEBFC927840C6B9F32D61A1D1E582 +#define idD83EEBFC927840C6B9F32D61A1D1E582 + +#include +#include +#include +#include +#include +#include + +struct redisContext; + +namespace redis { + class Command { + public: + Command ( std::string&& parAddress, uint16_t parPort, bool parConnect ); + ~Command ( void ) noexcept; + + void connect ( void ); + void disconnect ( void ); + + bool is_connected ( void ) const; + + template + void run ( const char* parCommand, Args&&... parArgs ); + + private: + using RedisConnection = std::unique_ptr; + + void run ( const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths ); + + RedisConnection m_conn; + std::string m_address; + uint16_t m_port; + }; + + template + void Command::run (const char* parCommand, Args&&... parArgs) { + constexpr const std::size_t arg_count = sizeof...(Args); + using CharPointerArray = std::array; + using LengthArray = std::array; + + CharPointerArray arguments; + LengthArray lengths; + assert(false); //TODO write implementation + + this->run( + parCommand, + static_cast(arg_count), + arguments.data(), + lengths.data() + ); + } +} //namespace redis + +#endif From 49a8e81feda43a1641a9167d53d5e3182d79ed31 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 9 Jun 2016 22:20:22 +0200 Subject: [PATCH 041/170] Restore adding sets into Redis using the new run() method. Partial implementation - not for use in real world cases. --- src/backends/redis/arg_to_bin_safe.hpp | 70 ++++++++++++++++++++++++++ src/backends/redis/backend_redis.cpp | 8 ++- src/backends/redis/command.cpp | 40 ++++++++++++++- src/backends/redis/command.hpp | 46 ++++++++++++++--- 4 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 src/backends/redis/arg_to_bin_safe.hpp diff --git a/src/backends/redis/arg_to_bin_safe.hpp b/src/backends/redis/arg_to_bin_safe.hpp new file mode 100644 index 0000000..360e4dd --- /dev/null +++ b/src/backends/redis/arg_to_bin_safe.hpp @@ -0,0 +1,70 @@ +/* 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 id9348909738B047B7B6912D73CB519039 +#define id9348909738B047B7B6912D73CB519039 + +#include "helpers/compatibility.h" +#include +#include +#include + +namespace redis { + namespace implem { + template + const char* arg_to_bin_safe_char ( const T& parArg ); + + template + std::size_t arg_to_bin_safe_length ( const T& parArg ) a_pure; + + template + struct MakeCharInfo; + + template<> + struct MakeCharInfo { + MakeCharInfo ( const std::string& parData ) : m_string(parData) {} + const char* data ( void ) const { return m_string.data(); } + std::size_t size ( void ) const { return m_string.size(); } + + private: + const std::string& m_string; + }; + + template<> + struct MakeCharInfo { + MakeCharInfo ( const boost::string_ref& parData ) : m_data(parData.data()), m_size(parData.size()) {} + const char* data ( void ) const { return m_data; } + std::size_t size ( void ) const { return m_size; } + + private: + const char* const m_data; + const std::size_t m_size; + }; + + template + inline const char* arg_to_bin_safe_char (const T& parArg) { + return MakeCharInfo(parArg).data(); + } + + template + inline std::size_t arg_to_bin_safe_length (const T& parArg) { + return MakeCharInfo(parArg).size(); + } + } //namespace implem +} //namespace redis + +#endif diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index ec02fe0..9b88ef2 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -19,8 +19,10 @@ #include "dindexer-machinery/recorddata.hpp" #include "backends/exposed_functions.hpp" #include "backends/backend_version.hpp" +#include "dindexerConfig.h" #include #include +#include namespace dindb { namespace { @@ -92,7 +94,11 @@ namespace dindb { } void BackendRedis::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { - //TODO: run command + using boost::lexical_cast; + + auto incr_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices set 1"); + const std::string set_key = PROGRAM_NAME ":set:" + lexical_cast(redis::get_integer(incr_reply)); + auto insert_set_reply = m_redis.run("HMSET %b name %b disk_label %b fs_uuid %b", set_key, parSetData.name, parSetData.disk_label, parSetData.fs_uuid); } bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index 5b53b64..72d5ebd 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -22,12 +22,45 @@ #include #include #include +#include +#include namespace redis { namespace { using RedisReply = std::unique_ptr; + + RedisReplyType make_redis_reply_type (redisReply* parReply) { + using boost::transform_iterator; + using PtrToReplyIterator = transform_iterator; + + switch (parReply->type) { + case REDIS_REPLY_INTEGER: + return parReply->integer; + case REDIS_REPLY_STRING: + return std::string(parReply->str, parReply->len); + case REDIS_REPLY_ARRAY: + return std::vector( + PtrToReplyIterator(parReply->element, &make_redis_reply_type), + PtrToReplyIterator(parReply->element + parReply->elements, &make_redis_reply_type) + ); + default: + return RedisReplyType(); + }; + } } //unnamed namespace + long long get_integer (const RedisReplyType& parReply) { + return boost::get(parReply); + } + + std::string get_string (const RedisReplyType& parReply) { + return boost::get(parReply); + } + + std::vector get_array (const RedisReplyType& parReply) { + return boost::get>(parReply); + } + Command::Command (std::string&& parAddress, uint16_t parPort, bool parConnect) : m_conn(nullptr, &redisFree), m_address(std::move(parAddress)), @@ -66,7 +99,10 @@ namespace redis { m_conn.reset(); } - void Command::run (const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths) { + RedisReplyType Command::run_pvt (const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths) { + assert(parCommand); + assert(parArgv); + assert(parLengths); //This /could/ be null, but I don't see why it should assert(is_connected()); RedisReply reply( @@ -74,6 +110,8 @@ namespace redis { &freeReplyObject ); + return make_redis_reply_type(reply.get()); + //std::string key; //{ // std::ostringstream key_oss; diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index fe327ed..dfdcc5b 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -18,16 +18,46 @@ #ifndef idD83EEBFC927840C6B9F32D61A1D1E582 #define idD83EEBFC927840C6B9F32D61A1D1E582 +#include "arg_to_bin_safe.hpp" #include #include #include #include #include #include +#include +#include +#include +#include struct redisContext; namespace redis { + class RedisReplyType; + + namespace implem { + using RedisVariantType = boost::variant< + long long, + std::string, + boost::recursive_wrapper> + >; + enum RedisVariantTypes { + RedisVariantType_Integer = 0, + RedisVariantType_String, + RedisVariantType_Array + }; + } //namespace implem + + struct RedisReplyType : implem::RedisVariantType { + using base_class = implem::RedisVariantType; + + RedisReplyType ( void ) = default; + RedisReplyType ( long long parVal ) : base_class(parVal) {} + RedisReplyType ( std::string&& parVal ) : base_class(std::move(parVal)) {} + RedisReplyType ( std::vector&& parVal ) : base_class(std::move(parVal)) {} + ~RedisReplyType ( void ) noexcept = default; + }; + class Command { public: Command ( std::string&& parAddress, uint16_t parPort, bool parConnect ); @@ -39,12 +69,12 @@ namespace redis { bool is_connected ( void ) const; template - void run ( const char* parCommand, Args&&... parArgs ); + RedisReplyType run ( const char* parCommand, Args&&... parArgs ); private: using RedisConnection = std::unique_ptr; - void run ( const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths ); + RedisReplyType run_pvt ( const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths ); RedisConnection m_conn; std::string m_address; @@ -52,7 +82,7 @@ namespace redis { }; template - void Command::run (const char* parCommand, Args&&... parArgs) { + RedisReplyType Command::run (const char* parCommand, Args&&... parArgs) { constexpr const std::size_t arg_count = sizeof...(Args); using CharPointerArray = std::array; using LengthArray = std::array; @@ -61,13 +91,17 @@ namespace redis { LengthArray lengths; assert(false); //TODO write implementation - this->run( + return this->run_pvt( parCommand, static_cast(arg_count), - arguments.data(), - lengths.data() + CharPointerArray{ implem::arg_to_bin_safe_char(std::forward(parArgs))... }.data(), + LengthArray{ implem::arg_to_bin_safe_length(std::forward(parArgs))... }.data() ); } + + long long get_integer ( const RedisReplyType& parReply ); + std::string get_string ( const RedisReplyType& parReply ); + std::vector get_array ( const RedisReplyType& parReply ); } //namespace redis #endif From 8bdb1f237fb17a043d442a970af53f698eed38e0 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 9 Jun 2016 22:55:38 +0200 Subject: [PATCH 042/170] Replace spaces with tabs --- src/backends/postgresql/scan.cpp | 4 +- src/backends/redis/backend_redis.cpp | 64 ++++++++++++++-------------- src/backends/redis/command.cpp | 12 +++--- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index ca5e09b..881c52d 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -104,8 +104,8 @@ namespace dindb { boost::string_ref(&parSetData.type, 1), parSignature, boost::string_ref(&parSetData.content_type, 1), - parSetData.fs_uuid, - parSetData.disk_label + parSetData.fs_uuid, + parSetData.disk_label ); assert(id_res.size() == 1); assert(id_res[0].size() == 1); diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 9b88ef2..1cf5e32 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -56,44 +56,44 @@ namespace YAML { } //namespace YAML namespace dindb { - BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, bool parConnect) : + BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, bool parConnect) : m_redis(std::move(parAddress), parPort, parConnect) { - } + } - BackendRedis::~BackendRedis() noexcept { - } + BackendRedis::~BackendRedis() noexcept { + } - void BackendRedis::connect() { + void BackendRedis::connect() { m_redis.connect(); } - void BackendRedis::disconnect() { - m_redis.disconnect(); - } - - 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::disconnect() { + m_redis.disconnect(); } - void BackendRedis::delete_all_tags (const std::vector& parFiles, GroupIDType parSet) { + void BackendRedis::tag_files (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { } - void BackendRedis::delete_all_tags (const std::vector& parRegexes, GroupIDType parSet) { + void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { } - void BackendRedis::delete_group (const std::vector& parIDs, ConfirmDeleCallback parConf) { + void BackendRedis::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { } - void BackendRedis::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { + 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) { using boost::lexical_cast; auto incr_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices set 1"); @@ -101,39 +101,39 @@ namespace dindb { auto insert_set_reply = m_redis.run("HMSET %b name %b disk_label %b fs_uuid %b", set_key, parSetData.name, parSetData.disk_label, parSetData.fs_uuid); } - bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { + 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) { + 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) { + 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) { + 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) { + 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() { + std::vector BackendRedis::find_all_sets() { return std::vector(); } - std::vector> BackendRedis::find_set_details (const std::vector& parSets) { + 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) { + 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) { + std::vector BackendRedis::find_paths_starting_by (GroupIDType parGroupID, uint16_t parLevel, boost::string_ref parPath) { return std::vector(); } } //namespace dindb diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index 72d5ebd..f2b9e82 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -27,7 +27,7 @@ namespace redis { namespace { - using RedisReply = std::unique_ptr; + using RedisReply = std::unique_ptr; RedisReplyType make_redis_reply_type (redisReply* parReply) { using boost::transform_iterator; @@ -66,15 +66,15 @@ namespace redis { m_address(std::move(parAddress)), m_port(parPort) { - if (parConnect) - this->connect(); + if (parConnect) + this->connect(); } Command::~Command() noexcept { } - void Command::connect() { - if (not m_conn) { + void Command::connect() { + if (not m_conn) { struct timeval timeout = {5, 500000}; //5.5 seconds? RedisConnection conn( redisConnectWithTimeout(m_address.c_str(), m_port, timeout), @@ -93,7 +93,7 @@ namespace redis { } std::swap(conn, m_conn); } - } + } void Command::disconnect() { m_conn.reset(); From 04b667485e5fc38b372432cbe029c795f9edec89 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 10 Jun 2016 09:55:37 +0200 Subject: [PATCH 043/170] Add optional database selection parameter in yml file. --- src/backends/redis/backend_redis.cpp | 18 ++++++++++++++++-- src/backends/redis/backend_redis.hpp | 3 ++- src/backends/redis/command.cpp | 4 +--- src/backends/redis/command.hpp | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 1cf5e32..1c28f15 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -29,6 +29,7 @@ namespace dindb { struct RedisConnectionSettings { std::string address; uint16_t port; + uint16_t database; }; } //unnamed namespace } //namespace dindb @@ -40,6 +41,7 @@ namespace YAML { Node node; node["address"] = parSettings.address; node["port"] = parSettings.port; + node["database"] = parSettings.database; return node; } @@ -50,22 +52,33 @@ namespace YAML { parSettings.address = parNode["address"].as(); parSettings.port = parNode["port"].as(); + if (parNode["database"]) + parSettings.database = parNode["database"].as(); return true; } }; } //namespace YAML namespace dindb { - BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, bool parConnect) : - m_redis(std::move(parAddress), parPort, parConnect) + BackendRedis::BackendRedis(std::string &&parAddress, uint16_t parPort, uint16_t parDatabase, bool parConnect) : + m_redis(std::move(parAddress), parPort), + m_database(parDatabase) { + if (parConnect) + this->connect(); } BackendRedis::~BackendRedis() noexcept { } void BackendRedis::connect() { + using boost::lexical_cast; + m_redis.connect(); + if (m_redis.is_connected() and m_database > 0) { + const std::string command = "SELECT " + lexical_cast(m_database); + m_redis.run(command.c_str()); + } } void BackendRedis::disconnect() { @@ -146,6 +159,7 @@ extern "C" dindb::Backend* dindexer_create_backend (const YAML::Node* parConfig) return new dindb::BackendRedis( std::move(config.address), config.port, + config.database, true ); } diff --git a/src/backends/redis/backend_redis.hpp b/src/backends/redis/backend_redis.hpp index 1e32ba9..2958694 100644 --- a/src/backends/redis/backend_redis.hpp +++ b/src/backends/redis/backend_redis.hpp @@ -27,7 +27,7 @@ namespace dindb { class BackendRedis : public Backend { public: BackendRedis ( BackendRedis&& ) = default; - BackendRedis ( std::string&& parAddress, uint16_t parPort, bool parConnect ); + BackendRedis ( std::string&& parAddress, uint16_t parPort, uint16_t parDatabase, bool parConnect ); virtual ~BackendRedis ( void ) noexcept; virtual void connect ( void ) override; @@ -57,6 +57,7 @@ namespace dindb { private: redis::Command m_redis; + uint16_t m_database; }; } //namespace dindb diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index f2b9e82..f3efb90 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -61,13 +61,11 @@ namespace redis { return boost::get>(parReply); } - Command::Command (std::string&& parAddress, uint16_t parPort, bool parConnect) : + Command::Command (std::string&& parAddress, uint16_t parPort) : m_conn(nullptr, &redisFree), m_address(std::move(parAddress)), m_port(parPort) { - if (parConnect) - this->connect(); } Command::~Command() noexcept { diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index dfdcc5b..025780d 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -60,7 +60,7 @@ namespace redis { class Command { public: - Command ( std::string&& parAddress, uint16_t parPort, bool parConnect ); + Command ( std::string&& parAddress, uint16_t parPort ); ~Command ( void ) noexcept; void connect ( void ); From c1e79c435b4ab74ea14c001f28fdcaba56f62275 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 10 Jun 2016 20:33:11 +0200 Subject: [PATCH 044/170] New ScanIterator class. Not yet tested and only supporting the SCAN command for now, more to come. Also includes some refactoring that was needed to make everything work. --- include/helpers/has_method.hpp | 54 +++++++++++++++ src/backends/redis/CMakeLists.txt | 2 + src/backends/redis/backend_redis.cpp | 3 + src/backends/redis/command.cpp | 17 ++--- src/backends/redis/command.hpp | 44 +++---------- src/backends/redis/reply.cpp | 52 +++++++++++++++ src/backends/redis/reply.hpp | 60 +++++++++++++++++ src/backends/redis/scan_iterator.cpp | 46 +++++++++++++ src/backends/redis/scan_iterator.hpp | 95 +++++++++++++++++++++++++++ src/backends/redis/scan_iterator.inl | 98 ++++++++++++++++++++++++++++ 10 files changed, 423 insertions(+), 48 deletions(-) create mode 100644 include/helpers/has_method.hpp create mode 100644 src/backends/redis/reply.cpp create mode 100644 src/backends/redis/reply.hpp create mode 100644 src/backends/redis/scan_iterator.cpp create mode 100644 src/backends/redis/scan_iterator.hpp create mode 100644 src/backends/redis/scan_iterator.inl diff --git a/include/helpers/has_method.hpp b/include/helpers/has_method.hpp new file mode 100644 index 0000000..d641771 --- /dev/null +++ b/include/helpers/has_method.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Michele "King_DuckZ" Santullo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef idFBC29C5127784D35BE62F7BAC16E3687 +#define idFBC29C5127784D35BE62F7BAC16E3687 + +#define define_has_method(method_name,pretty_name) \ + template \ + struct Has ## pretty_name ## Method { \ + private: \ + struct TrueType { int a[2]; }; \ + typedef int FalseType; \ + template static TrueType has_method ( decltype(&C::method_name) ); \ + template static FalseType has_method ( ... ); \ + public: \ + enum { value = sizeof(has_method(0)) == sizeof(TrueType) }; \ + } +#define define_has_typedef(typedef_name,pretty_name) \ + template \ + struct Has ## pretty_name ## Typedef { \ + private: \ + struct TrueType { int a[2]; }; \ + typedef int FalseType; \ + template static TrueType has_typedef ( const typename C::typedef_name* ); \ + template static FalseType has_typedef ( ... ); \ + public: \ + enum { value = sizeof(has_typedef(nullptr)) == sizeof(TrueType) }; \ + } +#define define_has_enum(enum_name,pretty_name) \ + template \ + struct Has ## pretty_name ## Enum { \ + private: \ + struct TrueType { int a[2]; }; \ + typedef int FalseType; \ + template static TrueType has_enum ( decltype(C::enum_name)* ); \ + template static FalseType has_enum ( ... ); \ + public:\ + enum { value = sizeof(has_enum(nullptr)) == sizeof(TrueType) }; \ + } + +#endif diff --git a/src/backends/redis/CMakeLists.txt b/src/backends/redis/CMakeLists.txt index 8a614df..6683d00 100644 --- a/src/backends/redis/CMakeLists.txt +++ b/src/backends/redis/CMakeLists.txt @@ -5,6 +5,8 @@ find_package(hiredis 0.11.0 REQUIRED) add_library(${PROJECT_NAME} SHARED backend_redis.cpp command.cpp + scan_iterator.cpp + reply.cpp ) target_include_directories(${PROJECT_NAME} SYSTEM diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 1c28f15..00adefe 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -89,6 +89,9 @@ namespace dindb { } void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + for (const auto& file_path : m_redis.scan()) { + std::cout << file_path << '\n'; + } } void BackendRedis::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index f3efb90..f2de461 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -23,7 +23,6 @@ #include #include #include -#include namespace redis { namespace { @@ -49,18 +48,6 @@ namespace redis { } } //unnamed namespace - long long get_integer (const RedisReplyType& parReply) { - return boost::get(parReply); - } - - std::string get_string (const RedisReplyType& parReply) { - return boost::get(parReply); - } - - std::vector get_array (const RedisReplyType& parReply) { - return boost::get>(parReply); - } - Command::Command (std::string&& parAddress, uint16_t parPort) : m_conn(nullptr, &redisFree), m_address(std::move(parAddress)), @@ -138,4 +125,8 @@ namespace redis { bool Command::is_connected() const { return m_conn and not m_conn->err; } + + auto Command::scan() -> scan_range { + return scan_range(scan_iterator(this, false), scan_iterator(this, true)); + } } //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 025780d..0dbb3aa 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -19,47 +19,26 @@ #define idD83EEBFC927840C6B9F32D61A1D1E582 #include "arg_to_bin_safe.hpp" +#include "scan_iterator.hpp" +#include "reply.hpp" #include #include #include #include #include #include -#include -#include #include #include +#include struct redisContext; namespace redis { - class RedisReplyType; - - namespace implem { - using RedisVariantType = boost::variant< - long long, - std::string, - boost::recursive_wrapper> - >; - enum RedisVariantTypes { - RedisVariantType_Integer = 0, - RedisVariantType_String, - RedisVariantType_Array - }; - } //namespace implem - - struct RedisReplyType : implem::RedisVariantType { - using base_class = implem::RedisVariantType; - - RedisReplyType ( void ) = default; - RedisReplyType ( long long parVal ) : base_class(parVal) {} - RedisReplyType ( std::string&& parVal ) : base_class(std::move(parVal)) {} - RedisReplyType ( std::vector&& parVal ) : base_class(std::move(parVal)) {} - ~RedisReplyType ( void ) noexcept = default; - }; - class Command { public: + typedef ScanIterator> scan_iterator; + typedef boost::iterator_range scan_range; + Command ( std::string&& parAddress, uint16_t parPort ); ~Command ( void ) noexcept; @@ -71,6 +50,9 @@ namespace redis { template RedisReplyType run ( const char* parCommand, Args&&... parArgs ); + //Single Redis command wrappers + scan_range scan ( void ); + private: using RedisConnection = std::unique_ptr; @@ -87,10 +69,6 @@ namespace redis { using CharPointerArray = std::array; using LengthArray = std::array; - CharPointerArray arguments; - LengthArray lengths; - assert(false); //TODO write implementation - return this->run_pvt( parCommand, static_cast(arg_count), @@ -98,10 +76,6 @@ namespace redis { LengthArray{ implem::arg_to_bin_safe_length(std::forward(parArgs))... }.data() ); } - - long long get_integer ( const RedisReplyType& parReply ); - std::string get_string ( const RedisReplyType& parReply ); - std::vector get_array ( const RedisReplyType& parReply ); } //namespace redis #endif diff --git a/src/backends/redis/reply.cpp b/src/backends/redis/reply.cpp new file mode 100644 index 0000000..6020d71 --- /dev/null +++ b/src/backends/redis/reply.cpp @@ -0,0 +1,52 @@ +/* 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 "reply.hpp" +#include + +namespace redis { + const long long& get_integer (const RedisReplyType& parReply) { + return boost::get(parReply); + } + + const std::string& get_string (const RedisReplyType& parReply) { + return boost::get(parReply); + } + + const std::vector& get_array (const RedisReplyType& parReply) { + return boost::get>(parReply); + } + + template <> + const std::string& get (const RedisReplyType& parReply) { + return get_string(parReply); + } + + template <> + const std::vector& get> (const RedisReplyType& parReply) { + return get_array(parReply); + } + + template <> + const long long& get (const RedisReplyType& parReply) { + return get_integer(parReply); + } + + template const std::string& get ( const RedisReplyType& parReply ); + template const std::vector& get> ( const RedisReplyType& parReply ); + template const long long& get ( const RedisReplyType& parReply ); +} //namespace redis diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp new file mode 100644 index 0000000..eb9469f --- /dev/null +++ b/src/backends/redis/reply.hpp @@ -0,0 +1,60 @@ +/* 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 id93FA96E3071745D9A1E45D4D29B9F7D0 +#define id93FA96E3071745D9A1E45D4D29B9F7D0 + +#include +#include +#include + +namespace redis { + class RedisReplyType; + + namespace implem { + using RedisVariantType = boost::variant< + long long, + std::string, + boost::recursive_wrapper> + >; + enum RedisVariantTypes { + RedisVariantType_Integer = 0, + RedisVariantType_String, + RedisVariantType_Array, + RedisVariantType_Bool + }; + } //namespace implem + + struct RedisReplyType : implem::RedisVariantType { + using base_class = implem::RedisVariantType; + + RedisReplyType ( void ) = default; + RedisReplyType ( long long parVal ) : base_class(parVal) {} + RedisReplyType ( std::string&& parVal ) : base_class(std::move(parVal)) {} + RedisReplyType ( std::vector&& parVal ) : base_class(std::move(parVal)) {} + ~RedisReplyType ( void ) noexcept = default; + }; + + const long long& get_integer ( const RedisReplyType& parReply ); + const std::string& get_string ( const RedisReplyType& parReply ); + const std::vector& get_array ( const RedisReplyType& parReply ); + + template + const T& get ( const RedisReplyType& parReply ); +} //namespace redis + +#endif diff --git a/src/backends/redis/scan_iterator.cpp b/src/backends/redis/scan_iterator.cpp new file mode 100644 index 0000000..00736a5 --- /dev/null +++ b/src/backends/redis/scan_iterator.cpp @@ -0,0 +1,46 @@ +/* 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 "scan_iterator.hpp" +#include "command.hpp" +#include +#include +#include +#include + +namespace redis { + namespace implem { + ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand) : + m_command(parCommand) + { + assert(m_command); + assert(m_command->is_connected()); + } + + bool ScanIteratorBaseClass::is_connected() const { + return m_command and m_command->is_connected(); + } + + RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext) { + return m_command->run(parCommand, boost::lexical_cast(parScanContext)); + } + + RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, const std::string& parParameter, long long parScanContext) { + return m_command->run(parCommand, parParameter, boost::lexical_cast(parScanContext)); + } + } //namespace implem +} //namespace redis diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp new file mode 100644 index 0000000..98bcb52 --- /dev/null +++ b/src/backends/redis/scan_iterator.hpp @@ -0,0 +1,95 @@ +/* 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 id774125B851514A26BD7C2AD1D804D732 +#define id774125B851514A26BD7C2AD1D804D732 + +#include "reply.hpp" +#include "helpers/has_method.hpp" +#include +#include +#include +#include + +namespace redis { + template + class ScanIterator; + + class Command; + + namespace implem { + template + using ScanIteratorBaseIterator = boost::iterator_facade, const V, boost::forward_traversal_tag>; + + class ScanIteratorBaseClass { + protected: + explicit ScanIteratorBaseClass ( Command* parCommand ); + ~ScanIteratorBaseClass ( void ) noexcept = default; + + bool is_connected ( void ) const; + RedisReplyType run ( const char* parCommand, long long parScanContext ); + RedisReplyType run ( const char* parCommand, const std::string& parParameter, long long parScanContext ); + + bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; } + + private: + Command* m_command; + }; + } //namespace implem + + template + class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator { + friend class boost::iterator_core_access; + typedef implem::ScanIteratorBaseIterator base_iterator; + public: + typedef typename base_iterator::difference_type difference_type; + typedef typename base_iterator::value_type value_type; + typedef typename base_iterator::pointer pointer; + typedef typename base_iterator::reference reference; + typedef typename base_iterator::iterator_category iterator_category; + + ScanIterator ( Command* parCommand, bool parEnd ); + + private: + define_has_method(scan_target, ScanTarget); + + template + RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); + template + RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); + + void increment ( void ); + bool equal ( const ScanIterator& parOther ) const; + const V& dereference ( void ) const; + + std::vector m_reply; + long long m_scan_context; + std::size_t m_curr_index; + }; + + template + struct ScanSingleValues { + static constexpr const char* command ( void ) { return "SCAN"; } + static constexpr const std::size_t step = 1; + + static const T& make_value ( const RedisReplyType* parItem ); + }; +} //namespace redis + +#include "scan_iterator.inl" + +#endif diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl new file mode 100644 index 0000000..ea7f7f3 --- /dev/null +++ b/src/backends/redis/scan_iterator.inl @@ -0,0 +1,98 @@ +/* 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 "command.hpp" +#include +#include + +namespace redis { + namespace implem { + } //namespace implem + + template + ScanIterator::ScanIterator (Command* parCommand, bool parEnd) : + implem::ScanIteratorBaseClass(parCommand), + m_reply(), + m_scan_context(0), + m_curr_index(0) + { + if (not parEnd) + this->increment(); + } + + template + void ScanIterator::increment() { + static_assert(ValueFetch::step > 0, "Can't have an increase step of 0"); + if (m_curr_index + ValueFetch::step < m_reply.size()) { + m_curr_index += ValueFetch::step; + } + else { + std::vector array_reply; + long long new_context; + + do { + auto whole_reply = this->forward_scan_command(0); + + array_reply = get_array(whole_reply); + assert(2 == array_reply.size()); + assert(array_reply.size() % ValueFetch::step == 0); + new_context = get_integer(array_reply[0]); + } while (new_context and array_reply.empty()); + + m_reply = get_array(array_reply[1]); + m_scan_context = new_context; + m_curr_index = 0; + } + } + + template + bool ScanIterator::equal (const ScanIterator& parOther) const { + return + (&parOther == this) or + ( + implem::ScanIteratorBaseClass::is_equal(parOther) and + (m_scan_context == parOther.m_scan_context) + ); + } + + template + const V& ScanIterator::dereference() const { + assert(m_scan_context); + assert(not m_reply.empty()); + assert(m_curr_index < m_reply.size()); + + return ValueFetch::make_value(m_reply.data() + m_curr_index); + } + + template + template + RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context); + } + + template + template + RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context); + } + + template + const T& ScanSingleValues::make_value (const RedisReplyType* parItem) { + assert(parItem); + return get(*parItem); + } +} //namespace redis From e0a82cce2dbec1304c363497c1aa06c881b35eb7 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 10:57:42 +0100 Subject: [PATCH 045/170] Fix SCAN iteration. --- src/backends/redis/backend_redis.cpp | 4 +++- src/backends/redis/command.cpp | 4 ++-- src/backends/redis/command.hpp | 12 +++++++----- src/backends/redis/reply.cpp | 16 ++++++++++++++++ src/backends/redis/reply.hpp | 1 + src/backends/redis/scan_iterator.hpp | 1 + src/backends/redis/scan_iterator.inl | 28 ++++++++++++++++++++++++---- 7 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 00adefe..ffdd57c 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -54,6 +54,8 @@ namespace YAML { parSettings.port = parNode["port"].as(); if (parNode["database"]) parSettings.database = parNode["database"].as(); + else + parSettings.database = 0; return true; } }; @@ -90,7 +92,7 @@ namespace dindb { void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { for (const auto& file_path : m_redis.scan()) { - std::cout << file_path << '\n'; + //std::cout << file_path << '\n'; } } diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index f2de461..d4a58d0 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -84,8 +84,8 @@ namespace redis { m_conn.reset(); } - RedisReplyType Command::run_pvt (const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths) { - assert(parCommand); + RedisReplyType Command::run_pvt (int parArgc, const char** parArgv, std::size_t* parLengths) { + assert(parArgc >= 1); assert(parArgv); assert(parLengths); //This /could/ be null, but I don't see why it should assert(is_connected()); diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 0dbb3aa..9b6e3e4 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -56,7 +56,7 @@ namespace redis { private: using RedisConnection = std::unique_ptr; - RedisReplyType run_pvt ( const char* parCommand, int parArgc, const char** parArgv, std::size_t* parLengths ); + RedisReplyType run_pvt ( int parArgc, const char** parArgv, std::size_t* parLengths ); RedisConnection m_conn; std::string m_address; @@ -65,15 +65,17 @@ namespace redis { template RedisReplyType Command::run (const char* parCommand, Args&&... parArgs) { - constexpr const std::size_t arg_count = sizeof...(Args); + constexpr const std::size_t arg_count = sizeof...(Args) + 1; using CharPointerArray = std::array; using LengthArray = std::array; + using implem::arg_to_bin_safe_char; + using implem::arg_to_bin_safe_length; + using boost::string_ref; return this->run_pvt( - parCommand, static_cast(arg_count), - CharPointerArray{ implem::arg_to_bin_safe_char(std::forward(parArgs))... }.data(), - LengthArray{ implem::arg_to_bin_safe_length(std::forward(parArgs))... }.data() + CharPointerArray{ arg_to_bin_safe_char(string_ref(parCommand)), arg_to_bin_safe_char(std::forward(parArgs))... }.data(), + LengthArray{ arg_to_bin_safe_length(string_ref(parCommand)), arg_to_bin_safe_length(std::forward(parArgs))... }.data() ); } } //namespace redis diff --git a/src/backends/redis/reply.cpp b/src/backends/redis/reply.cpp index 6020d71..34789ef 100644 --- a/src/backends/redis/reply.cpp +++ b/src/backends/redis/reply.cpp @@ -17,6 +17,7 @@ #include "reply.hpp" #include +#include namespace redis { const long long& get_integer (const RedisReplyType& parReply) { @@ -27,6 +28,21 @@ namespace redis { return boost::get(parReply); } + long long get_integer_autoconv_if_str (const RedisReplyType &parReply) { + using boost::lexical_cast; + + const auto type = parReply.which(); + switch (type) { + case implem::RedisVariantType_Integer: + return get_integer(parReply); + case implem::RedisVariantType_String: + return lexical_cast(get_string(parReply)); + default: + assert(false); + return 0; + } + } + const std::vector& get_array (const RedisReplyType& parReply) { return boost::get>(parReply); } diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index eb9469f..db2ccf8 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -50,6 +50,7 @@ namespace redis { }; const long long& get_integer ( const RedisReplyType& parReply ); + long long get_integer_autoconv_if_str ( const RedisReplyType& parReply ); const std::string& get_string ( const RedisReplyType& parReply ); const std::vector& get_array ( const RedisReplyType& parReply ); diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index 98bcb52..ee0946a 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -71,6 +71,7 @@ namespace redis { RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); template RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); + bool is_end ( void ) const; void increment ( void ); bool equal ( const ScanIterator& parOther ) const; diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index ea7f7f3..51b7466 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -30,16 +30,33 @@ namespace redis { m_scan_context(0), m_curr_index(0) { - if (not parEnd) + if (not parEnd) { + m_curr_index = 1; //Some arbitrary value so is_end()==false + assert(not is_end()); this->increment(); + } + else { + assert(is_end()); + } + } + + template + bool ScanIterator::is_end() const { + return not m_curr_index and m_reply.empty() and not m_scan_context; } template void ScanIterator::increment() { + assert(not is_end()); static_assert(ValueFetch::step > 0, "Can't have an increase step of 0"); + if (m_curr_index + ValueFetch::step < m_reply.size()) { m_curr_index += ValueFetch::step; } + else if (m_curr_index + ValueFetch::step == m_reply.size() and not m_scan_context) { + m_reply.clear(); + m_curr_index = 0; + } else { std::vector array_reply; long long new_context; @@ -50,7 +67,7 @@ namespace redis { array_reply = get_array(whole_reply); assert(2 == array_reply.size()); assert(array_reply.size() % ValueFetch::step == 0); - new_context = get_integer(array_reply[0]); + new_context = get_integer_autoconv_if_str(array_reply[0]); } while (new_context and array_reply.empty()); m_reply = get_array(array_reply[1]); @@ -63,15 +80,18 @@ namespace redis { bool ScanIterator::equal (const ScanIterator& parOther) const { return (&parOther == this) or + (is_end() and parOther.is_end()) or ( + not (is_end() or parOther.is_end()) and implem::ScanIteratorBaseClass::is_equal(parOther) and - (m_scan_context == parOther.m_scan_context) + (m_scan_context == parOther.m_scan_context) and + (m_curr_index == parOther.m_curr_index) and + (m_reply.size() == parOther.m_reply.size()) ); } template const V& ScanIterator::dereference() const { - assert(m_scan_context); assert(not m_reply.empty()); assert(m_curr_index < m_reply.size()); From c7eeddabf1b28116f8fbf5ade1a3b46527b6a0d1 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 15:14:10 +0100 Subject: [PATCH 046/170] Implement HSCAN Redis command. --- src/backends/redis/command.cpp | 4 +++ src/backends/redis/command.hpp | 4 +++ src/backends/redis/scan_iterator.cpp | 2 +- src/backends/redis/scan_iterator.hpp | 29 +++++++++++++--- src/backends/redis/scan_iterator.inl | 52 +++++++++++++++++++++++++--- 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index d4a58d0..171d9c7 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -129,4 +129,8 @@ namespace redis { auto Command::scan() -> scan_range { return scan_range(scan_iterator(this, false), scan_iterator(this, true)); } + + auto Command::hscan (boost::string_ref parKey) -> hscan_range { + return hscan_range(hscan_iterator(this, parKey, false), hscan_iterator(this, parKey, true)); + } } //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 9b6e3e4..ca22514 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -30,6 +30,7 @@ #include #include #include +#include struct redisContext; @@ -38,6 +39,8 @@ namespace redis { public: typedef ScanIterator> scan_iterator; typedef boost::iterator_range scan_range; + typedef ScanIterator, ScanPairs>> hscan_iterator; + typedef boost::iterator_range hscan_range; Command ( std::string&& parAddress, uint16_t parPort ); ~Command ( void ) noexcept; @@ -52,6 +55,7 @@ namespace redis { //Single Redis command wrappers scan_range scan ( void ); + hscan_range hscan ( boost::string_ref parKey ); private: using RedisConnection = std::unique_ptr; diff --git a/src/backends/redis/scan_iterator.cpp b/src/backends/redis/scan_iterator.cpp index 00736a5..f8dbeaa 100644 --- a/src/backends/redis/scan_iterator.cpp +++ b/src/backends/redis/scan_iterator.cpp @@ -39,7 +39,7 @@ namespace redis { return m_command->run(parCommand, boost::lexical_cast(parScanContext)); } - RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, const std::string& parParameter, long long parScanContext) { + RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext) { return m_command->run(parCommand, parParameter, boost::lexical_cast(parScanContext)); } } //namespace implem diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index ee0946a..e98dbcc 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace redis { template @@ -42,7 +43,7 @@ namespace redis { bool is_connected ( void ) const; RedisReplyType run ( const char* parCommand, long long parScanContext ); - RedisReplyType run ( const char* parCommand, const std::string& parParameter, long long parScanContext ); + RedisReplyType run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext ); bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; } @@ -52,9 +53,10 @@ namespace redis { } //namespace implem template - class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator { + class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator, private ValueFetch { friend class boost::iterator_core_access; typedef implem::ScanIteratorBaseIterator base_iterator; + define_has_method(scan_target, ScanTarget); public: typedef typename base_iterator::difference_type difference_type; typedef typename base_iterator::value_type value_type; @@ -62,11 +64,12 @@ namespace redis { typedef typename base_iterator::reference reference; typedef typename base_iterator::iterator_category iterator_category; + template ::value>::type> ScanIterator ( Command* parCommand, bool parEnd ); + template ::value>::type> + ScanIterator ( Command* parCommand, boost::string_ref parKey, bool parEnd ); private: - define_has_method(scan_target, ScanTarget); - template RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); template @@ -77,7 +80,7 @@ namespace redis { bool equal ( const ScanIterator& parOther ) const; const V& dereference ( void ) const; - std::vector m_reply; + std::vector m_reply; long long m_scan_context; std::size_t m_curr_index; }; @@ -89,6 +92,22 @@ namespace redis { static const T& make_value ( const RedisReplyType* parItem ); }; + + template + struct ScanPairs { + typedef P PairType; + + explicit ScanPairs ( boost::string_ref parScanTarget ) : m_scan_target(parScanTarget) {} + + static constexpr const char* command ( void ) { return "HSCAN"; } + static constexpr const std::size_t step = 2; + + static PairType make_value ( const RedisReplyType* parItem ); + boost::string_ref scan_target ( void ); + + private: + boost::string_ref m_scan_target; + }; } //namespace redis #include "scan_iterator.inl" diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index 51b7466..3427948 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -24,8 +24,31 @@ namespace redis { } //namespace implem template + template ScanIterator::ScanIterator (Command* parCommand, bool parEnd) : implem::ScanIteratorBaseClass(parCommand), + implem::ScanIteratorBaseIterator(), + ValueFetch(), + m_reply(), + m_scan_context(0), + m_curr_index(0) + { + if (not parEnd) { + m_curr_index = 1; //Some arbitrary value so is_end()==false + assert(not is_end()); + this->increment(); + } + else { + assert(is_end()); + } + } + + template + template + ScanIterator::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd) : + implem::ScanIteratorBaseClass(parCommand), + implem::ScanIteratorBaseIterator(), + ValueFetch(parKey), m_reply(), m_scan_context(0), m_curr_index(0) @@ -50,10 +73,10 @@ namespace redis { assert(not is_end()); static_assert(ValueFetch::step > 0, "Can't have an increase step of 0"); - if (m_curr_index + ValueFetch::step < m_reply.size()) { - m_curr_index += ValueFetch::step; + if (m_curr_index + 1 < m_reply.size()) { + ++m_curr_index; } - else if (m_curr_index + ValueFetch::step == m_reply.size() and not m_scan_context) { + else if (m_curr_index + 1 == m_reply.size() and not m_scan_context) { m_reply.clear(); m_curr_index = 0; } @@ -70,7 +93,15 @@ namespace redis { new_context = get_integer_autoconv_if_str(array_reply[0]); } while (new_context and array_reply.empty()); - m_reply = get_array(array_reply[1]); + const auto variant_array = get_array(array_reply[1]); + assert(variant_array.size() % ValueFetch::step == 0); + const std::size_t expected_reply_count = variant_array.size() / ValueFetch::step; + m_reply.clear(); + m_reply.reserve(expected_reply_count); + for (std::size_t z = 0; z < variant_array.size(); z += ValueFetch::step) { + m_reply.push_back(ValueFetch::make_value(variant_array.data() + z)); + } + assert(expected_reply_count == m_reply.size()); m_scan_context = new_context; m_curr_index = 0; } @@ -95,7 +126,7 @@ namespace redis { assert(not m_reply.empty()); assert(m_curr_index < m_reply.size()); - return ValueFetch::make_value(m_reply.data() + m_curr_index); + return m_reply[m_curr_index]; } template @@ -115,4 +146,15 @@ namespace redis { assert(parItem); return get(*parItem); } + + template + P ScanPairs::make_value (const RedisReplyType* parItem) { + assert(parItem); + return PairType(get(parItem[0]), get(parItem[1])); + } + + template + boost::string_ref ScanPairs::scan_target() { + return m_scan_target; + } } //namespace redis From 731582d8fe613f823f9f8523f14cfe17463f9ae4 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 15:24:26 +0100 Subject: [PATCH 047/170] Move V into ValueFetch. No need to explicitly specify the dereferenced type directly to the scan iterator anymore. --- src/backends/redis/command.hpp | 4 +-- src/backends/redis/scan_iterator.hpp | 20 +++++++------ src/backends/redis/scan_iterator.inl | 42 ++++++++++++++-------------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index ca22514..d4e1ce6 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -37,9 +37,9 @@ struct redisContext; namespace redis { class Command { public: - typedef ScanIterator> scan_iterator; + typedef ScanIterator> scan_iterator; typedef boost::iterator_range scan_range; - typedef ScanIterator, ScanPairs>> hscan_iterator; + typedef ScanIterator>> hscan_iterator; typedef boost::iterator_range hscan_range; Command ( std::string&& parAddress, uint16_t parPort ); diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index e98dbcc..3c24139 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -27,14 +27,14 @@ #include namespace redis { - template + template class ScanIterator; class Command; namespace implem { - template - using ScanIteratorBaseIterator = boost::iterator_facade, const V, boost::forward_traversal_tag>; + template + using ScanIteratorBaseIterator = boost::iterator_facade, const typename ValueFetch::value_type, boost::forward_traversal_tag>; class ScanIteratorBaseClass { protected: @@ -52,10 +52,10 @@ namespace redis { }; } //namespace implem - template - class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator, private ValueFetch { + template + class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator, private ValueFetch { friend class boost::iterator_core_access; - typedef implem::ScanIteratorBaseIterator base_iterator; + typedef implem::ScanIteratorBaseIterator base_iterator; define_has_method(scan_target, ScanTarget); public: typedef typename base_iterator::difference_type difference_type; @@ -78,7 +78,7 @@ namespace redis { void increment ( void ); bool equal ( const ScanIterator& parOther ) const; - const V& dereference ( void ) const; + const value_type& dereference ( void ) const; std::vector m_reply; long long m_scan_context; @@ -87,6 +87,8 @@ namespace redis { template struct ScanSingleValues { + typedef T value_type; + static constexpr const char* command ( void ) { return "SCAN"; } static constexpr const std::size_t step = 1; @@ -95,14 +97,14 @@ namespace redis { template struct ScanPairs { - typedef P PairType; + typedef P value_type; explicit ScanPairs ( boost::string_ref parScanTarget ) : m_scan_target(parScanTarget) {} static constexpr const char* command ( void ) { return "HSCAN"; } static constexpr const std::size_t step = 2; - static PairType make_value ( const RedisReplyType* parItem ); + static value_type make_value ( const RedisReplyType* parItem ); boost::string_ref scan_target ( void ); private: diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index 3427948..fa75eff 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -23,11 +23,11 @@ namespace redis { namespace implem { } //namespace implem - template + template template - ScanIterator::ScanIterator (Command* parCommand, bool parEnd) : + ScanIterator::ScanIterator (Command* parCommand, bool parEnd) : implem::ScanIteratorBaseClass(parCommand), - implem::ScanIteratorBaseIterator(), + implem::ScanIteratorBaseIterator(), ValueFetch(), m_reply(), m_scan_context(0), @@ -43,11 +43,11 @@ namespace redis { } } - template + template template - ScanIterator::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd) : + ScanIterator::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd) : implem::ScanIteratorBaseClass(parCommand), - implem::ScanIteratorBaseIterator(), + implem::ScanIteratorBaseIterator(), ValueFetch(parKey), m_reply(), m_scan_context(0), @@ -63,13 +63,13 @@ namespace redis { } } - template - bool ScanIterator::is_end() const { + template + bool ScanIterator::is_end() const { return not m_curr_index and m_reply.empty() and not m_scan_context; } - template - void ScanIterator::increment() { + template + void ScanIterator::increment() { assert(not is_end()); static_assert(ValueFetch::step > 0, "Can't have an increase step of 0"); @@ -107,8 +107,8 @@ namespace redis { } } - template - bool ScanIterator::equal (const ScanIterator& parOther) const { + template + bool ScanIterator::equal (const ScanIterator& parOther) const { return (&parOther == this) or (is_end() and parOther.is_end()) or @@ -121,36 +121,36 @@ namespace redis { ); } - template - const V& ScanIterator::dereference() const { + template + auto ScanIterator::dereference() const -> const value_type& { assert(not m_reply.empty()); assert(m_curr_index < m_reply.size()); return m_reply[m_curr_index]; } - template + template template - RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context); } - template + template template - RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context); } template - const T& ScanSingleValues::make_value (const RedisReplyType* parItem) { + auto ScanSingleValues::make_value (const RedisReplyType* parItem) -> const value_type& { assert(parItem); return get(*parItem); } template - P ScanPairs::make_value (const RedisReplyType* parItem) { + auto ScanPairs::make_value (const RedisReplyType* parItem) -> value_type { assert(parItem); - return PairType(get(parItem[0]), get(parItem[1])); + return value_type(get(parItem[0]), get(parItem[1])); } template From 9949c273a1a7b9fc884122b83c56faed030d3259 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 15:38:18 +0100 Subject: [PATCH 048/170] Implement SSCAN Redis command. --- src/backends/redis/command.cpp | 4 ++++ src/backends/redis/command.hpp | 3 +++ src/backends/redis/scan_iterator.hpp | 18 +++++++++++++++++- src/backends/redis/scan_iterator.inl | 11 ++++++----- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index 171d9c7..7445b61 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -133,4 +133,8 @@ namespace redis { auto Command::hscan (boost::string_ref parKey) -> hscan_range { return hscan_range(hscan_iterator(this, parKey, false), hscan_iterator(this, parKey, true)); } + + auto Command::sscan (boost::string_ref parKey) -> sscan_range { + return sscan_range(sscan_iterator(this, parKey, false), sscan_iterator(this, parKey, true)); + } } //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index d4e1ce6..1b3e840 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -41,6 +41,8 @@ namespace redis { typedef boost::iterator_range scan_range; typedef ScanIterator>> hscan_iterator; typedef boost::iterator_range hscan_range; + typedef ScanIterator> sscan_iterator; + typedef boost::iterator_range sscan_range; Command ( std::string&& parAddress, uint16_t parPort ); ~Command ( void ) noexcept; @@ -56,6 +58,7 @@ namespace redis { //Single Redis command wrappers scan_range scan ( void ); hscan_range hscan ( boost::string_ref parKey ); + sscan_range sscan ( boost::string_ref parKey ); private: using RedisConnection = std::unique_ptr; diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index 3c24139..f0f5231 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -95,6 +95,22 @@ namespace redis { static const T& make_value ( const RedisReplyType* parItem ); }; + template + struct ScanSingleValuesInKey { + typedef T value_type; + + explicit ScanSingleValuesInKey ( boost::string_ref parScanTarget ) : m_scan_target(parScanTarget) {} + + static constexpr const char* command ( void ) { return "SSCAN"; } + static constexpr const std::size_t step = 1; + + static const T& make_value ( const RedisReplyType* parItem ); + boost::string_ref scan_target ( void ) const { return m_scan_target; } + + private: + boost::string_ref m_scan_target; + }; + template struct ScanPairs { typedef P value_type; @@ -105,7 +121,7 @@ namespace redis { static constexpr const std::size_t step = 2; static value_type make_value ( const RedisReplyType* parItem ); - boost::string_ref scan_target ( void ); + boost::string_ref scan_target ( void ) const { return m_scan_target; } private: boost::string_ref m_scan_target; diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index fa75eff..5ef01c8 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -147,14 +147,15 @@ namespace redis { return get(*parItem); } + template + auto ScanSingleValuesInKey::make_value (const RedisReplyType* parItem) -> const value_type& { + assert(parItem); + return get(*parItem); + } + template auto ScanPairs::make_value (const RedisReplyType* parItem) -> value_type { assert(parItem); return value_type(get(parItem[0]), get(parItem[1])); } - - template - boost::string_ref ScanPairs::scan_target() { - return m_scan_target; - } } //namespace redis From 78eee0e16f48a87a382793441328ffaed9e6ee6a Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 16:20:31 +0100 Subject: [PATCH 049/170] Make the scan command in ScanPairs a template parameter. --- src/backends/redis/CMakeLists.txt | 1 + src/backends/redis/command.hpp | 2 +- src/backends/redis/scan_iterator.hpp | 10 ++++++++-- src/backends/redis/scan_iterator.inl | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/backends/redis/CMakeLists.txt b/src/backends/redis/CMakeLists.txt index 6683d00..f268708 100644 --- a/src/backends/redis/CMakeLists.txt +++ b/src/backends/redis/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(${PROJECT_NAME} SHARED target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS} PRIVATE ${HIREDIS_INCLUDE_DIRS} + PRIVATE ${CMAKE_SOURCE_DIR}/lib/better-enums ) target_link_libraries(${PROJECT_NAME} diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 1b3e840..51bedd1 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -39,7 +39,7 @@ namespace redis { public: typedef ScanIterator> scan_iterator; typedef boost::iterator_range scan_range; - typedef ScanIterator>> hscan_iterator; + typedef ScanIterator, ScanCommands::HSCAN>> hscan_iterator; typedef boost::iterator_range hscan_range; typedef ScanIterator> sscan_iterator; typedef boost::iterator_range sscan_range; diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index f0f5231..0042b1e 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -20,6 +20,7 @@ #include "reply.hpp" #include "helpers/has_method.hpp" +#include "enum.h" #include #include #include @@ -52,6 +53,10 @@ namespace redis { }; } //namespace implem + BETTER_ENUM(ScanCommands, char, + SCAN, SSCAN, ZSCAN, HSCAN + ); + template class ScanIterator : private implem::ScanIteratorBaseClass, public implem::ScanIteratorBaseIterator, private ValueFetch { friend class boost::iterator_core_access; @@ -111,13 +116,14 @@ namespace redis { boost::string_ref m_scan_target; }; - template + template struct ScanPairs { + static_assert(Command == ScanCommands::HSCAN or Command == ScanCommands::ZSCAN, "Invalid scan command chosen"); typedef P value_type; explicit ScanPairs ( boost::string_ref parScanTarget ) : m_scan_target(parScanTarget) {} - static constexpr const char* command ( void ) { return "HSCAN"; } + static constexpr const char* command ( void ) { return ScanCommands::_from_integral(Command)._to_string(); } static constexpr const std::size_t step = 2; static value_type make_value ( const RedisReplyType* parItem ); diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index 5ef01c8..16dae8c 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -153,8 +153,8 @@ namespace redis { return get(*parItem); } - template - auto ScanPairs::make_value (const RedisReplyType* parItem) -> value_type { + template + auto ScanPairs::make_value (const RedisReplyType* parItem) -> value_type { assert(parItem); return value_type(get(parItem[0]), get(parItem[1])); } From 533b5717718aa9f0853e124e4d3ab037477e962d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 16:20:54 +0100 Subject: [PATCH 050/170] Implement ZSCAN Redis command. --- src/backends/redis/command.cpp | 4 ++++ src/backends/redis/command.hpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index 7445b61..b8e49d4 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -137,4 +137,8 @@ namespace redis { auto Command::sscan (boost::string_ref parKey) -> sscan_range { return sscan_range(sscan_iterator(this, parKey, false), sscan_iterator(this, parKey, true)); } + + auto Command::zscan (boost::string_ref parKey) -> zscan_range { + return zscan_range(zscan_iterator(this, parKey, false), zscan_iterator(this, parKey, true)); + } } //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 51bedd1..c839cb1 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -43,6 +43,8 @@ namespace redis { typedef boost::iterator_range hscan_range; typedef ScanIterator> sscan_iterator; typedef boost::iterator_range sscan_range; + typedef ScanIterator, ScanCommands::ZSCAN>> zscan_iterator; + typedef boost::iterator_range zscan_range; Command ( std::string&& parAddress, uint16_t parPort ); ~Command ( void ) noexcept; @@ -59,6 +61,7 @@ namespace redis { scan_range scan ( void ); hscan_range hscan ( boost::string_ref parKey ); sscan_range sscan ( boost::string_ref parKey ); + zscan_range zscan ( boost::string_ref parKey ); private: using RedisConnection = std::unique_ptr; From 316f8f585be305da7b06f2668d700eb868242dbf Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 17:00:12 +0100 Subject: [PATCH 051/170] Rename RedisReplyType to just Reply. --- src/backends/redis/command.cpp | 10 +++++----- src/backends/redis/command.hpp | 6 +++--- src/backends/redis/reply.cpp | 22 +++++++++++----------- src/backends/redis/reply.hpp | 26 +++++++++++++------------- src/backends/redis/scan_iterator.cpp | 4 ++-- src/backends/redis/scan_iterator.hpp | 14 +++++++------- src/backends/redis/scan_iterator.inl | 12 ++++++------ 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index b8e49d4..0007aec 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -28,9 +28,9 @@ namespace redis { namespace { using RedisReply = std::unique_ptr; - RedisReplyType make_redis_reply_type (redisReply* parReply) { + Reply make_redis_reply_type (redisReply* parReply) { using boost::transform_iterator; - using PtrToReplyIterator = transform_iterator; + using PtrToReplyIterator = transform_iterator; switch (parReply->type) { case REDIS_REPLY_INTEGER: @@ -38,12 +38,12 @@ namespace redis { case REDIS_REPLY_STRING: return std::string(parReply->str, parReply->len); case REDIS_REPLY_ARRAY: - return std::vector( + return std::vector( PtrToReplyIterator(parReply->element, &make_redis_reply_type), PtrToReplyIterator(parReply->element + parReply->elements, &make_redis_reply_type) ); default: - return RedisReplyType(); + return Reply(); }; } } //unnamed namespace @@ -84,7 +84,7 @@ namespace redis { m_conn.reset(); } - RedisReplyType Command::run_pvt (int parArgc, const char** parArgv, std::size_t* parLengths) { + Reply Command::run_pvt (int parArgc, const char** parArgv, std::size_t* parLengths) { assert(parArgc >= 1); assert(parArgv); assert(parLengths); //This /could/ be null, but I don't see why it should diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index c839cb1..4626e9b 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -55,7 +55,7 @@ namespace redis { bool is_connected ( void ) const; template - RedisReplyType run ( const char* parCommand, Args&&... parArgs ); + Reply run ( const char* parCommand, Args&&... parArgs ); //Single Redis command wrappers scan_range scan ( void ); @@ -66,7 +66,7 @@ namespace redis { private: using RedisConnection = std::unique_ptr; - RedisReplyType run_pvt ( int parArgc, const char** parArgv, std::size_t* parLengths ); + Reply run_pvt ( int parArgc, const char** parArgv, std::size_t* parLengths ); RedisConnection m_conn; std::string m_address; @@ -74,7 +74,7 @@ namespace redis { }; template - RedisReplyType Command::run (const char* parCommand, Args&&... parArgs) { + Reply Command::run (const char* parCommand, Args&&... parArgs) { constexpr const std::size_t arg_count = sizeof...(Args) + 1; using CharPointerArray = std::array; using LengthArray = std::array; diff --git a/src/backends/redis/reply.cpp b/src/backends/redis/reply.cpp index 34789ef..1474584 100644 --- a/src/backends/redis/reply.cpp +++ b/src/backends/redis/reply.cpp @@ -20,15 +20,15 @@ #include namespace redis { - const long long& get_integer (const RedisReplyType& parReply) { + const long long& get_integer (const Reply& parReply) { return boost::get(parReply); } - const std::string& get_string (const RedisReplyType& parReply) { + const std::string& get_string (const Reply& parReply) { return boost::get(parReply); } - long long get_integer_autoconv_if_str (const RedisReplyType &parReply) { + long long get_integer_autoconv_if_str (const Reply &parReply) { using boost::lexical_cast; const auto type = parReply.which(); @@ -43,26 +43,26 @@ namespace redis { } } - const std::vector& get_array (const RedisReplyType& parReply) { - return boost::get>(parReply); + const std::vector& get_array (const Reply& parReply) { + return boost::get>(parReply); } template <> - const std::string& get (const RedisReplyType& parReply) { + const std::string& get (const Reply& parReply) { return get_string(parReply); } template <> - const std::vector& get> (const RedisReplyType& parReply) { + const std::vector& get> (const Reply& parReply) { return get_array(parReply); } template <> - const long long& get (const RedisReplyType& parReply) { + const long long& get (const Reply& parReply) { return get_integer(parReply); } - template const std::string& get ( const RedisReplyType& parReply ); - template const std::vector& get> ( const RedisReplyType& parReply ); - template const long long& get ( const RedisReplyType& parReply ); + template const std::string& get ( const Reply& parReply ); + template const std::vector& get> ( const Reply& parReply ); + template const long long& get ( const Reply& parReply ); } //namespace redis diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index db2ccf8..39d42cb 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -23,13 +23,13 @@ #include namespace redis { - class RedisReplyType; + class Reply; namespace implem { using RedisVariantType = boost::variant< long long, std::string, - boost::recursive_wrapper> + boost::recursive_wrapper> >; enum RedisVariantTypes { RedisVariantType_Integer = 0, @@ -39,23 +39,23 @@ namespace redis { }; } //namespace implem - struct RedisReplyType : implem::RedisVariantType { + struct Reply : implem::RedisVariantType { using base_class = implem::RedisVariantType; - RedisReplyType ( void ) = default; - RedisReplyType ( long long parVal ) : base_class(parVal) {} - RedisReplyType ( std::string&& parVal ) : base_class(std::move(parVal)) {} - RedisReplyType ( std::vector&& parVal ) : base_class(std::move(parVal)) {} - ~RedisReplyType ( void ) noexcept = default; + Reply ( void ) = default; + Reply ( long long parVal ) : base_class(parVal) {} + Reply ( std::string&& parVal ) : base_class(std::move(parVal)) {} + Reply ( std::vector&& parVal ) : base_class(std::move(parVal)) {} + ~Reply ( void ) noexcept = default; }; - const long long& get_integer ( const RedisReplyType& parReply ); - long long get_integer_autoconv_if_str ( const RedisReplyType& parReply ); - const std::string& get_string ( const RedisReplyType& parReply ); - const std::vector& get_array ( const RedisReplyType& parReply ); + const long long& get_integer ( const Reply& parReply ); + long long get_integer_autoconv_if_str ( const Reply& parReply ); + const std::string& get_string ( const Reply& parReply ); + const std::vector& get_array ( const Reply& parReply ); template - const T& get ( const RedisReplyType& parReply ); + const T& get ( const Reply& parReply ); } //namespace redis #endif diff --git a/src/backends/redis/scan_iterator.cpp b/src/backends/redis/scan_iterator.cpp index f8dbeaa..8307930 100644 --- a/src/backends/redis/scan_iterator.cpp +++ b/src/backends/redis/scan_iterator.cpp @@ -35,11 +35,11 @@ namespace redis { return m_command and m_command->is_connected(); } - RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext) { + Reply ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext) { return m_command->run(parCommand, boost::lexical_cast(parScanContext)); } - RedisReplyType ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext) { + Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext) { return m_command->run(parCommand, parParameter, boost::lexical_cast(parScanContext)); } } //namespace implem diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index 0042b1e..bde4d0a 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -43,8 +43,8 @@ namespace redis { ~ScanIteratorBaseClass ( void ) noexcept = default; bool is_connected ( void ) const; - RedisReplyType run ( const char* parCommand, long long parScanContext ); - RedisReplyType run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext ); + Reply run ( const char* parCommand, long long parScanContext ); + Reply run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext ); bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; } @@ -76,9 +76,9 @@ namespace redis { private: template - RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); + Reply forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); template - RedisReplyType forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); + Reply forward_scan_command ( typename std::enable_if::value, int>::type parDummy ); bool is_end ( void ) const; void increment ( void ); @@ -97,7 +97,7 @@ namespace redis { static constexpr const char* command ( void ) { return "SCAN"; } static constexpr const std::size_t step = 1; - static const T& make_value ( const RedisReplyType* parItem ); + static const T& make_value ( const Reply* parItem ); }; template @@ -109,7 +109,7 @@ namespace redis { static constexpr const char* command ( void ) { return "SSCAN"; } static constexpr const std::size_t step = 1; - static const T& make_value ( const RedisReplyType* parItem ); + static const T& make_value ( const Reply* parItem ); boost::string_ref scan_target ( void ) const { return m_scan_target; } private: @@ -126,7 +126,7 @@ namespace redis { static constexpr const char* command ( void ) { return ScanCommands::_from_integral(Command)._to_string(); } static constexpr const std::size_t step = 2; - static value_type make_value ( const RedisReplyType* parItem ); + static value_type make_value ( const Reply* parItem ); boost::string_ref scan_target ( void ) const { return m_scan_target; } private: diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index 16dae8c..441a857 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -81,7 +81,7 @@ namespace redis { m_curr_index = 0; } else { - std::vector array_reply; + std::vector array_reply; long long new_context; do { @@ -131,30 +131,30 @@ namespace redis { template template - RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + Reply ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context); } template template - RedisReplyType ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { + Reply ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context); } template - auto ScanSingleValues::make_value (const RedisReplyType* parItem) -> const value_type& { + auto ScanSingleValues::make_value (const Reply* parItem) -> const value_type& { assert(parItem); return get(*parItem); } template - auto ScanSingleValuesInKey::make_value (const RedisReplyType* parItem) -> const value_type& { + auto ScanSingleValuesInKey::make_value (const Reply* parItem) -> const value_type& { assert(parItem); return get(*parItem); } template - auto ScanPairs::make_value (const RedisReplyType* parItem) -> value_type { + auto ScanPairs::make_value (const Reply* parItem) -> value_type { assert(parItem); return value_type(get(parItem[0]), get(parItem[1])); } From 93e328d77f23604bfd2e88850f99c6a0fceaf19a Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 17:27:52 +0100 Subject: [PATCH 052/170] Remove unnecessary usage of recursive_wrapper. --- src/backends/redis/reply.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index 39d42cb..4d60022 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -19,8 +19,8 @@ #define id93FA96E3071745D9A1E45D4D29B9F7D0 #include -#include #include +#include namespace redis { class Reply; @@ -29,7 +29,7 @@ namespace redis { using RedisVariantType = boost::variant< long long, std::string, - boost::recursive_wrapper> + std::vector >; enum RedisVariantTypes { RedisVariantType_Integer = 0, From 9a69b8de10cc47385331e2c0fdd2de59cae6b1d2 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 13 Jun 2016 17:33:25 +0100 Subject: [PATCH 053/170] Throw if Redis reply contains any error messages. --- src/backends/redis/command.cpp | 7 +++++++ src/backends/redis/command.hpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/backends/redis/command.cpp b/src/backends/redis/command.cpp index 0007aec..a2d6d37 100644 --- a/src/backends/redis/command.cpp +++ b/src/backends/redis/command.cpp @@ -42,6 +42,8 @@ namespace redis { PtrToReplyIterator(parReply->element, &make_redis_reply_type), PtrToReplyIterator(parReply->element + parReply->elements, &make_redis_reply_type) ); + case REDIS_REPLY_ERROR: + throw RedisError(parReply->str, parReply->len); default: return Reply(); }; @@ -141,4 +143,9 @@ namespace redis { auto Command::zscan (boost::string_ref parKey) -> zscan_range { return zscan_range(zscan_iterator(this, parKey, false), zscan_iterator(this, parKey, true)); } + + RedisError::RedisError (const char* parMessage, std::size_t parLength) : + std::runtime_error(std::string(parMessage, parLength)) + { + } } //namespace redis diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 4626e9b..4524f3d 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -31,6 +31,7 @@ #include #include #include +#include struct redisContext; @@ -88,6 +89,11 @@ namespace redis { LengthArray{ arg_to_bin_safe_length(string_ref(parCommand)), arg_to_bin_safe_length(std::forward(parArgs))... }.data() ); } + + class RedisError : public std::runtime_error { + public: + RedisError ( const char* parMessage, std::size_t parLength ); + }; } //namespace redis #endif From efd71181897b4937ebf11735eb23c430ee9e50b9 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 09:10:45 +0100 Subject: [PATCH 054/170] Add support for single chars to the run() method. --- src/backends/redis/arg_to_bin_safe.hpp | 10 ++++++++ src/backends/redis/backend_redis.cpp | 35 +++++++++++++++++++++----- src/backends/redis/command.hpp | 3 ++- src/backends/redis/reply.hpp | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/backends/redis/arg_to_bin_safe.hpp b/src/backends/redis/arg_to_bin_safe.hpp index 360e4dd..47e5f42 100644 --- a/src/backends/redis/arg_to_bin_safe.hpp +++ b/src/backends/redis/arg_to_bin_safe.hpp @@ -55,6 +55,16 @@ namespace redis { const std::size_t m_size; }; + template<> + struct MakeCharInfo { + MakeCharInfo ( char parData ) : m_data(parData) {} + const char* data ( void ) const { return &m_data; } + std::size_t size ( void ) const { return 1; } + + private: + const char m_data; + }; + template inline const char* arg_to_bin_safe_char (const T& parArg) { return MakeCharInfo(parArg).data(); diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index ffdd57c..cf50df3 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -91,9 +91,6 @@ namespace dindb { } void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { - for (const auto& file_path : m_redis.scan()) { - //std::cout << file_path << '\n'; - } } void BackendRedis::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { @@ -114,9 +111,35 @@ namespace dindb { void BackendRedis::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { using boost::lexical_cast; - auto incr_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices set 1"); - const std::string set_key = PROGRAM_NAME ":set:" + lexical_cast(redis::get_integer(incr_reply)); - auto insert_set_reply = m_redis.run("HMSET %b name %b disk_label %b fs_uuid %b", set_key, parSetData.name, parSetData.disk_label, parSetData.fs_uuid); + redis::Reply set_id_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices set 1"); + const std::string set_key = PROGRAM_NAME ":set:" + lexical_cast(redis::get_integer(set_id_reply)); + redis::Reply insert_set_reply = m_redis.run( + "HMSET %b name %b disk_label %b fs_uuid %b type %b content_type %b", + set_key, + parSetData.name, + parSetData.disk_label, + parSetData.fs_uuid, + parSetData.type, + parSetData.content_type + ); + + for (const auto& file_data : parData) { + redis::Reply file_id_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices files 1"); + const std::string file_key = PROGRAM_NAME ":file:" + lexical_cast(redis::get_integer(file_id_reply)); + redis::Reply insert_file_reply = m_redis.run( + "HMSET %b hash %b path %b size %b level %b mime_type %b mime_charset %b is_directory %b is_symlink %b is_unreadable %b hash_valid %b", + file_key, + tiger_to_string(file_data.hash), + lexical_cast(file_data.size), + lexical_cast(file_data.level), + file_data.mime_type(), + file_data.mime_charset(), + (file_data.is_directory ? '1' : '0'), + (file_data.is_symlink ? '1' : '0'), + (file_data.unreadable ? '1' : '0'), + (file_data.hash_valid ? '1' : '0') + ); + } } bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { diff --git a/src/backends/redis/command.hpp b/src/backends/redis/command.hpp index 4524f3d..b3b00a0 100644 --- a/src/backends/redis/command.hpp +++ b/src/backends/redis/command.hpp @@ -81,11 +81,12 @@ namespace redis { using LengthArray = std::array; using implem::arg_to_bin_safe_char; using implem::arg_to_bin_safe_length; + using implem::MakeCharInfo; using boost::string_ref; return this->run_pvt( static_cast(arg_count), - CharPointerArray{ arg_to_bin_safe_char(string_ref(parCommand)), arg_to_bin_safe_char(std::forward(parArgs))... }.data(), + CharPointerArray{ (arg_to_bin_safe_char(string_ref(parCommand))), MakeCharInfo::type>::type>(std::forward(parArgs)).data()... }.data(), LengthArray{ arg_to_bin_safe_length(string_ref(parCommand)), arg_to_bin_safe_length(std::forward(parArgs))... }.data() ); } diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index 4d60022..24332d6 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -23,7 +23,7 @@ #include namespace redis { - class Reply; + struct Reply; namespace implem { using RedisVariantType = boost::variant< From ba8e8b9f7bff3b7afb071a867a1166507322e626 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 09:11:07 +0100 Subject: [PATCH 055/170] Add support for char[N] to the run() method. --- src/backends/redis/arg_to_bin_safe.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/backends/redis/arg_to_bin_safe.hpp b/src/backends/redis/arg_to_bin_safe.hpp index 47e5f42..41ab8d2 100644 --- a/src/backends/redis/arg_to_bin_safe.hpp +++ b/src/backends/redis/arg_to_bin_safe.hpp @@ -65,6 +65,17 @@ namespace redis { const char m_data; }; + template + struct MakeCharInfo { + static_assert(N > 0, "Given input should have at least one character as it's assumed to be a null-terminated string"); + MakeCharInfo ( const char (&parData)[N] ) : m_data(parData, N - 1) {} + const char* data ( void ) const { return m_data.data(); } + std::size_t size ( void ) const { return m_data.size(); } + + private: + boost::string_ref m_data; + }; + template inline const char* arg_to_bin_safe_char (const T& parArg) { return MakeCharInfo(parArg).data(); From ab43215f4941e0b4d77e00ea4175c3fc9f2a2cf2 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 09:12:32 +0100 Subject: [PATCH 056/170] Use the right syntax for Redis command. With this commit, scan subcommand can save all it needs into Redis. --- src/backends/redis/backend_redis.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index cf50df3..7e3ff5d 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -110,33 +110,50 @@ namespace dindb { void BackendRedis::write_files (const std::vector& parData, const mchlib::SetRecordDataFull& parSetData, const std::string& parSignature) { using boost::lexical_cast; + using boost::string_ref; - redis::Reply set_id_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices set 1"); + redis::Reply set_id_reply = m_redis.run("HINCRBY", PROGRAM_NAME ":indices", "set", "1"); const std::string set_key = PROGRAM_NAME ":set:" + lexical_cast(redis::get_integer(set_id_reply)); redis::Reply insert_set_reply = m_redis.run( - "HMSET %b name %b disk_label %b fs_uuid %b type %b content_type %b", + "HMSET", set_key, + "name", parSetData.name, + "disk_label", parSetData.disk_label, + "fs_uuid", parSetData.fs_uuid, + "type", parSetData.type, + "content_type", parSetData.content_type ); for (const auto& file_data : parData) { - redis::Reply file_id_reply = m_redis.run("HINCRBY " PROGRAM_NAME ":indices files 1"); + redis::Reply file_id_reply = m_redis.run("HINCRBY", PROGRAM_NAME ":indices", "files", "1"); const std::string file_key = PROGRAM_NAME ":file:" + lexical_cast(redis::get_integer(file_id_reply)); redis::Reply insert_file_reply = m_redis.run( - "HMSET %b hash %b path %b size %b level %b mime_type %b mime_charset %b is_directory %b is_symlink %b is_unreadable %b hash_valid %b", + "HMSET", file_key, + "hash", tiger_to_string(file_data.hash), + "path", + file_data.path(), + "size", lexical_cast(file_data.size), + "level", lexical_cast(file_data.level), + "mime_type", file_data.mime_type(), + "mime_charset", file_data.mime_charset(), + "is_directory", (file_data.is_directory ? '1' : '0'), + "is_symlink", (file_data.is_symlink ? '1' : '0'), + "unreadable", (file_data.unreadable ? '1' : '0'), + "hash_valid", (file_data.hash_valid ? '1' : '0') ); } From 9ef9b05014fe15e6971069c4343e7b6bcf30777c Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 09:37:57 +0100 Subject: [PATCH 057/170] Move variant types enum out of implem namespace. Also assert that you can get the type you are trying to get before actually trying. --- src/backends/redis/reply.cpp | 7 +++++-- src/backends/redis/reply.hpp | 12 ++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/backends/redis/reply.cpp b/src/backends/redis/reply.cpp index 1474584..9751f11 100644 --- a/src/backends/redis/reply.cpp +++ b/src/backends/redis/reply.cpp @@ -21,10 +21,12 @@ namespace redis { const long long& get_integer (const Reply& parReply) { + assert(RedisVariantType_Integer == parReply.which()); return boost::get(parReply); } const std::string& get_string (const Reply& parReply) { + assert(RedisVariantType_String == parReply.which()); return boost::get(parReply); } @@ -33,9 +35,9 @@ namespace redis { const auto type = parReply.which(); switch (type) { - case implem::RedisVariantType_Integer: + case RedisVariantType_Integer: return get_integer(parReply); - case implem::RedisVariantType_String: + case RedisVariantType_String: return lexical_cast(get_string(parReply)); default: assert(false); @@ -44,6 +46,7 @@ namespace redis { } const std::vector& get_array (const Reply& parReply) { + assert(RedisVariantType_Array == parReply.which()); return boost::get>(parReply); } diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index 24332d6..6ed6820 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -31,13 +31,13 @@ namespace redis { std::string, std::vector >; - enum RedisVariantTypes { - RedisVariantType_Integer = 0, - RedisVariantType_String, - RedisVariantType_Array, - RedisVariantType_Bool - }; } //namespace implem + enum RedisVariantTypes { + RedisVariantType_Integer = 0, + RedisVariantType_String, + RedisVariantType_Array, + RedisVariantType_Bool + }; struct Reply : implem::RedisVariantType { using base_class = implem::RedisVariantType; From 549ab7b16ab20b2e1b767147ea861ffb276f4155 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 10:39:42 +0100 Subject: [PATCH 058/170] Write implementation for search_file_by_hash(). Note that the postgresql backend does something like "select blah... where hash=$1 limit 1", so it only returns one match. The SRANDMEMBER used in this implementation also returns one match, but it's not deterministic I suppose. --- src/backends/redis/backend_redis.cpp | 130 ++++++++++++++++++++------- src/backends/redis/reply.hpp | 3 +- 2 files changed, 100 insertions(+), 33 deletions(-) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 7e3ff5d..d2d4679 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace dindb { namespace { @@ -31,6 +33,66 @@ namespace dindb { uint16_t port; uint16_t database; }; + + std::pair pair_list_to_file_record (const redis::Command::hscan_range& parRange, const mchlib::TigerHash& parHash) { + using boost::lexical_cast; + + mchlib::FileRecordData retval; + retval.hash = parHash; + std::array mime; + std::string group_key; + + for (const auto itm : parRange) { + if (itm.first == "path") + retval.abs_path = itm.second; + else if (itm.first == "hash") + assert(tiger_to_string(parHash) == itm.second); + else if (itm.first == "size") + retval.size = lexical_cast( + itm.second); + else if (itm.first == "level") + retval.level = lexical_cast( + itm.second); + else if (itm.first == "mime_type") + mime[0] = itm.second; + else if (itm.first == "mime_charset") + mime[1] = itm.second; + else if (itm.first == "is_directory") + retval.is_directory = (itm.second[0] == '0' ? false : true); + else if (itm.first == "is_symlink") + retval.is_symlink = (itm.second[0] == '0' ? false : true); + else if (itm.first == "unreadable") + retval.unreadable = (itm.second[0] == '0' ? false : true); + else if (itm.first == "hash_valid") + retval.hash_valid = (itm.second[0] == '0' ? false : true); + else if (itm.first == "group_id") + group_key = itm.second; + } + retval.mime_full = mime[0] + mime[1]; + retval.mime_type_offset = 0; + retval.mime_type_length = retval.mime_charset_offset = static_cast(mime[0].size()); + retval.mime_charset_length = static_cast(mime[1].size()); + return std::make_pair(group_key, std::move(retval)); + } + + mchlib::SetRecordDataFull pair_list_to_set_record (const redis::Command::hscan_range& parRange) { + using boost::lexical_cast; + + mchlib::SetRecordDataFull retval; + for (const auto& itm : parRange) { + if (itm.first == "name") + retval.name = itm.second; + else if (itm.first == "disk_label") + retval.disk_label = itm.second; + else if (itm.first == "fs_uuid") + retval.fs_uuid = itm.second; + else if (itm.first == "type") + retval.type = lexical_cast(itm.second[0]); + else if (itm.first == "content_type") + retval.content_type = lexical_cast(itm.second[0]); + } + return retval; + } } //unnamed namespace } //namespace dindb @@ -117,50 +179,56 @@ namespace dindb { redis::Reply insert_set_reply = m_redis.run( "HMSET", set_key, - "name", - parSetData.name, - "disk_label", - parSetData.disk_label, - "fs_uuid", - parSetData.fs_uuid, - "type", - parSetData.type, - "content_type", - parSetData.content_type + "name", parSetData.name, + "disk_label", parSetData.disk_label, + "fs_uuid", parSetData.fs_uuid, + "type", parSetData.type, + "content_type", parSetData.content_type ); for (const auto& file_data : parData) { redis::Reply file_id_reply = m_redis.run("HINCRBY", PROGRAM_NAME ":indices", "files", "1"); const std::string file_key = PROGRAM_NAME ":file:" + lexical_cast(redis::get_integer(file_id_reply)); + const std::string hash = tiger_to_string(file_data.hash); redis::Reply insert_file_reply = m_redis.run( "HMSET", file_key, - "hash", - tiger_to_string(file_data.hash), - "path", - file_data.path(), - "size", - lexical_cast(file_data.size), - "level", - lexical_cast(file_data.level), - "mime_type", - file_data.mime_type(), - "mime_charset", - file_data.mime_charset(), - "is_directory", - (file_data.is_directory ? '1' : '0'), - "is_symlink", - (file_data.is_symlink ? '1' : '0'), - "unreadable", - (file_data.unreadable ? '1' : '0'), - "hash_valid", - (file_data.hash_valid ? '1' : '0') + "hash", hash, + "path", file_data.path(), + "size", lexical_cast(file_data.size), + "level", lexical_cast(file_data.level), + "mime_type", file_data.mime_type(), + "mime_charset", file_data.mime_charset(), + "is_directory", (file_data.is_directory ? '1' : '0'), + "is_symlink", (file_data.is_symlink ? '1' : '0'), + "unreadable", (file_data.unreadable ? '1' : '0'), + "hash_valid", (file_data.hash_valid ? '1' : '0'), + "group_id", set_key + ); + + redis::Reply insert_hash_reply = m_redis.run( + "SADD", + "hash:" + hash, + file_key ); } } bool BackendRedis::search_file_by_hash (mchlib::FileRecordData& parItem, mchlib::SetRecordDataFull& parSet, const mchlib::TigerHash& parHash) { - return false; + const std::string hash_key = "hash:" + tiger_to_string(parHash); + redis::Reply hash_reply = m_redis.run("SRANDMEMBER", hash_key); + if (redis::RedisVariantType_Integer == hash_reply.which() and not redis::get_integer(hash_reply)) { + return false; + } + else { + const auto result_id = redis::get_string(hash_reply); + auto set_key_and_file_item = pair_list_to_file_record(m_redis.hscan(result_id), parHash); + parItem = std::move(set_key_and_file_item.second); + const std::string group_key = std::move(set_key_and_file_item.first); + + auto set_item = pair_list_to_set_record(m_redis.hscan(group_key)); + return true; + } } std::vector BackendRedis::locate_in_db (const std::string& parSearch, const TagList& parTags) { diff --git a/src/backends/redis/reply.hpp b/src/backends/redis/reply.hpp index 6ed6820..a1a6606 100644 --- a/src/backends/redis/reply.hpp +++ b/src/backends/redis/reply.hpp @@ -35,8 +35,7 @@ namespace redis { enum RedisVariantTypes { RedisVariantType_Integer = 0, RedisVariantType_String, - RedisVariantType_Array, - RedisVariantType_Bool + RedisVariantType_Array }; struct Reply : implem::RedisVariantType { From a5d5ee5af58f3eb2bd6f551bfc83cbd0a909f4a5 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 10:41:38 +0100 Subject: [PATCH 059/170] Also return content_type. --- src/backends/postgresql/scan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/postgresql/scan.cpp b/src/backends/postgresql/scan.cpp index 881c52d..b1149de 100644 --- a/src/backends/postgresql/scan.cpp +++ b/src/backends/postgresql/scan.cpp @@ -64,7 +64,7 @@ namespace dindb { { auto resultset = parDB.query( - "SELECT \"desc\",\"type\",\"disk_number\",\"fs_uuid\",\"disk_label\" FROM sets WHERE \"id\"=$1;", + "SELECT \"desc\",\"type\",\"disk_number\",\"fs_uuid\",\"disk_label\",\"content_type\" FROM sets WHERE \"id\"=$1;", group_id ); if (resultset.empty()) { @@ -79,6 +79,7 @@ namespace dindb { parSet.disk_number = lexical_cast(row["disk_number"]); parSet.fs_uuid = row["fs_uuid"]; parSet.disk_label = row["disk_label"]; + parSet.content_type = lexical_cast(row["content_type"]); } return true; } From 2a696aa62a71edfd15a0de319efbb09be4a603dd Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 11:03:31 +0100 Subject: [PATCH 060/170] Allow users to selectively build backends. Pass -DDINDEXER_ENABLED_BACKENDS="list,of,backends" to cmake to tell which backends you want to be built. Currently available backends are postgresql and redis. Default is postgresql. Allowed strings in the comma separated list above are the names of the directories in src/backends. --- src/backends/CMakeLists.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt index f091a99..2b73dc9 100644 --- a/src/backends/CMakeLists.txt +++ b/src/backends/CMakeLists.txt @@ -1,6 +1,8 @@ project(${bare_name}-backend CXX) set(BACKEND_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") +set(DINDEXER_ENABLED_BACKENDS "postgresql" CACHE STRING "Comma separated list of enabled backends. See directories in backends source directory for a list of known backends.") + function(ln_backend backend_name) add_custom_command(TARGET "${backend_name}" POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink $ ${BACKEND_BINARY_DIR}/$ @@ -27,13 +29,9 @@ target_link_libraries(${PROJECT_NAME} INTERFACE ${bare_name}-machinery ) -#install(TARGETS ${PROJECT_NAME} -# LIBRARY DESTINATION lib -# RUNTIME DESTINATION bin -# ARCHIVE DESTINATION lib/static -#) - -add_subdirectory(postgresql) -add_subdirectory(redis) -add_dependencies(${PROJECT_NAME} ${bare_name}-backend-postgresql) -add_dependencies(${PROJECT_NAME} ${bare_name}-backend-redis) +string(REPLACE "," ";" backend_list "${DINDEXER_ENABLED_BACKENDS}") +foreach(backend ${backend_list}) + add_subdirectory(${backend}) + add_dependencies(${PROJECT_NAME} ${bare_name}-backend-${backend}) +endforeach() +unset(backend) From 423effa6cbe3559f2f7734b1842732b98d23e169 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 19:10:10 +0100 Subject: [PATCH 061/170] Set client name in Redis to dindexer_v0.1.5 --- src/backends/redis/backend_redis.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index d2d4679..8c5d484 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -20,6 +20,7 @@ #include "backends/exposed_functions.hpp" #include "backends/backend_version.hpp" #include "dindexerConfig.h" +#include "helpers/stringize.h" #include #include #include @@ -140,8 +141,8 @@ namespace dindb { m_redis.connect(); if (m_redis.is_connected() and m_database > 0) { - const std::string command = "SELECT " + lexical_cast(m_database); - m_redis.run(command.c_str()); + m_redis.run("SELECT", lexical_cast(m_database)); + m_redis.run("CLIENT", "SETNAME", PROGRAM_NAME "_v" STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "." STRINGIZE(VERSION_PATCH)); } } From 874783e8da4f905a0ae277865ae7dc763ba30c9a Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 14 Jun 2016 19:11:13 +0100 Subject: [PATCH 062/170] Add support for the MATCH and COUNT options for the SCAN commands. --- src/backends/redis/scan_iterator.cpp | 26 +++++++++++++++++++++----- src/backends/redis/scan_iterator.hpp | 13 +++++++++---- src/backends/redis/scan_iterator.inl | 12 ++++++------ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/backends/redis/scan_iterator.cpp b/src/backends/redis/scan_iterator.cpp index 8307930..4f9d67e 100644 --- a/src/backends/redis/scan_iterator.cpp +++ b/src/backends/redis/scan_iterator.cpp @@ -25,7 +25,13 @@ namespace redis { namespace implem { ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand) : - m_command(parCommand) + ScanIteratorBaseClass(parCommand, boost::string_ref()) + { + } + + ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand, boost::string_ref parMatchPattern) : + m_command(parCommand), + m_match_pattern(parMatchPattern) { assert(m_command); assert(m_command->is_connected()); @@ -35,12 +41,22 @@ namespace redis { return m_command and m_command->is_connected(); } - Reply ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext) { - return m_command->run(parCommand, boost::lexical_cast(parScanContext)); + Reply ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext, std::size_t parCount) { + const auto scan_context = boost::lexical_cast(parScanContext); + const auto count_hint = boost::lexical_cast(parCount); + if (m_match_pattern.empty()) + return m_command->run(parCommand, scan_context, "COUNT", count_hint); + else + return m_command->run(parCommand, scan_context, "MATCH", m_match_pattern, "COUNT", count_hint); } - Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext) { - return m_command->run(parCommand, parParameter, boost::lexical_cast(parScanContext)); + Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext, std::size_t parCount) { + const auto scan_context = boost::lexical_cast(parScanContext); + const auto count_hint = boost::lexical_cast(parCount); + if (m_match_pattern.empty()) + return m_command->run(parCommand, parParameter, scan_context, "COUNT", count_hint); + else + return m_command->run(parCommand, parParameter, scan_context, "MATCH", m_match_pattern, "COUNT", count_hint); } } //namespace implem } //namespace redis diff --git a/src/backends/redis/scan_iterator.hpp b/src/backends/redis/scan_iterator.hpp index bde4d0a..b6f1a0c 100644 --- a/src/backends/redis/scan_iterator.hpp +++ b/src/backends/redis/scan_iterator.hpp @@ -40,16 +40,18 @@ namespace redis { class ScanIteratorBaseClass { protected: explicit ScanIteratorBaseClass ( Command* parCommand ); + ScanIteratorBaseClass ( Command* parCommand, boost::string_ref parMatchPattern ); ~ScanIteratorBaseClass ( void ) noexcept = default; bool is_connected ( void ) const; - Reply run ( const char* parCommand, long long parScanContext ); - Reply run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext ); + Reply run ( const char* parCommand, long long parScanContext, std::size_t parCount ); + Reply run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext, std::size_t parCount ); bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; } private: Command* m_command; + boost::string_ref m_match_pattern; }; } //namespace implem @@ -70,9 +72,9 @@ namespace redis { typedef typename base_iterator::iterator_category iterator_category; template ::value>::type> - ScanIterator ( Command* parCommand, bool parEnd ); + ScanIterator ( Command* parCommand, bool parEnd, boost::string_ref parMatchPattern=boost::string_ref() ); template ::value>::type> - ScanIterator ( Command* parCommand, boost::string_ref parKey, bool parEnd ); + ScanIterator ( Command* parCommand, boost::string_ref parKey, bool parEnd, boost::string_ref parMatchPattern=boost::string_ref() ); private: template @@ -96,6 +98,7 @@ namespace redis { static constexpr const char* command ( void ) { return "SCAN"; } static constexpr const std::size_t step = 1; + static constexpr const std::size_t work_count = 10; static const T& make_value ( const Reply* parItem ); }; @@ -108,6 +111,7 @@ namespace redis { static constexpr const char* command ( void ) { return "SSCAN"; } static constexpr const std::size_t step = 1; + static constexpr const std::size_t work_count = 10; static const T& make_value ( const Reply* parItem ); boost::string_ref scan_target ( void ) const { return m_scan_target; } @@ -125,6 +129,7 @@ namespace redis { static constexpr const char* command ( void ) { return ScanCommands::_from_integral(Command)._to_string(); } static constexpr const std::size_t step = 2; + static constexpr const std::size_t work_count = 10; static value_type make_value ( const Reply* parItem ); boost::string_ref scan_target ( void ) const { return m_scan_target; } diff --git a/src/backends/redis/scan_iterator.inl b/src/backends/redis/scan_iterator.inl index 441a857..1e7a443 100644 --- a/src/backends/redis/scan_iterator.inl +++ b/src/backends/redis/scan_iterator.inl @@ -25,8 +25,8 @@ namespace redis { template template - ScanIterator::ScanIterator (Command* parCommand, bool parEnd) : - implem::ScanIteratorBaseClass(parCommand), + ScanIterator::ScanIterator (Command* parCommand, bool parEnd, boost::string_ref parMatchPattern) : + implem::ScanIteratorBaseClass(parCommand, parMatchPattern), implem::ScanIteratorBaseIterator(), ValueFetch(), m_reply(), @@ -45,8 +45,8 @@ namespace redis { template template - ScanIterator::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd) : - implem::ScanIteratorBaseClass(parCommand), + ScanIterator::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd, boost::string_ref parMatchPattern) : + implem::ScanIteratorBaseClass(parCommand, parMatchPattern), implem::ScanIteratorBaseIterator(), ValueFetch(parKey), m_reply(), @@ -132,13 +132,13 @@ namespace redis { template template Reply ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { - return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context); + return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context, T::work_count); } template template Reply ScanIterator::forward_scan_command (typename std::enable_if::value, int>::type) { - return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context); + return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context, T::work_count); } template From 9491f2eb47707e600d8bab5986672b3a33d55259 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 15 Jun 2016 14:53:07 +0100 Subject: [PATCH 063/170] Move sequence_bt and string_bt into helpers. They are useful in the Redis backend and in helpers itself. People wanting to use pq alone from this project will have to cope and search for all the needed files. --- include/{pq/implem => helpers}/sequence_bt.hpp | 4 ++-- include/{pq/implem => helpers}/string_bt.hpp | 6 +++--- include/pq/implem/pq_type_helpers.hpp | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) rename include/{pq/implem => helpers}/sequence_bt.hpp (97%) rename include/{pq/implem => helpers}/string_bt.hpp (97%) diff --git a/include/pq/implem/sequence_bt.hpp b/include/helpers/sequence_bt.hpp similarity index 97% rename from include/pq/implem/sequence_bt.hpp rename to include/helpers/sequence_bt.hpp index 80bb7df..b79e126 100644 --- a/include/pq/implem/sequence_bt.hpp +++ b/include/helpers/sequence_bt.hpp @@ -20,7 +20,7 @@ #include -namespace pq { +namespace dinhelp { namespace bt { template struct index_seq { @@ -43,6 +43,6 @@ namespace pq { template using index_range = typename implem::range_builder::type; } //namespace bt -} //namespace pq +} //namespace dinhelp #endif diff --git a/include/pq/implem/string_bt.hpp b/include/helpers/string_bt.hpp similarity index 97% rename from include/pq/implem/string_bt.hpp rename to include/helpers/string_bt.hpp index dc1dbde..820ad81 100644 --- a/include/pq/implem/string_bt.hpp +++ b/include/helpers/string_bt.hpp @@ -18,12 +18,12 @@ #ifndef id170B0E6C34D14EBA9B92A35977BDBFB3 #define id170B0E6C34D14EBA9B92A35977BDBFB3 -#include "pq/implem/sequence_bt.hpp" +#include "sequence_bt.hpp" #include #include #include -namespace pq { +namespace dinhelp { namespace bt { template class string; @@ -107,6 +107,6 @@ namespace pq { return string(parData); } } //namespace bt -} //namespace pq +} //namespace dinhelp #endif diff --git a/include/pq/implem/pq_type_helpers.hpp b/include/pq/implem/pq_type_helpers.hpp index 92023be..2ebf303 100644 --- a/include/pq/implem/pq_type_helpers.hpp +++ b/include/pq/implem/pq_type_helpers.hpp @@ -18,7 +18,7 @@ #ifndef idEC73C3E4D64D44ABA0DB7D41FA8A7EB7 #define idEC73C3E4D64D44ABA0DB7D41FA8A7EB7 -#include "pq/implem/string_bt.hpp" +#include "helpers/string_bt.hpp" #include #include #include @@ -30,6 +30,8 @@ struct pg_param; typedef pg_param PGparam; namespace pq { + namespace bt = dinhelp::bt; + class Connection; namespace implem { From 7db82f83d96ffb51a6fb0c586245acffc2ac2584 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 15 Jun 2016 14:54:24 +0100 Subject: [PATCH 064/170] Add custom lexical_cast function that can handle hex values and string_ref. Negative values are not supported. --- include/helpers/casts.hpp | 181 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 include/helpers/casts.hpp diff --git a/include/helpers/casts.hpp b/include/helpers/casts.hpp new file mode 100644 index 0000000..1055933 --- /dev/null +++ b/include/helpers/casts.hpp @@ -0,0 +1,181 @@ +/* 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 id942A6B5AB2AF443C82D4321775BFC9E8 +#define id942A6B5AB2AF443C82D4321775BFC9E8 + +#include "compatibility.h" +#include "helpers/sequence_bt.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dinhelp { + namespace customize { + template + struct index_array_to_string; + + template + struct char_to_int; + } //namespace customize + + namespace implem { + template + inline constexpr std::size_t max_digits() { + return static_cast(::log(std::numeric_limits::max())); + } + + template + struct power { + enum { value = Base * power::value }; + }; + template + struct power { + enum { value = 1 }; + }; + + constexpr std::size_t count_digits_10_compiletime (std::size_t parNum) { + return (parNum == 0 ? 0 : static_cast(::log10(parNum))) + 1; + } + + template + struct maxdigits { + enum { value = count_digits_10_compiletime(static_cast(::pow(2.0, static_cast(N)))) }; + }; + + template