/* 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 "locate.hpp"
#include "dindexer-machinery/recorddata.hpp"
#include "pq/connection.hpp"
#include "query_count_limit.hpp"
#include "dindexer-machinery/tiger.hpp"
#include
#include
#include
#include
namespace dindb {
namespace {
const int g_max_results = g_query_count_limit;
std::vector sets_result_to_vec (pq::ResultSet&& parResult) {
using boost::lexical_cast;
std::vector retval;
retval.reserve(parResult.size());
for (const auto& record : parResult) {
retval.push_back(LocatedSet{
record["desc"],
lexical_cast(record["id"]),
lexical_cast(record["file_count"]),
lexical_cast(record["dir_count"])
});
}
return retval;
}
std::vector file_result_to_vec (pq::ResultSet&& parResult) {
using boost::lexical_cast;
std::vector retval;
retval.reserve(parResult.size());
for (const auto& record : parResult) {
retval.push_back(LocatedItem{
record["path"],
lexical_cast(record["id"]),
lexical_cast(record["group_id"])
});
}
return retval;
}
template
std::vector 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(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
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(parDB, base_query, sizeof(base_query) - 1, "$2", parTags, parSearch);
}
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(parDB, base_query, sizeof(base_query) - 1, "$2", parTags, mchlib::tiger_to_string(parSearch, true));
}
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\", "
"(SELECT COUNT(*) FROM \"files\" WHERE \"group_id\"=\"sets\".\"id\" AND \"is_directory\") as \"dir_count\" "
"FROM \"sets\" WHERE str_match_partial(\"desc\", $1, $2) LIMIT "
) + std::to_string(g_max_results) + ";";
auto result = parDB.query(query, parSearch, parCaseInsensitive);
return sets_result_to_vec(std::move(result));
}
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);
}
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\", "
"(SELECT COUNT(*) FROM \"files\" WHERE \"group_id\"=\"sets\".\"id\" AND \"is_directory\") as \"dir_count\" "
"FROM \"sets\" WHERE \"id\" = ANY($1) AND str_match_partial(\"desc\", $3, $2) LIMIT "
) + std::to_string(g_max_results) + ";";
auto result = parDB.query(query, parSearch, parCaseInsensitive, parSets);
return sets_result_to_vec(std::move(result));
}
} //namespace dindb