Loading newsgroup list from database implemented
This commit is contained in:
parent
fbc9964ea6
commit
5645d31f59
|
@ -18,6 +18,7 @@
|
|||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "usenetsearch/UsenetClient.h"
|
||||
|
@ -26,10 +27,18 @@ namespace usenetsearch {
|
|||
|
||||
static constexpr const std::uint64_t DatabaseVersion{1};
|
||||
|
||||
struct DatabaseException: public UsenetSearchException
|
||||
{
|
||||
DatabaseException(int errorCode, const std::string& message):
|
||||
UsenetSearchException(errorCode, message){}
|
||||
|
||||
virtual ~DatabaseException() = default;
|
||||
};
|
||||
|
||||
class Database{
|
||||
|
||||
std::filesystem::path m_databasePath;
|
||||
std::uint64_t m_databaseVersion{0};
|
||||
std::uint64_t m_databaseVersion{DatabaseVersion};
|
||||
std::ifstream m_newsGroupFileInput;
|
||||
std::ofstream m_newsGroupFileOutput;
|
||||
|
||||
|
@ -38,6 +47,7 @@ class Database{
|
|||
public:
|
||||
|
||||
~Database();
|
||||
std::unique_ptr<std::vector<NntpListEntry>> LoadNewsgroupList();
|
||||
void Open(std::filesystem::path dbPath);
|
||||
void UpdateNewsgroupList(const std::vector<NntpListEntry>& list);
|
||||
|
||||
|
|
|
@ -36,6 +36,38 @@ Database::~Database()
|
|||
m_newsGroupFileOutput.close();
|
||||
}
|
||||
}
|
||||
std::unique_ptr<std::vector<NntpListEntry>> Database::LoadNewsgroupList()
|
||||
{
|
||||
OpenNewsGroupFile();
|
||||
|
||||
std::uint64_t dbVersion{0};
|
||||
m_newsGroupFileInput.read(
|
||||
reinterpret_cast<char*>(&dbVersion),
|
||||
sizeof(dbVersion)
|
||||
);
|
||||
if (dbVersion != m_databaseVersion)
|
||||
{
|
||||
throw DatabaseException(EINVAL,
|
||||
"The loaded database version (" + std::to_string(dbVersion)
|
||||
+ ") does not match the current database version ("
|
||||
+ std::to_string(m_databaseVersion) + ")");
|
||||
}
|
||||
|
||||
size_t newsGroupCount{0};
|
||||
m_newsGroupFileInput.read(
|
||||
reinterpret_cast<char*>(&newsGroupCount),
|
||||
sizeof(newsGroupCount)
|
||||
);
|
||||
|
||||
auto result = std::make_unique<std::vector<NntpListEntry>>();
|
||||
for (size_t numLoaded = 0; numLoaded != newsGroupCount; ++numLoaded)
|
||||
{
|
||||
NntpListEntry entry;
|
||||
m_newsGroupFileInput >> entry;
|
||||
result->emplace_back(entry);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Database::Open(std::filesystem::path dbPath)
|
||||
{
|
||||
|
@ -68,15 +100,18 @@ void Database::OpenNewsGroupFile()
|
|||
void Database::UpdateNewsgroupList(const std::vector<NntpListEntry>& list)
|
||||
{
|
||||
OpenNewsGroupFile();
|
||||
|
||||
m_newsGroupFileOutput.write(
|
||||
reinterpret_cast<const char*>(&m_databaseVersion),
|
||||
sizeof(m_databaseVersion)
|
||||
);
|
||||
const size_t newsGroupCount = list.size();
|
||||
|
||||
const std::uint64_t newsGroupCount = list.size();
|
||||
m_newsGroupFileOutput.write(
|
||||
reinterpret_cast<const char*>(&newsGroupCount),
|
||||
sizeof(newsGroupCount)
|
||||
);
|
||||
|
||||
for (const auto& entry: list)
|
||||
{
|
||||
m_newsGroupFileOutput << entry;
|
||||
|
|
|
@ -35,7 +35,7 @@ std::ifstream& operator>>(std::ifstream& in, std::string& str)
|
|||
{
|
||||
std::uint64_t size{0};
|
||||
in.read(reinterpret_cast<char*>(&size), sizeof(size));
|
||||
char buf[size];
|
||||
char buf[size + 1];
|
||||
in.read(buf, size);
|
||||
buf[size] = 0;
|
||||
str = buf;
|
||||
|
@ -57,7 +57,7 @@ std::ifstream& operator>>(std::ifstream& in, std::wstring& str)
|
|||
{
|
||||
std::uint64_t size{0};
|
||||
in.read(reinterpret_cast<char*>(&size), sizeof(size));
|
||||
wchar_t buf[size];
|
||||
wchar_t buf[size + 1];
|
||||
in.read(reinterpret_cast<char*>(buf), size * sizeof(wchar_t));
|
||||
buf[size] = 0;
|
||||
str = buf;
|
||||
|
|
|
@ -75,6 +75,7 @@ int main(int argc, char* argv[])
|
|||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
|
||||
try
|
||||
{
|
||||
|
||||
client.Connect(
|
||||
config.NNTPServerHost(),
|
||||
config.NNTPServerPort(),
|
||||
|
@ -88,8 +89,13 @@ int main(int argc, char* argv[])
|
|||
// Just testing the list command for now.
|
||||
const auto list = client.List();
|
||||
db.UpdateNewsgroupList(list);
|
||||
std::cout << "Number of newsgroups in newsgroup list: "
|
||||
std::cout << "Number of newsgroups in newsgroup list (saved): "
|
||||
<< list.size() << std::endl;
|
||||
|
||||
const auto listLoaded = db.LoadNewsgroupList();
|
||||
std::cout << "Number of newsgroups in newsgroup list (loaded): "
|
||||
<< listLoaded->size() << std::endl;
|
||||
|
||||
}
|
||||
catch (const usenetsearch::UsenetSearchException& e)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue