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); }