AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
UpdateFetcher Class Reference

#include "UpdateFetcher.h"

Classes

struct  AppliedFileEntry
 
struct  DirectoryEntry
 
struct  PathCompare
 

Public Member Functions

 UpdateFetcher (Path const &updateDirectory, std::function< void(std::string const &)> const &apply, std::function< void(Path const &path)> const &applyFile, std::function< QueryResult(std::string const &)> const &retrieve, std::string const &dbModuleName, std::vector< std::string > const *setDirectories=nullptr)
 
 UpdateFetcher (Path const &updateDirectory, std::function< void(std::string const &)> const &apply, std::function< void(Path const &path)> const &applyFile, std::function< QueryResult(std::string const &)> const &retrieve, std::string const &dbModuleName, std::string_view modulesList={})
 
 ~UpdateFetcher ()
 
UpdateResult Update (bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const
 

Private Types

enum  UpdateMode {
  MODE_APPLY ,
  MODE_REHASH
}
 
enum  State {
  RELEASED ,
  CUSTOM ,
  MODULE ,
  ARCHIVED
}
 
typedef std::filesystem::path Path
 
typedef std::pair< Path, StateLocaleFileEntry
 
typedef std::set< LocaleFileEntry, PathCompareLocaleFileStorage
 
typedef std::unordered_map< std::string, std::string > HashToFileNameStorage
 
typedef std::unordered_map< std::string, AppliedFileEntryAppliedFileStorage
 
typedef std::vector< UpdateFetcher::DirectoryEntryDirectoryStorage
 

Private Member Functions

LocaleFileStorage GetFileList () const
 
void FillFileListRecursively (Path const &path, LocaleFileStorage &storage, State const state, uint32 const depth) const
 
DirectoryStorage ReceiveIncludedDirectories () const
 
AppliedFileStorage ReceiveAppliedFiles () const
 
std::string ReadSQLUpdate (Path const &file) const
 
uint32 Apply (Path const &path) const
 
void UpdateEntry (AppliedFileEntry const &entry, uint32 const speed=0) const
 
void RenameEntry (std::string const &from, std::string const &to) const
 
void CleanUp (AppliedFileStorage const &storage) const
 
void UpdateState (std::string const &name, State const state) const
 

Private Attributes

std::unique_ptr< Path > const _sourceDirectory
 
std::function< void(std::string const &)> const _apply
 
std::function< void(Path const &path)> const _applyFile
 
std::function< QueryResult(std::string const &)> const _retrieve
 
std::string const _dbModuleName
 
std::vector< std::string > const * _setDirectories
 
std::string_view _modulesList = {}
 

Detailed Description

Member Typedef Documentation

◆ AppliedFileStorage

typedef std::unordered_map<std::string, AppliedFileEntry> UpdateFetcher::AppliedFileStorage
private

◆ DirectoryStorage

◆ HashToFileNameStorage

typedef std::unordered_map<std::string, std::string> UpdateFetcher::HashToFileNameStorage
private

◆ LocaleFileEntry

typedef std::pair<Path, State> UpdateFetcher::LocaleFileEntry
private

◆ LocaleFileStorage

◆ Path

typedef std::filesystem::path UpdateFetcher::Path
private

Member Enumeration Documentation

◆ State

enum UpdateFetcher::State
private
Enumerator
RELEASED 
CUSTOM 
MODULE 
ARCHIVED 
72 {
74 CUSTOM,
75 MODULE,
77 };
@ CUSTOM
Definition: UpdateFetcher.h:74
@ RELEASED
Definition: UpdateFetcher.h:73
@ ARCHIVED
Definition: UpdateFetcher.h:76
@ MODULE
Definition: UpdateFetcher.h:75

◆ UpdateMode

Enumerator
MODE_APPLY 
MODE_REHASH 
66 {
69 };
@ MODE_APPLY
Definition: UpdateFetcher.h:67
@ MODE_REHASH
Definition: UpdateFetcher.h:68

Constructor & Destructor Documentation

◆ UpdateFetcher() [1/2]

UpdateFetcher::UpdateFetcher ( Path const &  updateDirectory,
std::function< void(std::string const &)> const &  apply,
std::function< void(Path const &path)> const &  applyFile,
std::function< QueryResult(std::string const &)> const &  retrieve,
std::string const &  dbModuleName,
std::vector< std::string > const *  setDirectories = nullptr 
)
43 :
44 _sourceDirectory(std::make_unique<Path>(sourceDirectory)), _apply(apply), _applyFile(applyFile),
45 _retrieve(retrieve), _dbModuleName(dbModuleName), _setDirectories(setDirectories)
46{
47}
std::vector< std::string > const * _setDirectories
Definition: UpdateFetcher.h:163
std::function< void(std::string const &)> const _apply
Definition: UpdateFetcher.h:157
std::string const _dbModuleName
Definition: UpdateFetcher.h:162
std::unique_ptr< Path > const _sourceDirectory
Definition: UpdateFetcher.h:155
std::function< void(Path const &path)> const _applyFile
Definition: UpdateFetcher.h:158
std::function< QueryResult(std::string const &)> const _retrieve
Definition: UpdateFetcher.h:159

◆ UpdateFetcher() [2/2]

UpdateFetcher::UpdateFetcher ( Path const &  updateDirectory,
std::function< void(std::string const &)> const &  apply,
std::function< void(Path const &path)> const &  applyFile,
std::function< QueryResult(std::string const &)> const &  retrieve,
std::string const &  dbModuleName,
std::string_view  modulesList = {} 
)
54 :
55 _sourceDirectory(std::make_unique<Path>(sourceDirectory)), _apply(apply), _applyFile(applyFile),
56 _retrieve(retrieve), _dbModuleName(dbModuleName), _setDirectories(nullptr), _modulesList(modulesList)
57{
58}
std::string_view _modulesList
Definition: UpdateFetcher.h:164

◆ ~UpdateFetcher()

UpdateFetcher::~UpdateFetcher ( )
61{
62}

Member Function Documentation

◆ Apply()

uint32 UpdateFetcher::Apply ( Path const &  path) const
private
441{
442 using Time = std::chrono::high_resolution_clock;
443
444 // Benchmark query speed
445 auto const begin = Time::now();
446
447 // Update database
448 _applyFile(path);
449
450 // Return the time it took the query to apply
451 return uint32(std::chrono::duration_cast<std::chrono::milliseconds>(Time::now() - begin).count());
452}
std::uint32_t uint32
Definition: Define.h:107

References _applyFile.

Referenced by Update().

◆ CleanUp()

void UpdateFetcher::CleanUp ( AppliedFileStorage const &  storage) const
private
483{
484 if (storage.empty())
485 return;
486
487 std::stringstream update;
488 std::size_t remaining = storage.size();
489
490 update << "DELETE FROM `updates` WHERE `name` IN(";
491
492 for (auto const& entry : storage)
493 {
494 update << "\"" << entry.first << "\"";
495 if ((--remaining) > 0)
496 update << ", ";
497 }
498
499 update << ")";
500
501 // Update database
502 _apply(update.str());
503}

References _apply.

Referenced by Update().

◆ FillFileListRecursively()

void UpdateFetcher::FillFileListRecursively ( Path const &  path,
LocaleFileStorage storage,
State const  state,
uint32 const  depth 
) const
private
75{
76 static uint32 const MAX_DEPTH = 10;
77 static directory_iterator const end;
78
79 for (directory_iterator itr(path); itr != end; ++itr)
80 {
81 if (is_directory(itr->path()))
82 {
83 if (depth < MAX_DEPTH)
84 FillFileListRecursively(itr->path(), storage, state, depth + 1);
85 }
86 else if (itr->path().extension() == ".sql")
87 {
88 LOG_TRACE("sql.updates", "Added locale file \"{}\" state '{}'.", itr->path().filename().generic_string(), AppliedFileEntry::StateConvert(state));
89
90 LocaleFileEntry const entry = { itr->path(), state };
91
92 // Check for doubled filenames
93 // Because elements are only compared by their filenames, this is ok
94 if (storage.find(entry) != storage.end())
95 {
96 LOG_FATAL("sql.updates", "Duplicate filename \"{}\" occurred. Because updates are ordered " \
97 "by their filenames, every name needs to be unique!", itr->path().generic_string());
98
99 throw UpdateException("Updating failed, see the log for details.");
100 }
101
102 storage.insert(entry);
103 }
104 }
105}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:153
#define LOG_TRACE(filterType__,...)
Definition: Log.h:173
Definition: DBUpdater.h:39
void FillFileListRecursively(Path const &path, LocaleFileStorage &storage, State const state, uint32 const depth) const
Definition: UpdateFetcher.cpp:74
std::pair< Path, State > LocaleFileEntry
Definition: UpdateFetcher.h:126
static State StateConvert(std::string const &state)
Definition: UpdateFetcher.h:89

References FillFileListRecursively(), LOG_FATAL, LOG_TRACE, and UpdateFetcher::AppliedFileEntry::StateConvert().

Referenced by FillFileListRecursively(), and GetFileList().

◆ GetFileList()

UpdateFetcher::LocaleFileStorage UpdateFetcher::GetFileList ( ) const
private
65{
68 for (auto const& entry : directories)
69 FillFileListRecursively(entry.path, files, entry.state, 1);
70
71 return files;
72}
std::set< LocaleFileEntry, PathCompare > LocaleFileStorage
Definition: UpdateFetcher.h:133
std::vector< UpdateFetcher::DirectoryEntry > DirectoryStorage
Definition: UpdateFetcher.h:136
DirectoryStorage ReceiveIncludedDirectories() const
Definition: UpdateFetcher.cpp:107

References FillFileListRecursively(), and ReceiveIncludedDirectories().

Referenced by Update().

◆ ReadSQLUpdate()

std::string UpdateFetcher::ReadSQLUpdate ( Path const &  file) const
private
209{
210 std::ifstream in(file.c_str());
211 if (!in.is_open())
212 {
213 LOG_FATAL("sql.updates", "Failed to open the sql update \"{}\" for reading! "
214 "Stopping the server to keep the database integrity, "
215 "try to identify and solve the issue or disable the database updater.",
216 file.generic_string());
217
218 throw UpdateException("Opening the sql update failed!");
219 }
220
221 auto update = [&in]
222 {
223 std::ostringstream ss;
224 ss << in.rdbuf();
225 return ss.str();
226 }();
227
228 in.close();
229 return update;
230}

References LOG_FATAL.

Referenced by Update().

◆ ReceiveAppliedFiles()

UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles ( ) const
private
186{
188
189 QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, UNIX_TIMESTAMP(`timestamp`) FROM `updates` ORDER BY `name` ASC");
190 if (!result)
191 return map;
192
193 do
194 {
195 Field* fields = result->Fetch();
196
197 AppliedFileEntry const entry =
198 {
199 fields[0].Get<std::string>(), fields[1].Get<std::string>(), AppliedFileEntry::StateConvert(fields[2].Get<std::string>()), fields[3].Get<uint64>()
200 };
201
202 map.emplace(entry.name, entry);
203 } while (result->NextRow());
204
205 return map;
206}
std::uint64_t uint64
Definition: Define.h:106
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:27
Class used to access individual fields of database query result.
Definition: Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:112
std::unordered_map< std::string, AppliedFileEntry > AppliedFileStorage
Definition: UpdateFetcher.h:135

References _retrieve, Field::Get(), UpdateFetcher::AppliedFileEntry::name, and UpdateFetcher::AppliedFileEntry::StateConvert().

Referenced by Update().

◆ ReceiveIncludedDirectories()

UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories ( ) const
private
108{
109 DirectoryStorage directories;
110
111 if (_setDirectories)
112 {
113 for (auto const& itr : *_setDirectories)
114 {
115 std::string path = _sourceDirectory->generic_string() + itr;
116
117 Path const p(path);
118 if (!is_directory(p))
119 continue;
120
121 DirectoryEntry const entry = {p, AppliedFileEntry::StateConvert("MODULE")};
122 directories.push_back(entry);
123
124 LOG_TRACE("sql.updates", "Added applied extra file \"{}\" from remote.", p.filename().generic_string());
125 }
126 }
127 else
128 {
129 QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`");
130 if (!result)
131 return directories;
132
133 do
134 {
135 Field* fields = result->Fetch();
136
137 std::string path = fields[0].Get<std::string>();
138 std::string state = fields[1].Get<std::string>();
139 if (path.substr(0, 1) == "$")
140 path = _sourceDirectory->generic_string() + path.substr(1);
141
142 Path const p(path);
143
144 if (!is_directory(p))
145 {
146 LOG_WARN("sql.updates", "DBUpdater: Given update include directory \"{}\" does not exist, skipped!", p.generic_string());
147 continue;
148 }
149
150 DirectoryEntry const entry = {p, AppliedFileEntry::StateConvert(state)};
151 directories.push_back(entry);
152
153 LOG_TRACE("sql.updates", "Added applied file \"{}\" '{}' state from remote.", p.filename().generic_string(), state);
154
155 } while (result->NextRow());
156
157 std::vector<std::string> moduleList;
158
159 for (auto const& itr : Acore::Tokenize(_modulesList, ',', true))
160 {
161 moduleList.emplace_back(itr);
162 }
163
164 // data/sql
165 for (auto const& itr : moduleList)
166 {
167 std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/data/sql/db-world
168
169 Path const p(path);
170 if (!is_directory(p))
171 {
172 continue;
173 }
174
175 DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert("MODULE") };
176 directories.push_back(entry);
177
178 LOG_TRACE("sql.updates", "Added applied modules file \"{}\" from remote.", p.filename().generic_string());
179 }
180 }
181
182 return directories;
183}
#define LOG_WARN(filterType__,...)
Definition: Log.h:161
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Tokenize.cpp:20
std::filesystem::path Path
Definition: UpdateFetcher.h:44

References _dbModuleName, _modulesList, _retrieve, _setDirectories, _sourceDirectory, Field::Get(), LOG_TRACE, LOG_WARN, UpdateFetcher::AppliedFileEntry::StateConvert(), and Acore::Tokenize().

Referenced by GetFileList().

◆ RenameEntry()

void UpdateFetcher::RenameEntry ( std::string const &  from,
std::string const &  to 
) const
private
464{
465 // Delete the target if it exists
466 {
467 std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\"";
468
469 // Update database
470 _apply(update);
471 }
472
473 // Rename
474 {
475 std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\"";
476
477 // Update database
478 _apply(update);
479 }
480}

References _apply.

Referenced by Update().

◆ Update()

UpdateResult UpdateFetcher::Update ( bool const  redundancyChecks,
bool const  allowRehash,
bool const  archivedRedundancy,
int32 const  cleanDeadReferencesMaxCount 
) const
236{
237 LocaleFileStorage const available = GetFileList();
238 if (_setDirectories && available.empty())
239 {
240 return UpdateResult();
241 }
242
244
245 std::size_t countRecentUpdates = 0;
246 std::size_t countArchivedUpdates = 0;
247
248 // Count updates
249 for (auto const& entry : applied)
250 if (entry.second.state == RELEASED)
251 ++countRecentUpdates;
252 else
253 ++countArchivedUpdates;
254
255 // Fill hash to name cache
256 HashToFileNameStorage hashToName;
257 for (auto& entry : applied)
258 hashToName.insert(std::make_pair(entry.second.hash, entry.first));
259
260 std::size_t importedUpdates = 0;
261
262 auto ApplyUpdateFile = [&](LocaleFileEntry const& sqlFile)
263 {
264 auto filePath = sqlFile.first;
265 auto fileState = sqlFile.second;
266
267 LOG_DEBUG("sql.updates", "Checking update \"{}\"...", filePath.filename().generic_string());
268
269 AppliedFileStorage::const_iterator iter = applied.find(filePath.filename().string());
270 if (iter != applied.end())
271 {
272 // If redundancy is disabled, skip it, because the update is already applied.
273 if (!redundancyChecks)
274 {
275 LOG_DEBUG("sql.updates", ">> Update is already applied, skipping redundancy checks.");
276 applied.erase(iter);
277 return;
278 }
279
280 // If the update is in an archived directory and is marked as archived in our database, skip redundancy checks (archived updates never change).
281 if (!archivedRedundancy && (iter->second.state == ARCHIVED) && (sqlFile.second == ARCHIVED))
282 {
283 LOG_DEBUG("sql.updates", ">> Update is archived and marked as archived in database, skipping redundancy checks.");
284 applied.erase(iter);
285 return;
286 }
287 }
288
289 std::string const hash = ByteArrayToHexStr(Acore::Crypto::SHA1::GetDigestOf(ReadSQLUpdate(filePath)));
290
291 UpdateMode mode = MODE_APPLY;
292
293 // Update is not in our applied list
294 if (iter == applied.end())
295 {
296 // Catch renames (different filename, but same hash)
297 HashToFileNameStorage::const_iterator const hashIter = hashToName.find(hash);
298 if (hashIter != hashToName.end())
299 {
300 // Check if the original file was removed. If not, we've got a problem.
301 LocaleFileStorage::const_iterator localeIter;
302
303 // Push localeIter forward
304 for (localeIter = available.begin(); (localeIter != available.end()) &&
305 (localeIter->first.filename().string() != hashIter->second); ++localeIter);
306
307 // Conflict!
308 if (localeIter != available.end())
309 {
310 LOG_WARN("sql.updates", ">> It seems like the update \"{}\" \'{}\' was renamed, but the old file is still there! " \
311 "Treating it as a new file! (It is probably an unmodified copy of the file \"{}\")",
312 filePath.filename().string(), hash.substr(0, 7),
313 localeIter->first.filename().string());
314 }
315 else // It is safe to treat the file as renamed here
316 {
317 LOG_INFO("sql.updates", ">> Renaming update \"{}\" to \"{}\" \'{}\'.",
318 hashIter->second, filePath.filename().string(), hash.substr(0, 7));
319
320 RenameEntry(hashIter->second, filePath.filename().string());
321 applied.erase(hashIter->second);
322 return;
323 }
324 }
325 // Apply the update if it was never seen before.
326 else
327 {
328 LOG_INFO("sql.updates", ">> Applying update \"{}\" \'{}\'...",
329 filePath.filename().string(), hash.substr(0, 7));
330 }
331 }
332 // Rehash the update entry if it exists in our database with an empty hash.
333 else if (allowRehash && iter->second.hash.empty())
334 {
335 mode = MODE_REHASH;
336
337 LOG_INFO("sql.updates", ">> Re-hashing update \"{}\" \'{}\'...", filePath.filename().string(),
338 hash.substr(0, 7));
339 }
340 else
341 {
342 // If the hash of the files differs from the one stored in our database, reapply the update (because it changed).
343 if (iter->second.hash != hash)
344 {
345 LOG_INFO("sql.updates", ">> Reapplying update \"{}\" \'{}\' -> \'{}\' (it changed)...", filePath.filename().string(),
346 iter->second.hash.substr(0, 7), hash.substr(0, 7));
347 }
348 else
349 {
350 // If the file wasn't changed and just moved, update its state (if necessary).
351 if (iter->second.state != fileState)
352 {
353 LOG_DEBUG("sql.updates", ">> Updating the state of \"{}\" to \'{}\'...",
354 filePath.filename().string(), AppliedFileEntry::StateConvert(fileState));
355
356 UpdateState(filePath.filename().string(), fileState);
357 }
358
359 LOG_DEBUG("sql.updates", ">> Update is already applied and matches the hash \'{}\'.", hash.substr(0, 7));
360
361 applied.erase(iter);
362 return;
363 }
364 }
365
366 uint32 speed = 0;
367 AppliedFileEntry const file = { filePath.filename().string(), hash, fileState, 0 };
368
369 switch (mode)
370 {
371 case MODE_APPLY:
372 speed = Apply(filePath);
373 [[fallthrough]];
374 case MODE_REHASH:
375 UpdateEntry(file, speed);
376 break;
377 }
378
379 if (iter != applied.end())
380 applied.erase(iter);
381
382 if (mode == MODE_APPLY)
383 ++importedUpdates;
384 };
385
386 // Apply default updates
387 for (auto const& availableQuery : available)
388 {
389 if (availableQuery.second != CUSTOM && availableQuery.second != MODULE)
390 ApplyUpdateFile(availableQuery);
391 }
392
393 // Apply only custom/module updates
394 for (auto const& availableQuery : available)
395 {
396 if (availableQuery.second == CUSTOM || availableQuery.second == MODULE)
397 ApplyUpdateFile(availableQuery);
398 }
399
400 // Cleanup up orphaned entries (if enabled)
401 if (!applied.empty() && !_setDirectories)
402 {
403 bool const doCleanup = (cleanDeadReferencesMaxCount < 0) || (applied.size() <= static_cast<size_t>(cleanDeadReferencesMaxCount));
404
405 AppliedFileStorage toCleanup;
406 for (auto const& entry : applied)
407 {
408 if (entry.second.state != MODULE)
409 {
410 LOG_WARN("sql.updates",
411 ">> The file \'{}\' was applied to the database, but is missing in"
412 " your update directory now!",
413 entry.first);
414
415 if (doCleanup)
416 {
417 LOG_INFO("sql.updates", "Deleting orphaned entry \'{}\'...", entry.first);
418 toCleanup.insert(entry);
419 }
420 }
421 }
422
423 if (!toCleanup.empty())
424 {
425 if (doCleanup)
426 CleanUp(toCleanup);
427 else
428 {
429 LOG_ERROR("sql.updates",
430 "Cleanup is disabled! There were {} dirty files applied to your database, "
431 "but they are now missing in your source directory!",
432 toCleanup.size());
433 }
434 }
435 }
436
437 return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates);
438}
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
std::string ByteArrayToHexStr(Container const &c, bool reverse=false)
Definition: Util.h:381
static Digest GetDigestOf(uint8 const *data, std::size_t len)
Definition: CryptoHash.h:48
Definition: UpdateFetcher.h:30
uint32 Apply(Path const &path) const
Definition: UpdateFetcher.cpp:440
LocaleFileStorage GetFileList() const
Definition: UpdateFetcher.cpp:64
void UpdateState(std::string const &name, State const state) const
Definition: UpdateFetcher.cpp:505
UpdateMode
Definition: UpdateFetcher.h:66
std::string ReadSQLUpdate(Path const &file) const
Definition: UpdateFetcher.cpp:208
void UpdateEntry(AppliedFileEntry const &entry, uint32 const speed=0) const
Definition: UpdateFetcher.cpp:454
void RenameEntry(std::string const &from, std::string const &to) const
Definition: UpdateFetcher.cpp:463
std::unordered_map< std::string, std::string > HashToFileNameStorage
Definition: UpdateFetcher.h:134
AppliedFileStorage ReceiveAppliedFiles() const
Definition: UpdateFetcher.cpp:185
void CleanUp(AppliedFileStorage const &storage) const
Definition: UpdateFetcher.cpp:482

References _setDirectories, Apply(), ARCHIVED, ByteArrayToHexStr(), CleanUp(), CUSTOM, Acore::Impl::GenericHash< HashCreator, DigestLength >::GetDigestOf(), GetFileList(), LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, MODE_APPLY, MODE_REHASH, MODULE, ReadSQLUpdate(), ReceiveAppliedFiles(), RELEASED, RenameEntry(), UpdateFetcher::AppliedFileEntry::StateConvert(), UpdateEntry(), and UpdateState().

◆ UpdateEntry()

void UpdateFetcher::UpdateEntry ( AppliedFileEntry const &  entry,
uint32 const  speed = 0 
) const
private
455{
456 std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" +
457 entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")";
458
459 // Update database
460 _apply(update);
461}

References _apply, UpdateFetcher::AppliedFileEntry::GetStateAsString(), UpdateFetcher::AppliedFileEntry::hash, and UpdateFetcher::AppliedFileEntry::name.

Referenced by Update().

◆ UpdateState()

void UpdateFetcher::UpdateState ( std::string const &  name,
State const  state 
) const
private
506{
507 std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\"";
508
509 // Update database
510 _apply(update);
511}

References _apply, and UpdateFetcher::AppliedFileEntry::StateConvert().

Referenced by Update().

Member Data Documentation

◆ _apply

std::function<void(std::string const&)> const UpdateFetcher::_apply
private

◆ _applyFile

std::function<void(Path const& path)> const UpdateFetcher::_applyFile
private

Referenced by Apply().

◆ _dbModuleName

std::string const UpdateFetcher::_dbModuleName
private

◆ _modulesList

std::string_view UpdateFetcher::_modulesList = {}
private

◆ _retrieve

std::function<QueryResult(std::string const&)> const UpdateFetcher::_retrieve
private

◆ _setDirectories

std::vector<std::string> const* UpdateFetcher::_setDirectories
private

◆ _sourceDirectory

std::unique_ptr<Path> const UpdateFetcher::_sourceDirectory
private