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 
)
41 :
42 _sourceDirectory(std::make_unique<Path>(sourceDirectory)), _apply(apply), _applyFile(applyFile),
43 _retrieve(retrieve), _dbModuleName(dbModuleName), _setDirectories(setDirectories)
44{
45}
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 = {} 
)
52 :
53 _sourceDirectory(std::make_unique<Path>(sourceDirectory)), _apply(apply), _applyFile(applyFile),
54 _retrieve(retrieve), _dbModuleName(dbModuleName), _setDirectories(nullptr), _modulesList(modulesList)
55{
56}
std::string_view _modulesList
Definition: UpdateFetcher.h:164

◆ ~UpdateFetcher()

UpdateFetcher::~UpdateFetcher ( )
59{
60}

Member Function Documentation

◆ Apply()

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

References _applyFile.

Referenced by Update().

◆ CleanUp()

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

References _apply.

Referenced by Update().

◆ FillFileListRecursively()

void UpdateFetcher::FillFileListRecursively ( Path const &  path,
LocaleFileStorage storage,
State const  state,
uint32 const  depth 
) const
private
73{
74 static uint32 const MAX_DEPTH = 10;
75 static directory_iterator const end;
76
77 for (directory_iterator itr(path); itr != end; ++itr)
78 {
79 if (is_directory(itr->path()))
80 {
81 if (depth < MAX_DEPTH)
82 FillFileListRecursively(itr->path(), storage, state, depth + 1);
83 }
84 else if (itr->path().extension() == ".sql")
85 {
86 LOG_TRACE("sql.updates", "Added locale file \"{}\" state '{}'.", itr->path().filename().generic_string(), AppliedFileEntry::StateConvert(state));
87
88 LocaleFileEntry const entry = { itr->path(), state };
89
90 // Check for doubled filenames
91 // Because elements are only compared by their filenames, this is ok
92 if (storage.find(entry) != storage.end())
93 {
94 LOG_FATAL("sql.updates", "Duplicate filename \"{}\" occurred. Because updates are ordered " \
95 "by their filenames, every name needs to be unique!", itr->path().generic_string());
96
97 throw UpdateException("Updating failed, see the log for details.");
98 }
99
100 storage.insert(entry);
101 }
102 }
103}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
#define LOG_TRACE(filterType__,...)
Definition: Log.h:172
Definition: DBUpdater.h:38
void FillFileListRecursively(Path const &path, LocaleFileStorage &storage, State const state, uint32 const depth) const
Definition: UpdateFetcher.cpp:72
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
63{
66 for (auto const& entry : directories)
67 FillFileListRecursively(entry.path, files, entry.state, 1);
68
69 return files;
70}
std::set< LocaleFileEntry, PathCompare > LocaleFileStorage
Definition: UpdateFetcher.h:133
std::vector< UpdateFetcher::DirectoryEntry > DirectoryStorage
Definition: UpdateFetcher.h:136
DirectoryStorage ReceiveIncludedDirectories() const
Definition: UpdateFetcher.cpp:105

References FillFileListRecursively(), and ReceiveIncludedDirectories().

Referenced by Update().

◆ ReadSQLUpdate()

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

References LOG_FATAL.

Referenced by Update().

◆ ReceiveAppliedFiles()

UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles ( ) const
private
184{
186
187 QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, UNIX_TIMESTAMP(`timestamp`) FROM `updates` ORDER BY `name` ASC");
188 if (!result)
189 return map;
190
191 do
192 {
193 Field* fields = result->Fetch();
194
195 AppliedFileEntry const entry =
196 {
197 fields[0].Get<std::string>(), fields[1].Get<std::string>(), AppliedFileEntry::StateConvert(fields[2].Get<std::string>()), fields[3].Get<uint64>()
198 };
199
200 map.emplace(entry.name, entry);
201 } while (result->NextRow());
202
203 return map;
204}
std::uint64_t uint64
Definition: Define.h:106
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
Class used to access individual fields of database query result.
Definition: Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
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
106{
107 DirectoryStorage directories;
108
109 if (_setDirectories)
110 {
111 for (auto const& itr : *_setDirectories)
112 {
113 std::string path = _sourceDirectory->generic_string() + itr;
114
115 Path const p(path);
116 if (!is_directory(p))
117 continue;
118
119 DirectoryEntry const entry = {p, AppliedFileEntry::StateConvert("MODULE")};
120 directories.push_back(entry);
121
122 LOG_TRACE("sql.updates", "Added applied extra file \"{}\" from remote.", p.filename().generic_string());
123 }
124 }
125 else
126 {
127 QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`");
128 if (!result)
129 return directories;
130
131 do
132 {
133 Field* fields = result->Fetch();
134
135 std::string path = fields[0].Get<std::string>();
136 std::string state = fields[1].Get<std::string>();
137 if (path.substr(0, 1) == "$")
138 path = _sourceDirectory->generic_string() + path.substr(1);
139
140 Path const p(path);
141
142 if (!is_directory(p))
143 {
144 LOG_WARN("sql.updates", "DBUpdater: Given update include directory \"{}\" does not exist, skipped!", p.generic_string());
145 continue;
146 }
147
148 DirectoryEntry const entry = {p, AppliedFileEntry::StateConvert(state)};
149 directories.push_back(entry);
150
151 LOG_TRACE("sql.updates", "Added applied file \"{}\" '{}' state from remote.", p.filename().generic_string(), state);
152
153 } while (result->NextRow());
154
155 std::vector<std::string> moduleList;
156
157 for (auto const& itr : Acore::Tokenize(_modulesList, ',', true))
158 {
159 moduleList.emplace_back(itr);
160 }
161
162 // data/sql
163 for (auto const& itr : moduleList)
164 {
165 std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/data/sql/db-world
166
167 Path const p(path);
168 if (!is_directory(p))
169 {
170 continue;
171 }
172
173 DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert("MODULE") };
174 directories.push_back(entry);
175
176 LOG_TRACE("sql.updates", "Added applied modules file \"{}\" from remote.", p.filename().generic_string());
177 }
178 }
179
180 return directories;
181}
#define LOG_WARN(filterType__,...)
Definition: Log.h:160
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
462{
463 // Delete the target if it exists
464 {
465 std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\"";
466
467 // Update database
468 _apply(update);
469 }
470
471 // Rename
472 {
473 std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\"";
474
475 // Update database
476 _apply(update);
477 }
478}

References _apply.

Referenced by Update().

◆ Update()

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

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
453{
454 std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" +
455 entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")";
456
457 // Update database
458 _apply(update);
459}

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
504{
505 std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\"";
506
507 // Update database
508 _apply(update);
509}

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