mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-02-17 11:45:50 +00:00
Don't save to DB if the disk has been added already.
This commit is contained in:
parent
e957fde12c
commit
8b9241757d
5 changed files with 79 additions and 9 deletions
|
@ -21,6 +21,8 @@
|
|||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace din {
|
||||
namespace {
|
||||
|
@ -36,6 +38,53 @@ namespace din {
|
|||
}
|
||||
} //unnamed namespace
|
||||
|
||||
bool read_from_db (FileRecordData& parItem, SetRecordDataFull& parSet, const DinDBSettings& parDB, std::string&& parHash) {
|
||||
using boost::lexical_cast;
|
||||
|
||||
pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port);
|
||||
conn.connect();
|
||||
|
||||
uint32_t group_id;
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "SELECT path,level,group_id,is_directory,is_symlink,size FROM files WHERE hash=" <<
|
||||
conn.escaped_literal(parHash) <<
|
||||
" LIMIT 1;";
|
||||
|
||||
auto resultset = conn.query(oss.str());
|
||||
if (resultset.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = resultset[0];
|
||||
parItem.path = row["path"];
|
||||
parItem.hash = std::move(parHash);
|
||||
parItem.level = lexical_cast<uint16_t>(row["level"]);
|
||||
parItem.size = lexical_cast<uint64_t>(row["size"]);
|
||||
parItem.is_directory = (row["is_directory"] == "t" ? true : false);
|
||||
parItem.is_symlink = (row["is_symlink"] == "t" ? true : false);
|
||||
group_id = lexical_cast<uint32_t>(row["group_id"]);
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "SELECT \"desc\",\"type\",\"disk_number\" FROM sets WHERE \"id\"=" << group_id << ';';
|
||||
|
||||
auto resultset = conn.query(oss.str());
|
||||
if (resultset.empty()) {
|
||||
std::ostringstream err_msg;
|
||||
err_msg << "Missing set: found a record with group_id=" << group_id;
|
||||
err_msg << " but there is no such id in table \"sets\"";
|
||||
throw std::length_error(err_msg.str());
|
||||
}
|
||||
auto row = resultset[0];
|
||||
parSet.type = lexical_cast<char>(row["type"]);
|
||||
parSet.name = row["desc"];
|
||||
parSet.disk_number = lexical_cast<uint32_t>(row["disk_number"]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_to_db (const DinDBSettings& parDB, const std::vector<FileRecordData>& parData, const SetRecordData& parSetData) {
|
||||
if (parData.empty()) {
|
||||
return;
|
||||
|
|
|
@ -27,12 +27,18 @@ namespace din {
|
|||
struct DinDBSettings;
|
||||
|
||||
struct FileRecordData {
|
||||
const std::string path;
|
||||
const std::string hash;
|
||||
const uint16_t level;
|
||||
const uint64_t size;
|
||||
const bool is_directory;
|
||||
const bool is_symlink;
|
||||
std::string path;
|
||||
std::string hash;
|
||||
uint16_t level;
|
||||
uint64_t size;
|
||||
bool is_directory;
|
||||
bool is_symlink;
|
||||
};
|
||||
|
||||
struct SetRecordDataFull {
|
||||
std::string name;
|
||||
uint32_t disk_number;
|
||||
char type;
|
||||
};
|
||||
|
||||
struct SetRecordData {
|
||||
|
@ -41,6 +47,7 @@ namespace din {
|
|||
};
|
||||
|
||||
void write_to_db ( const DinDBSettings& parDB, const std::vector<FileRecordData>& parData, const SetRecordData& parSetData );
|
||||
bool read_from_db ( FileRecordData& parItem, SetRecordDataFull& parSet, const DinDBSettings& parDB, std::string&& parHash );
|
||||
} //namespace din
|
||||
|
||||
#endif
|
||||
|
|
|
@ -277,10 +277,21 @@ namespace din {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Indexer::add_to_db (const std::string& parSetName, char parType) const {
|
||||
bool Indexer::add_to_db (const std::string& parSetName, char parType, bool parForce) const {
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
assert(m_local_data->done_count == m_local_data->file_count);
|
||||
#endif
|
||||
|
||||
if (not parForce) {
|
||||
std::string first_hash(tiger_to_string(m_local_data->paths.front().hash, true));
|
||||
FileRecordData itm;
|
||||
SetRecordDataFull set;
|
||||
const bool already_in_db = read_from_db(itm, set, m_local_data->db_settings, std::move(first_hash));
|
||||
if (already_in_db) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PathName base_path(m_local_data->paths.front().path);
|
||||
std::vector<FileRecordData> data;
|
||||
data.reserve(m_local_data->paths.size());
|
||||
|
@ -297,6 +308,7 @@ namespace din {
|
|||
|
||||
SetRecordData set_data {parSetName, parType};
|
||||
write_to_db(m_local_data->db_settings, data, set_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Indexer::add_path (const char* parPath, int parLevel, bool parIsDir, bool parIsSymLink) {
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace din {
|
|||
std::condition_variable& step_notify ( void );
|
||||
#endif
|
||||
void calculate_hash ( void );
|
||||
void add_to_db ( const std::string& parSetName, char parType ) const;
|
||||
bool add_to_db ( const std::string& parSetName, char parType, bool parForce=false ) const;
|
||||
bool empty ( void ) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -94,7 +94,9 @@ int main (int parArgc, char* parArgv[]) {
|
|||
if (verbose) {
|
||||
std::cout << "Writing to database...\n";
|
||||
}
|
||||
indexer.add_to_db(vm["setname"].as<std::string>(), vm["type"].as<char>());
|
||||
if (not indexer.add_to_db(vm["setname"].as<std::string>(), vm["type"].as<char>())) {
|
||||
std::cerr << "Not written to DB, likely because a set with the same hash already exists\n";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue