39 lines
1.5 KiB
C++
39 lines
1.5 KiB
C++
#include "database.h"
|
|
|
|
#include "subcommands.h"
|
|
|
|
static inline void is_file(sqlite3_context* context, int argc, sqlite3_value** argv);
|
|
|
|
void subcommand_prune(const Parser& parser) {
|
|
if (parser.arguments.size() != 1) {
|
|
fprintf(stderr, HELP_TEXT, parser.program_name);
|
|
exit(1);
|
|
}
|
|
|
|
Database db = Database::find(false);
|
|
|
|
// https://stackoverflow.com/a/4929486
|
|
int error_code = sqlite3_create_function(db.db.get(), "is_file", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY, &db.path, is_file, nullptr, nullptr);
|
|
if (error_code != SQLITE_OK) {
|
|
throw Sqlite3Exception(error_code, &db.db);
|
|
}
|
|
Sqlite3Statement delete_stmt(db.db, "DELETE FROM memes WHERE NOT is_file(path)");
|
|
db.db.exec(delete_stmt);
|
|
sqlite3_create_function(db.db.get(), "is_file", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY, &db.path, nullptr, nullptr, nullptr);
|
|
|
|
Sqlite3Statement vacuum_stmt(db.db, "VACUUM");
|
|
db.db.exec(vacuum_stmt);
|
|
}
|
|
|
|
static inline void is_file(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
|
if (argc != 1) {
|
|
sqlite3_result_error(context, "is_file() expects one argument", -1);
|
|
sqlite3_result_error_code(context, SQLITE_MISUSE);
|
|
return;
|
|
}
|
|
|
|
const std::filesystem::path* db_path = static_cast<const std::filesystem::path*>(sqlite3_user_data(context));
|
|
std::filesystem::path file_path = db_path->parent_path() / reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
|
|
sqlite3_result_int(context, std::filesystem::is_regular_file(file_path));
|
|
}
|