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 QString checkQuery = qgetenv (
"LC_THOROUGH_SQLITE_CHECK") ==
"1" ?
109 "PRAGMA integrity_check;" :
110 "PRAGMA quick_check;";
111 const auto isGood = pragma.exec (checkQuery) &&
113 pragma.value (0) ==
"ok";
114 qDebug () << Q_FUNC_INFO
122 return std::make_shared<FailedImpl> (shared_from_this ());
128 iface.reportStarted ();
130 DumpReinitImpl (iface);
132 return iface.future ();
140 iface.reportFinished (&result);
146 const QFileInfo fi { DBPath_ };
147 const auto filesize = fi.size ();
153 qDebug () << Q_FUNC_INFO
154 <<
"db size:" << filesize
155 <<
"free space:" << available;
156 if (available >= static_cast<quint64> (filesize))
159 if (QMessageBox::question (
nullptr,
161 tr (
"Not enough available space on partition with file %1: " 162 "%2 while the restored file is expected to be around %3. " 163 "Please either free some disk space on this partition " 164 "and retry or cancel the restore process.")
165 .arg (
"<em>" + DBPath_ +
"</em>")
168 QMessageBox::Retry | QMessageBox::Cancel) == QMessageBox::Cancel)
170 ReportResult (iface, DumpError { tr (
"Not enough available disk space.") });
175 const auto& newPath = DBPath_ +
".new";
179 if (!QFile::exists (newPath))
182 if (QMessageBox::question (
nullptr,
184 tr (
"%1 already exists. Please either remove the file manually " 185 "and retry or cancel the restore process.")
186 .arg (
"<em>" + newPath +
"</em>"),
187 QMessageBox::Retry | QMessageBox::Cancel) == QMessageBox::Cancel)
189 ReportResult (iface, DumpError { tr (
"Backup file already exists.") });
194 const auto dumper =
new Dumper { DBPath_, newPath };
196 const auto managed = shared_from_this ();
197 Util::Sequence (
nullptr, dumper->GetFuture ()) >>
201 [iface] (
const Dumper::Error& error)
204 DumpError { tr (
"Unable to restore the database.") +
" " + error.What_ });
206 [iface, newPath, managed] (
const Dumper::Finished&) { managed->HandleDumperFinished (iface, newPath); });
212 const auto oldSize = QFileInfo { DBPath_ }.size ();
213 const auto newSize = QFileInfo { to }.size ();
215 const auto& backup = DBPath_ +
".bak";
216 while (!QFile::rename (DBPath_, backup))
217 QMessageBox::critical (
nullptr,
219 tr (
"Unable to backup %1 to %2. Please remove %2 and hit OK.")
223 QFile::rename (to, DBPath_);
225 ReportResult (iface, DumpFinished { oldSize, newSize });
SpaceInfo GetSpaceInfo(const QString &path)
Returns the disk space info of the partition containing path.
static std::shared_ptr< ConsistencyChecker > Create(const QString &dbPath, const QString &dialogContext)
std::variant< Succeeded, Failed > CheckResult_t
auto Visit(const Either< Left, Right > &either, Args &&... args)
FailedImpl(const std::shared_ptr< ConsistencyChecker > &checker)
std::variant< Finished, Error > Result_t
QFuture< CheckResult_t > StartCheck()
UTIL_API QString MakePrettySize(qint64 sourceSize)
Makes a formatted size from number.
quint64 Available_
How much space is available to the current user.
std::variant< DumpFinished, DumpError > DumpResult_t
QString GenConnectionName(const QString &base)
Generates an unique thread-safe connection name.