#include "base_generator.h" #include #include BaseGenerator::ShouldLogSuccess BaseGenerator::shouldLogAllSuccesses() const noexcept { return [this]() { return true; }; } BaseGenerator::ShouldLogSuccess BaseGenerator::shouldLogEveryNPercent(int percent) const noexcept { if (percent <= 0) { return [this]() { return false; }; } int oldLastPercentage = 0; return [this, percent, oldLastPercentage]() mutable { if (oldLastPercentage == lastPercentage_) { return false; } oldLastPercentage = lastPercentage_; return !bool(lastPercentage_ % percent); }; } BaseGenerator::ShouldLogSuccess BaseGenerator::shouldLogFirstAndLastPercent() const noexcept { return [this]() { return createdRecords_ == 1 || lastPercentage_ == 100; }; } BaseGenerator::ShouldLogSuccess BaseGenerator::shouldLogEveryNSeconds( int seconds, const ShouldLogSuccess &performOtherwise) const noexcept { QElapsedTimer timer; timer.start(); return [this, timer, seconds, performOtherwise]() mutable { if (timer.elapsed() >= seconds * 1000) { timer.restart(); return true; } return performOtherwise(); }; } BaseGenerator::ShouldLogSuccess BaseGenerator::defaultShouldLog(int percent, int seconds) const noexcept { ShouldLogSuccess first = shouldLogEveryNSeconds(seconds, shouldLogFirstAndLastPercent()); ShouldLogSuccess second = shouldLogEveryNPercent(percent); return [first, second]() { return first() || second(); }; } void BaseGenerator::generateAll(const ShouldLogSuccess &shouldLogSuccess) { auto withoutLimit = []() { return true; }; generateImplementation(withoutLimit, shouldLogSuccess); } void BaseGenerator::generateByFillRatio( double fillRatio, const ShouldLogSuccess &shouldLogSuccess) { fillRatio >= 1.0 ? fillRatio = 1.0 : fillRatio; qInfo() << "Limit fill ratio of records to create: " << fillRatio; auto shouldContinue = [this, fillRatio]() -> bool { double currentFillRatio = lastPercentage_ / 100.0; bool shouldContinue = currentFillRatio < fillRatio; if (!shouldContinue) { qInfo() << "Limit of records to create reached"; } return shouldContinue; }; generateImplementation(shouldContinue, shouldLogSuccess); }; void BaseGenerator::generateByRecordCount( qsizetype totalRecordsToCreate, const ShouldLogSuccess &shouldLogSuccess) { int limit = std::min(totalRecordsToCreate, calculateRemainingCapacity()); qInfo() << "Limit of records to create: " << limit; auto shouldContinue = [this, limit]() -> bool { bool shouldContinue = createdRecords_ < limit; if (!shouldContinue) { qInfo() << "Limit of records to create reached"; } return shouldContinue; }; generateImplementation(shouldContinue, shouldLogSuccess); }; void BaseGenerator::generateImplementation( std::function shouldContinue, std::function shouldLogSuccess) { maximumRecords_ = calculateRemainingCapacity(); qInfo() << "The number of records available for creation:" << maximumRecords_; qInfo().noquote() << createTemplateMessage() << "Started"; while (shouldContinue() && prepareData()) { bool success; RepositoryResult result = createRecord(); if (!result.success) { qWarning().noquote() << createTemplateMessage() << createFailureMessage(result.errorMessage); continue; } ++createdRecords_; updatePercentage(); if (shouldLogSuccess()) { qInfo().noquote() << createTemplateMessage() << createSuccessMessage(); } clearStaleData(); } qInfo().noquote() << createTemplateMessage() << "Completed"; } void BaseGenerator::updatePercentage() { int numerator = maximumRecords_ - calculateRemainingCapacity(); int newPercentage = std::floor(numerator * 100.0 / maximumRecords_); lastPercentage_ = std::max(newPercentage, lastPercentage_); } QString BaseGenerator::createFailureMessage(const QString &errorMessage) const { QString failureMessage = "Failure: Error message:\n\t%1"; return failureMessage.arg(errorMessage); } QString BaseGenerator::createSuccessMessage() const { return "Success"; } QString BaseGenerator::createTemplateMessage() const { auto digitCount = [](int number) { if (number == 0) { return 1; } return static_cast(std::log10(std::abs(number))) + 1; }; int maximumRecordsValue = calculateRemainingCapacity(); int newFieldWidth = std::max(digitCount(createdRecords_), digitCount(maximumRecordsValue)); fieldWidth_ = std::max(fieldWidth_, newFieldWidth); static constexpr int progressBarSize = 25; static constexpr int progressBarStep = 100 / progressBarSize; const QString progressBar(lastPercentage_ / progressBarStep, QChar('#')); return QString("Creating records of entity %1 [ %2 <~ %3] [%4]:") .arg(entityName_) .arg(createdRecords_, fieldWidth_, 10, QChar(' ')) .arg(maximumRecordsValue, fieldWidth_, 10, QChar(' ')) .arg(progressBar.leftJustified(progressBarSize, QChar(' '))); };