20#include "SqliteVacuum.h"
21#include "sqlite_debug.h"
26#include <QProgressDialog>
30#include <QApplication>
34#include <QTemporaryFile>
39void usleep(
unsigned int usec)
45#define CONV(x) ((wchar_t*)x.utf16())
50 bool ok = (MoveFileExW(CONV(in), CONV(out),
51 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0);
53 bool ok = (MoveFileW(CONV(in), CONV(out)) != 0);
66SqliteVacuum::SqliteVacuum(
const QString& filePath)
67 : m_filePath(filePath)
69 m_dumpProcess =
nullptr;
70 m_sqliteProcess =
nullptr;
76SqliteVacuum::~SqliteVacuum()
79 m_dumpProcess->waitForFinished();
82 if (m_sqliteProcess) {
83 m_sqliteProcess->waitForFinished();
84 delete m_sqliteProcess;
97 m_result =
KDbResult(ERR_OBJECT_NOT_FOUND,
tr(
"Could not find tool \"%1\".")
99 sqliteWarning() << m_result;
105 m_result =
KDbResult(ERR_OBJECT_NOT_FOUND,
tr(
"Could not find application \"%1\".")
107 sqliteWarning() << m_result;
113 m_result =
KDbResult(ERR_OBJECT_NOT_FOUND,
tr(
"Could not read file \"%1\".")
115 sqliteWarning() << m_result;
121 delete m_dumpProcess;
129 delete m_sqliteProcess;
130 m_sqliteProcess =
new QProcess(
this);
135 m_dumpProcess->setStandardOutputProcess(m_sqliteProcess);
137 if (!m_dumpProcess->waitForStarted()) {
138 delete m_dumpProcess;
139 m_dumpProcess =
nullptr;
140 m_result.setCode(ERR_OTHER);
146 if (!tempFile.
open()) {
147 delete m_dumpProcess;
148 m_dumpProcess =
nullptr;
149 m_result.setCode(ERR_OTHER);
152 m_tmpFilePath = tempFile.
fileName();
155 m_sqliteProcess->start(sqlite_app,
QStringList() << m_tmpFilePath);
156 if (!m_sqliteProcess->waitForStarted()) {
157 delete m_dumpProcess;
158 m_dumpProcess =
nullptr;
159 delete m_sqliteProcess;
160 m_sqliteProcess =
nullptr;
161 m_result.setCode(ERR_OTHER);
168 m_dlg->setWindowTitle(
tr(
"Compacting database"));
176 m_dlg->resize(300, m_dlg->height());
177 m_dlg->setMinimumDuration(1000);
178 m_dlg->setAutoClose(
true);
179 m_dlg->setRange(0, 100);
181 if (m_dlg->wasCanceled()) {
194 return !m_result.isError();
207 m_dlg->setValue(m_percent);
210 if (s.
mid(6, 4) ==
"100%") {
216 }
else if (s.
mid(7, 1) ==
"%") {
218 }
else if (s.
mid(8, 1) ==
"%") {
222 m_dlg->setValue(m_percent);
233 m_result.setCode(ERR_OTHER);
241 m_result.setCode(ERR_OTHER);
248 if (m_result.isError() || m_canceled) {
253 QFileInfo fi(m_filePath);
254 const qint64 origSize = fi.size();
256 const QString newName(fi.absoluteFilePath());
257 if (0 != atomic_rename(m_tmpFilePath, newName)) {
258 m_result= KDbResult(ERR_ACCESS_RIGHTS,
259 tr(
"Could not rename file \"%1\" to \"%2\".").arg(m_tmpFilePath, newName));
260 sqliteWarning() << m_result;
263 if (!m_result.isError()) {
264 const qint64 newSize = QFileInfo(m_filePath).size();
265 const qint64 decrease = 100 - 100 * newSize / origSize;
267 tr(
"The database has been compacted. Current size decreased by %1% to %2 MB.")
268 .arg(decrease).arg(QLocale().
toString(
double(newSize)/1000000.0,
'f', 2)));
272void SqliteVacuum::cancelClicked()
274 m_sqliteProcess->terminate();
3-state logical type with three values: true, false and cancelled and convenient operators.
char * toString(const EngineQuery &query)
KDB_EXPORT QString sqlite3ProgramPath()
bool isEmpty() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
bool startsWith(QByteArrayView bv) const const
int toInt(bool *ok, int base) const const
QString fromNativeSeparators(const QString &pathName)
QString path() const const
QByteArray encodeName(const QString &fileName)
QDir absoluteDir() const const
QString absoluteFilePath() const const
QString fileName() const const
bool isReadable() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
virtual QString fileName() const const override