From 45e5b7bc8d1bc1fc527695a9fba677bc3ff0c6a0 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 14 Dec 2015 13:00:10 +0000 Subject: [PATCH] Implement "locate" action. --- CMakeLists.txt | 1 + action_skel_code/main.cpp | 1 - src/delete/postgre_delete.cpp | 1 - src/locate/CMakeLists.txt | 21 +++++++++++ src/locate/commandline.cpp | 59 ++++++++++++++++++++++++++++++ src/locate/commandline.hpp | 29 +++++++++++++++ src/locate/main.cpp | 65 +++++++++++++++++++++++++++++++++ src/locate/postgre_locate.cpp | 67 +++++++++++++++++++++++++++++++++++ src/locate/postgre_locate.hpp | 36 +++++++++++++++++++ 9 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 src/locate/CMakeLists.txt create mode 100644 src/locate/commandline.cpp create mode 100644 src/locate/commandline.hpp create mode 100644 src/locate/main.cpp create mode 100644 src/locate/postgre_locate.cpp create mode 100644 src/locate/postgre_locate.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d4b860..63376a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ add_subdirectory(src/main) add_subdirectory(src/common) add_subdirectory(src/delete) add_subdirectory(src/query) +add_subdirectory(src/locate) target_link_libraries(${PROJECT_NAME} INTERFACE ${PostgreSQL_LIBRARIES} diff --git a/action_skel_code/main.cpp b/action_skel_code/main.cpp index 39e6094..b214c7b 100644 --- a/action_skel_code/main.cpp +++ b/action_skel_code/main.cpp @@ -34,4 +34,3 @@ int main (int parArgc, char* parArgv[]) { } return 0; } - diff --git a/src/delete/postgre_delete.cpp b/src/delete/postgre_delete.cpp index b940e74..ce78397 100644 --- a/src/delete/postgre_delete.cpp +++ b/src/delete/postgre_delete.cpp @@ -25,7 +25,6 @@ #include #include #include -#include namespace din { namespace { diff --git a/src/locate/CMakeLists.txt b/src/locate/CMakeLists.txt new file mode 100644 index 0000000..439f414 --- /dev/null +++ b/src/locate/CMakeLists.txt @@ -0,0 +1,21 @@ +project(${bare_name}-locate CXX) + +add_executable(${PROJECT_NAME} + main.cpp + commandline.cpp + postgre_locate.cpp +) + +target_include_directories(${PROJECT_NAME} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE ${bare_name}-if + PRIVATE ${bare_name}-common +) + +string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}") +target_compile_definitions(${PROJECT_NAME} + PRIVATE ACTION_NAME="${ACTION_NAME}" +) diff --git a/src/locate/commandline.cpp b/src/locate/commandline.cpp new file mode 100644 index 0000000..7bb2b06 --- /dev/null +++ b/src/locate/commandline.cpp @@ -0,0 +1,59 @@ +/* Copyright 2015, 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 "commandline.hpp" +#include "dindexer-common/commandline.hpp" +#include +#include + +namespace po = boost::program_options; + +namespace din { + bool parse_commandline (int parArgc, char* parArgv[], po::variables_map& parVarMap) { + po::options_description set_options(ACTION_NAME " options"); + set_options.add_options() + ("case-insensitive,i", "Disable case sensitivity during search") + //("option,o", po::value()->default_value("default_value"), "Help message") + //("option2", po::value(), "Help message") + ; + + po::options_description positional_options("Positional options"); + positional_options.add_options() + ("substring", po::value(), "Substring to look for") + ; + + const auto desc = dinlib::get_default_commandline(); + po::options_description all("Available options"); + po::positional_options_description pd; + all.add(desc).add(positional_options).add(set_options); + pd.add("substring", 1);//.add("pos_option2", 1); + try { + po::store(po::command_line_parser(parArgc, parArgv).options(all).positional(pd).run(), parVarMap); + } + catch (const po::validation_error& err) { + throw dinlib::ValidationError(err); + } + + po::notify(parVarMap); + + if (dinlib::manage_common_commandline(std::cout, ACTION_NAME, "[options...] ", parVarMap, {std::cref(desc), std::cref(set_options)})) { + return true; + } + + return false; + } +} //namespace din diff --git a/src/locate/commandline.hpp b/src/locate/commandline.hpp new file mode 100644 index 0000000..979ca65 --- /dev/null +++ b/src/locate/commandline.hpp @@ -0,0 +1,29 @@ +/* Copyright 2015, 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 id1B7A42F6E46547A6AB0F914E2A91399F +#define id1B7A42F6E46547A6AB0F914E2A91399F + +#include "dindexer-common/validationerror.hpp" +#include "dindexer-common/mediatypes.hpp" +#include + +namespace din { + bool parse_commandline ( int parArgc, char* parArgv[], boost::program_options::variables_map& parVarMap ); +} //namespace din + +#endif diff --git a/src/locate/main.cpp b/src/locate/main.cpp new file mode 100644 index 0000000..9dba93d --- /dev/null +++ b/src/locate/main.cpp @@ -0,0 +1,65 @@ +/* Copyright 2015, 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 "commandline.hpp" +#include "postgre_locate.hpp" +#include "dindexer-common/settings.hpp" +#include "dindexerConfig.h" +#include +#include +#include +#include + +namespace din { + std::ostream& operator<< (std::ostream& parStream, const LocatedItem& parItem) { + parStream << parItem.group_id << '\t' << parItem.id << '\t' << parItem.path; + return parStream; + } +} //namespace din + +int main (int parArgc, char* parArgv[]) { + using boost::program_options::variables_map; + + variables_map vm; + try { + if (din::parse_commandline(parArgc, parArgv, vm)) { + return 0; + } + } + catch (const std::invalid_argument& err) { + std::cerr << err.what() << "\nUse --help for help" << std::endl; + return 2; + } + + if (not vm.count("substring")) { + std::cerr << "Missing search parameter, please use --help for usage instructions.\n"; + return 2; + } + + 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; + } + } + + const auto results = din::locate_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")); + return 0; +} diff --git a/src/locate/postgre_locate.cpp b/src/locate/postgre_locate.cpp new file mode 100644 index 0000000..47475ff --- /dev/null +++ b/src/locate/postgre_locate.cpp @@ -0,0 +1,67 @@ +/* Copyright 2015, 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 "postgre_locate.hpp" +#include "pq/connection.hpp" +#include +#include +#include +#include +#include + +namespace din { + namespace { + const int g_max_results = 200; + } //unnamed namespace + + std::vector locate_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive) { + using boost::lexical_cast; + using boost::string_ref; + namespace ba = boost::algorithm; + + 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 clean_string_with_quotes = conn.escaped_literal(parSearch); + const auto clean_string = string_ref(clean_string_with_quotes).substr(1, clean_string_with_quotes.size() - 2); + + std::ostringstream oss; + oss << "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE "; + if (parCaseInsensitive) { + std::string lower(clean_string); + ba::to_lower(lower); + oss << "LOWER(\"path\") LIKE '%" << lower << "%' "; + } + else { + oss << "\"path\" LIKE '%" << clean_string << "%' "; + } + oss << "LIMIT " << g_max_results << ';'; + + auto result = conn.query(oss.str()); + std::vector retval; + retval.reserve(result.size()); + for (const auto& record : result) { + retval.push_back(LocatedItem{ + record["path"], + std::stoull(record["id"]), + lexical_cast(record["group_id"]) + }); + } + + return std::move(retval); + } +} //namespace din diff --git a/src/locate/postgre_locate.hpp b/src/locate/postgre_locate.hpp new file mode 100644 index 0000000..025d481 --- /dev/null +++ b/src/locate/postgre_locate.hpp @@ -0,0 +1,36 @@ +/* Copyright 2015, 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 id1AE05A59AE0E4A4490040FD85D9AF665 +#define id1AE05A59AE0E4A4490040FD85D9AF665 + +#include "dindexer-common/settings.hpp" +#include +#include +#include + +namespace din { + struct LocatedItem { + std::string path; + uint64_t id; + uint32_t group_id; + }; + + std::vector locate_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive ); +} //namespace din + +#endif