mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2024-11-29 01:33:46 +00:00
Implement tag deletion.
This commit is contained in:
parent
adcdf56254
commit
7cfc25aeeb
5 changed files with 146 additions and 17 deletions
|
@ -9,6 +9,7 @@ add_executable(${PROJECT_NAME}
|
|||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/lib/glob2regex/include
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/lib/better-enums
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
|
|
|
@ -27,7 +27,8 @@ 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()
|
||||
//("switch,s", "Help message")
|
||||
("delete,d", "Delete tags instead of adding")
|
||||
("alltags,a", "Only allowed when --delete is also specified - ignores any given tag list and delete all tags associated to the matching elements instead")
|
||||
//("option,o", po::value<std::string>()->default_value("default_value"), "Help message")
|
||||
("ids", po::value<std::string>(), "Comma-separated list of IDs of files to be tagged")
|
||||
("set,s", po::value<uint32_t>(), "Limit matching to files belonging to the specified set ID")
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tag_postgres.hpp"
|
||||
#include "dindexer-common/split_tags.hpp"
|
||||
#include "glob2regex/glob2regex.hpp"
|
||||
#include "enum.h"
|
||||
#include <iostream>
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
||||
|
@ -29,10 +30,9 @@
|
|||
#include <iterator>
|
||||
|
||||
namespace {
|
||||
enum TaggingModes {
|
||||
TaggingMode_Glob,
|
||||
TaggingMode_ID
|
||||
};
|
||||
BETTER_ENUM(TaggingMode, char,
|
||||
Glob, ID
|
||||
);
|
||||
|
||||
std::vector<std::string> globs_to_regex_list (const std::vector<std::string>& parGlobs) {
|
||||
std::vector<std::string> retval;
|
||||
|
@ -46,10 +46,7 @@ namespace {
|
|||
return retval;
|
||||
}
|
||||
|
||||
int tag_files (const dinlib::SettingsDB& parDB, TaggingModes parMode, const boost::program_options::variables_map& parVM, const std::vector<boost::string_ref>& parTags) {
|
||||
using boost::lexical_cast;
|
||||
using boost::string_ref;
|
||||
|
||||
din::OwnerSetInfo make_owner_set_info (const boost::program_options::variables_map& parVM) {
|
||||
din::OwnerSetInfo set_info;
|
||||
if (parVM.count("set")) {
|
||||
set_info.is_valid = true;
|
||||
|
@ -59,9 +56,17 @@ namespace {
|
|||
set_info.is_valid = false;
|
||||
set_info.group_id = 0;
|
||||
}
|
||||
return set_info;
|
||||
}
|
||||
|
||||
int tag_files (const dinlib::SettingsDB& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector<boost::string_ref>& parTags) {
|
||||
using boost::lexical_cast;
|
||||
using boost::string_ref;
|
||||
|
||||
const din::OwnerSetInfo set_info = make_owner_set_info(parVM);
|
||||
|
||||
switch (parMode) {
|
||||
case TaggingMode_ID:
|
||||
case TaggingMode::ID:
|
||||
{
|
||||
auto ids_string = dinlib::split_tags(parVM["ids"].as<std::string>());
|
||||
std::vector<uint64_t> ids;
|
||||
|
@ -71,7 +76,7 @@ namespace {
|
|||
return 0;
|
||||
}
|
||||
|
||||
case TaggingMode_Glob:
|
||||
case TaggingMode::Glob:
|
||||
{
|
||||
const auto regexes(globs_to_regex_list(parVM["globs"].as<std::vector<std::string>>()));
|
||||
din::tag_files(parDB, regexes, parTags, set_info);
|
||||
|
@ -83,6 +88,42 @@ namespace {
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int delete_tags (const dinlib::SettingsDB& parDB, TaggingMode parMode, const boost::program_options::variables_map& parVM, const std::vector<boost::string_ref>& parTags) {
|
||||
using boost::lexical_cast;
|
||||
using boost::string_ref;
|
||||
|
||||
assert(parVM.count("delete"));
|
||||
|
||||
switch (parMode) {
|
||||
case TaggingMode::ID:
|
||||
{
|
||||
auto ids_string = dinlib::split_tags(parVM["ids"].as<std::string>());
|
||||
std::vector<uint64_t> ids;
|
||||
ids.reserve(ids_string.size());
|
||||
std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast<uint64_t, string_ref>);
|
||||
if (parVM.count("alltags"))
|
||||
din::delete_all_tags(parDB, ids, make_owner_set_info(parVM));
|
||||
else
|
||||
din::delete_tags(parDB, ids, parTags, make_owner_set_info(parVM));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case TaggingMode::Glob:
|
||||
{
|
||||
const auto regexes(globs_to_regex_list(parVM["globs"].as<std::vector<std::string>>()));
|
||||
if (parVM.count("alltags"))
|
||||
din::delete_all_tags(parDB, regexes, make_owner_set_info(parVM));
|
||||
else
|
||||
din::delete_tags(parDB, regexes, parTags, make_owner_set_info(parVM));
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
int main (int parArgc, char* parArgv[]) {
|
||||
|
@ -122,11 +163,10 @@ int main (int parArgc, char* parArgv[]) {
|
|||
|
||||
const auto master_tags_string = vm["tags"].as<std::string>();
|
||||
const std::vector<boost::string_ref> tags = dinlib::split_tags(master_tags_string);
|
||||
const auto mode = (glob_mode ? TaggingMode::Glob : TaggingMode::ID);
|
||||
|
||||
return tag_files(
|
||||
settings.db,
|
||||
(glob_mode ? TaggingMode_Glob : TaggingMode_ID),
|
||||
vm,
|
||||
tags
|
||||
);
|
||||
if (not vm.count("delete"))
|
||||
return tag_files(settings.db, mode, vm, tags);
|
||||
else
|
||||
return delete_tags(settings.db, mode, vm, tags);
|
||||
}
|
||||
|
|
|
@ -70,4 +70,86 @@ namespace din {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void delete_tags (const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& 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();
|
||||
|
||||
if (parTags.size() == 1) {
|
||||
if (parSet.is_valid) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"id\" = ANY($2);";
|
||||
conn.query(query, parTags.front(), parFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (parSet.is_valid) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void delete_tags (const dinlib::SettingsDB& parDB, const std::vector<std::string>& parRegexes, const std::vector<boost::string_ref>& 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();
|
||||
|
||||
if (parTags.size() == 1) {
|
||||
if (parSet.is_valid) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
const std::string query = "UPDATE \"files\" SET \"tags\" = ARRAY_REMOVE(tags, $1) WHERE \"path\" ~ ANY($2);";
|
||||
conn.query(query, parTags.front(), parRegexes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (parSet.is_valid) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void delete_all_tags (const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& 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();
|
||||
|
||||
if (parSet.is_valid) {
|
||||
const std::string query =
|
||||
"UPDATE \"files\" SET \"tags\" = '{}' WHERE \"id\"=ANY($1) AND \"group_id\"=$2;";
|
||||
conn.query(query, parFiles, parSet.group_id);
|
||||
}
|
||||
else {
|
||||
const std::string query =
|
||||
"UPDATE \"files\" SET \"tags\" = '{}' WHERE \"id\"=ANY($1);";
|
||||
conn.query(query, parFiles);
|
||||
}
|
||||
}
|
||||
|
||||
void delete_all_tags (const dinlib::SettingsDB& parDB, const std::vector<std::string>& 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();
|
||||
|
||||
if (parSet.is_valid) {
|
||||
const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"group_id\"=$1 AND \"path\" ~ ANY($2);";
|
||||
conn.query(query, parSet.group_id, parRegexes);
|
||||
}
|
||||
else {
|
||||
const std::string query = "UPDATE \"files\" SET \"tags\" = '{}' WHERE \"path\" ~ ANY($2);";
|
||||
conn.query(query, parRegexes);
|
||||
}
|
||||
}
|
||||
} //namespace din
|
||||
|
|
|
@ -34,6 +34,11 @@ namespace din {
|
|||
|
||||
void tag_files ( const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags, OwnerSetInfo parSet );
|
||||
void tag_files ( const dinlib::SettingsDB& parDB, const std::vector<std::string>& parRegexes, const std::vector<boost::string_ref>& parTags, OwnerSetInfo parSet );
|
||||
|
||||
void delete_tags ( const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags, OwnerSetInfo parSet );
|
||||
void delete_tags ( const dinlib::SettingsDB& parDB, const std::vector<std::string>& parRegexes, const std::vector<boost::string_ref>& parTags, OwnerSetInfo parSet );
|
||||
void delete_all_tags ( const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, OwnerSetInfo parSet );
|
||||
void delete_all_tags ( const dinlib::SettingsDB& parDB, const std::vector<std::string>& parRegexes, OwnerSetInfo parSet );
|
||||
} //namespace din
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue