1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2025-08-07 13:29:49 +00:00

Allow --tags option in locate command.

When a comma separated list of tags is specified, locate searches for
filenames matching the given glob that also belong to all of the
specified tags.
This commit is contained in:
King_DuckZ 2016-05-16 23:45:08 +02:00
parent 5832ca3374
commit 67bdabb548
4 changed files with 49 additions and 17 deletions

View file

@ -29,6 +29,7 @@ namespace din {
("case-insensitive,i", "Disable case sensitivity during search") ("case-insensitive,i", "Disable case sensitivity during search")
("set,s", "Look for matching sets instead of files") ("set,s", "Look for matching sets instead of files")
("byhash,a", "Paths on the command line are local paths and searching should be done by content hash") ("byhash,a", "Paths on the command line are local paths and searching should be done by content hash")
("tags,t", po::value<std::string>(), "Match files only if they belong to the listed tags")
//("option,o", po::value<std::string>()->default_value("default_value"), "Help message") //("option,o", po::value<std::string>()->default_value("default_value"), "Help message")
//("option2", po::value<int>(), "Help message") //("option2", po::value<int>(), "Help message")
; ;

View file

@ -18,6 +18,7 @@
#include "commandline.hpp" #include "commandline.hpp"
#include "postgre_locate.hpp" #include "postgre_locate.hpp"
#include "dindexer-common/settings.hpp" #include "dindexer-common/settings.hpp"
#include "dindexer-common/split_tags.hpp"
#include "dindexerConfig.h" #include "dindexerConfig.h"
#include "hash.hpp" #include "hash.hpp"
#include "glob2regex/glob2regex.hpp" #include "glob2regex/glob2regex.hpp"
@ -42,6 +43,15 @@ namespace din {
} }
} //namespace din } //namespace din
namespace {
std::vector<boost::string_ref> extract_tags (const boost::program_options::variables_map& parVM) {
if (not parVM.count("tags"))
return std::vector<boost::string_ref>();
else
return dinlib::split_tags(parVM["tags"].as<std::string>());
}
} //unnamed namespace
int main (int parArgc, char* parArgv[]) { int main (int parArgc, char* parArgv[]) {
using boost::program_options::variables_map; using boost::program_options::variables_map;
@ -76,14 +86,15 @@ int main (int parArgc, char* parArgv[]) {
} }
else { else {
std::vector<din::LocatedItem> results; std::vector<din::LocatedItem> results;
const std::vector<boost::string_ref> tags = extract_tags(vm);
if (vm.count("byhash")) { if (vm.count("byhash")) {
const auto hash = din::hash(vm["substring"].as<std::string>()); const auto hash = din::hash(vm["substring"].as<std::string>());
results = din::locate_in_db(settings.db, hash); results = din::locate_in_db(settings.db, hash, tags);
} }
else { else {
const auto search_regex = g2r::convert(vm["substring"].as<std::string>()); const auto search_regex = g2r::convert(vm["substring"].as<std::string>());
results = din::locate_in_db(settings.db, search_regex, not not vm.count("case-insensitive")); results = din::locate_in_db(settings.db, search_regex, not not vm.count("case-insensitive"), tags);
} }
std::copy(results.begin(), results.end(), std::ostream_iterator<din::LocatedItem>(std::cout, "\n")); std::copy(results.begin(), results.end(), std::ostream_iterator<din::LocatedItem>(std::cout, "\n"));
} }

View file

@ -68,29 +68,46 @@ namespace din {
return retval; return retval;
} }
template <typename... P>
std::vector<LocatedItem> locate_in_db (pq::Connection& parConn, const char* parBaseQuery, std::size_t parBaseQueryLength, const char* parTagsParamToken, const TagList& parTags, const P&... parParams) {
using boost::lexical_cast;
assert(parTagsParamToken or parTags.empty());
auto query = std::string(parBaseQuery, parBaseQueryLength);
if (not parTags.empty()) {
query += " AND \"tags\" @> ";
query += parTagsParamToken;
}
query += " LIMIT ";
query += lexical_cast<std::string>(g_max_results);
query += ";";
if (parTags.empty()) {
auto result = parConn.query(query, parParams...);
return file_result_to_vec(std::move(result));
}
else {
auto result = parConn.query(query, parParams..., parTags);
return file_result_to_vec(std::move(result));
}
}
} //unnamed namespace } //unnamed namespace
std::vector<LocatedItem> locate_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive) { std::vector<LocatedItem> locate_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive, const TagList& parTags) {
auto conn = make_pq_conn(parDB); auto conn = make_pq_conn(parDB);
const auto clean_string_with_quotes = conn.escaped_literal(parSearch); const auto clean_string_with_quotes = conn.escaped_literal(parSearch);
const std::string search_regex = (parCaseInsensitive ? "(?i)" : "") + parSearch; const std::string search_regex = (parCaseInsensitive ? "(?i)" : "") + parSearch;
const std::string query = const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"path\" ~ $1";
std::string("SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"path\" ~ $1 LIMIT ") + return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, search_regex);
boost::lexical_cast<std::string>(g_max_results) +
";";
auto result = conn.query(query, search_regex);
return file_result_to_vec(std::move(result));
} }
std::vector<LocatedItem> locate_in_db (const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch) { std::vector<LocatedItem> locate_in_db (const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags) {
const std::string query = std::string("SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"hash\"=$1 LIMIT ") + boost::lexical_cast<std::string>(g_max_results) + ';';
auto conn = make_pq_conn(parDB); auto conn = make_pq_conn(parDB);
auto result = conn.query(query, mchlib::tiger_to_string(parSearch, true)); const char base_query[] = "SELECT \"path\",\"id\",\"group_id\" FROM \"files\" WHERE \"hash\"=$1";
return file_result_to_vec(std::move(result)); return locate_in_db(conn, base_query, sizeof(base_query) - 1, "$2", parTags, mchlib::tiger_to_string(parSearch, true));
} }
std::vector<LocatedSet> locate_sets_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive) { std::vector<LocatedSet> locate_sets_in_db (const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive) {

View file

@ -22,6 +22,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <boost/utility/string_ref.hpp>
namespace mchlib { namespace mchlib {
struct TigerHash; struct TigerHash;
@ -41,8 +42,10 @@ namespace din {
uint32_t dir_count; uint32_t dir_count;
}; };
std::vector<LocatedItem> locate_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive ); using TagList = std::vector<boost::string_ref>;
std::vector<LocatedItem> locate_in_db ( const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch );
std::vector<LocatedItem> locate_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive, const TagList& parTags );
std::vector<LocatedItem> locate_in_db ( const dinlib::SettingsDB& parDB, const mchlib::TigerHash& parSearch, const TagList& parTags );
std::vector<LocatedSet> locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive ); std::vector<LocatedSet> locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, bool parCaseInsensitive );
std::vector<LocatedSet> locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, const std::vector<uint32_t>& parSets, bool parCaseInsensitive ); std::vector<LocatedSet> locate_sets_in_db ( const dinlib::SettingsDB& parDB, const std::string& parSearch, const std::vector<uint32_t>& parSets, bool parCaseInsensitive );
} //namespace din } //namespace din