33 #include <QSqlDatabase> 34 #include <QMessageBox> 35 #include <QtConcurrentRun> 50 const std::shared_ptr<ConsistencyChecker> Checker_;
52 FailedImpl (
const std::shared_ptr<ConsistencyChecker>& checker)
53 : Checker_ { checker }
59 return Checker_->DumpReinit ();
63 ConsistencyChecker::ConsistencyChecker (
const QString& dbPath,
64 const QString& dialogContext, QObject *parent)
67 , DialogContext_ { dialogContext }
73 return std::shared_ptr<ConsistencyChecker> {
new ConsistencyChecker { dbPath, dialogContext } };
78 const auto managed = shared_from_this ();
79 return QtConcurrent::run ([managed] {
return managed->CheckDB (); });
84 qDebug () << Q_FUNC_INFO
89 std::shared_ptr<QSqlDatabase> db
91 new QSqlDatabase { QSqlDatabase::addDatabase (
"QSQLITE", connName) },
92 [connName] (QSqlDatabase *db)
95 QSqlDatabase::removeDatabase (connName);
99 db->setDatabaseName (DBPath_);
102 qWarning () << Q_FUNC_INFO
103 <<
"cannot open the DB, but that's not the kind of errors we're solving.";
107 QSqlQuery pragma { *db };
108 const auto isGood = pragma.exec (
"PRAGMA integrity_check;") &&
110 pragma.value (0) ==
"ok";
111 qDebug () << Q_FUNC_INFO
119 return std::make_shared<FailedImpl> (shared_from_this ());
125 iface.reportStarted ();
127 DumpReinitImpl (iface);
129 return iface.future ();
137 iface.reportFinished (&result);
143 const QFileInfo fi { DBPath_ };
144 const auto filesize = fi.size ();
150 qDebug () << Q_FUNC_INFO
151 <<
"db size:" << filesize
152 <<
"free space:" << available;
153 if (available >= static_cast<quint64> (filesize))
156 if (QMessageBox::question (
nullptr,
158 tr (
"Not enough available space on partition with file %1: " 159 "%2 while the restored file is expected to be around %3. " 160 "Please either free some disk space on this partition " 161 "and retry or cancel the restore process.")
162 .arg (
"<em>" + DBPath_ +
"</em>")
165 QMessageBox::Retry | QMessageBox::Cancel) == QMessageBox::Cancel)
167 ReportResult (iface, DumpError { tr (
"Not enough available disk space.") });
172 const auto& newPath = DBPath_ +
".new";
176 if (!QFile::exists (newPath))
179 if (QMessageBox::question (
nullptr,
181 tr (
"%1 already exists. Please either remove the file manually " 182 "and retry or cancel the restore process.")
183 .arg (
"<em>" + newPath +
"</em>"),
184 QMessageBox::Retry | QMessageBox::Cancel) == QMessageBox::Cancel)
186 ReportResult (iface, DumpError { tr (
"Backup file already exists.") });
191 const auto dumper =
new Dumper { DBPath_, newPath };
193 const auto managed = shared_from_this ();
194 Util::Sequence (
nullptr, dumper->GetFuture ()) >>
198 [iface] (
const Dumper::Error& error)
201 DumpError { tr (
"Unable to restore the database.") +
" " + error.What_ });
203 [iface, newPath, managed] (
const Dumper::Finished&) { managed->HandleDumperFinished (iface, newPath); });
209 const auto oldSize = QFileInfo { DBPath_ }.size ();
210 const auto newSize = QFileInfo { to }.size ();
212 const auto& backup = DBPath_ +
".bak";
213 while (!QFile::rename (DBPath_, backup))
214 QMessageBox::critical (
nullptr,
216 tr (
"Unable to backup %1 to %2. Please remove %2 and hit OK.")
220 QFile::rename (to, DBPath_);
222 ReportResult (iface, DumpFinished { oldSize, newSize });
UTIL_API QString MakePrettySize(qint64 sourceSize)
Makes a formatted size from number.
FailedImpl(const std::shared_ptr< ConsistencyChecker > &checker)
QString GenConnectionName(const QString &base)
Generates an unique thread-safe connection name.
quint64 Available_
How much space is available to the current user.
QFuture< CheckResult_t > StartCheck()
boost::variant< Succeeded, Failed > CheckResult_t
boost::variant< Finished, Error > Result_t
boost::variant< DumpFinished, DumpError > DumpResult_t
auto Visit(const Either< Left, Right > &either, Args &&... args)
static std::shared_ptr< ConsistencyChecker > Create(const QString &dbPath, const QString &dialogContext)
SpaceInfo GetSpaceInfo(const QString &path)
Returns the disk space info of the partition containing path.