65 static uint32 const MAX_DEPTH = 10;
66 static directory_iterator
const end;
68 for (directory_iterator itr(path); itr != end; ++itr)
70 if (is_directory(itr->path()))
72 if (depth < MAX_DEPTH)
75 else if (itr->path().extension() ==
".sql")
77 TC_LOG_TRACE(
"sql.updates",
"Added locale file \"{}\".", itr->path().filename().generic_string());
83 if (storage.find(entry) != storage.end())
85 TC_LOG_FATAL(
"sql.updates",
"Duplicate filename \"{}\" occurred. Because updates are ordered " \
86 "by their filenames, every name needs to be unique!", itr->path().generic_string());
91 storage.insert(entry);
176 bool const allowRehash,
177 bool const archivedRedundancy,
178 int32 const cleanDeadReferencesMaxCount)
const
183 size_t countRecentUpdates = 0;
184 size_t countArchivedUpdates = 0;
187 for (
auto const& entry : applied)
189 ++countRecentUpdates;
191 ++countArchivedUpdates;
195 for (
auto entry : applied)
196 hashToName.insert(std::make_pair(entry.second.hash, entry.first));
198 size_t importedUpdates = 0;
200 for (
auto const& availableQuery : available)
202 TC_LOG_DEBUG(
"sql.updates",
"Checking update \"{}\"...", availableQuery.first.filename().generic_string());
204 AppliedFileStorage::const_iterator iter = applied.find(availableQuery.first.filename().string());
205 if (iter != applied.end())
208 if (!redundancyChecks)
210 TC_LOG_DEBUG(
"sql.updates",
">> Update is already applied, skipping redundancy checks.");
216 if (!archivedRedundancy && (iter->second.state ==
ARCHIVED) && (availableQuery.second ==
ARCHIVED))
218 TC_LOG_DEBUG(
"sql.updates",
">> Update is archived and marked as archived in database, skipping redundancy checks.");
230 if (iter == applied.end())
233 HashToFileNameStorage::const_iterator
const hashIter = hashToName.find(hash);
234 if (hashIter != hashToName.end())
237 LocaleFileStorage::const_iterator localeIter;
239 for (localeIter = available.begin(); (localeIter != available.end()) &&
240 (localeIter->first.filename().string() != hashIter->second); ++localeIter);
243 if (localeIter != available.end())
245 TC_LOG_WARN(
"sql.updates",
">> It seems like the update \"{}\" \'{}\' was renamed, but the old file is still there! " \
246 "Treating it as a new file! (It is probably an unmodified copy of the file \"{}\")",
247 availableQuery.first.filename().string(), hash.substr(0, 7),
248 localeIter->first.filename().string());
253 TC_LOG_INFO(
"sql.updates",
">> Renaming update \"{}\" to \"{}\" \'{}\'.",
254 hashIter->second, availableQuery.first.filename().string(), hash.substr(0, 7));
256 RenameEntry(hashIter->second, availableQuery.first.filename().string());
257 applied.erase(hashIter->second);
264 TC_LOG_INFO(
"sql.updates",
">> Applying update \"{}\" \'{}\'...",
265 availableQuery.first.filename().string(), hash.substr(0, 7));
269 else if (allowRehash && iter->second.hash.empty())
273 TC_LOG_INFO(
"sql.updates",
">> Re-hashing update \"{}\" \'{}\'...", availableQuery.first.filename().string(),
279 if (iter->second.hash != hash)
281 TC_LOG_INFO(
"sql.updates",
">> Reapplying update \"{}\" \'{}\' -> \'{}\' (it changed)...", availableQuery.first.filename().string(),
282 iter->second.hash.substr(0, 7), hash.substr(0, 7));
287 if (iter->second.state != availableQuery.second)
289 TC_LOG_DEBUG(
"sql.updates",
">> Updating the state of \"{}\" to \'{}\'...",
292 UpdateState(availableQuery.first.filename().string(), availableQuery.second);
295 TC_LOG_DEBUG(
"sql.updates",
">> Update is already applied and matches the hash \'{}\'.", hash.substr(0, 7));
303 AppliedFileEntry const file = { availableQuery.first.filename().string(), hash, availableQuery.second, 0 };
308 speed =
Apply(availableQuery.first);
315 if (iter != applied.end())
323 if (!applied.empty())
325 bool const doCleanup = (cleanDeadReferencesMaxCount < 0) || (applied.size() <=
static_cast<size_t>(cleanDeadReferencesMaxCount));
327 for (
auto const& entry : applied)
329 TC_LOG_WARN(
"sql.updates",
">> The file \'{}\' was applied to the database, but is missing in" \
330 " your update directory now!", entry.first);
333 TC_LOG_INFO(
"sql.updates",
"Deleting orphaned entry \'{}\'...", entry.first);
340 TC_LOG_ERROR(
"sql.updates",
"Cleanup is disabled! There were {} dirty files applied to your database, " \
341 "but they are now missing in your source directory!", applied.size());
345 return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates);
std::string GetStateAsString() const
static State StateConvert(std::string const &state)
DirectoryEntry(Path const &path_, State state_)