VacuumDialog: Add dialog to allow compacting single objects individually

Add a new dialog which is shown when compacting the database. This
dialog allows selecting single objects individually to avoid vacuuming
the entire database.

It also shows a new warning if the database is dirty as changes are
going to be saved before vacuuming.
This commit is contained in:
Martin Kleusberg
2013-05-21 22:32:05 +02:00
parent 6f8e988f10
commit 4dfabe4a78
7 changed files with 230 additions and 40 deletions

View File

@@ -25,6 +25,7 @@
#include "sqlitetablemodel.h"
#include "FilterTableHeader.h"
#include "SqlExecutionArea.h"
#include "VacuumDialog.h"
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent),
@@ -530,18 +531,12 @@ void MainWindow::createIndex()
void MainWindow::compact()
{
QApplication::setOverrideCursor( Qt::WaitCursor );
if (!db.compact()){
QString error = tr("Error: could not compact the database file. Message from database engine: %1").arg(db.lastErrorMessage);
QApplication::restoreOverrideCursor( );
QMessageBox::warning( this, QApplication::applicationName(), error );
} else {
QApplication::restoreOverrideCursor( );
QMessageBox::information(this, QApplication::applicationName(), tr("Database successfully compacted."));
VacuumDialog dialog(&db, this);
if(dialog.exec())
{
populateStructure();
resetBrowser();
}
db.open(db.curDBFilename);
populateStructure();
resetBrowser();
}
void MainWindow::deleteObject()

63
src/VacuumDialog.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "VacuumDialog.h"
#include "ui_VacuumDialog.h"
#include "sqlitedb.h"
#include <QTreeWidgetItem>
VacuumDialog::VacuumDialog(DBBrowserDB* _db, QWidget* parent) :
QDialog(parent),
ui(new Ui::VacuumDialog),
db(_db)
{
// Create UI
ui->setupUi(this);
// Show warning if DB is dirty
ui->labelSavepointWarning->setVisible(db->getDirty());
// Populate list of objects to compact
QList<DBBrowserObject> objects = db->objMap.values("table");
objects.append(db->objMap.values("index"));
for(QList<DBBrowserObject>::const_iterator i=objects.constBegin();i!=objects.constEnd();++i)
{
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeSelectedObjects);
item->setText(0, (*i).getname());
item->setIcon(0, QIcon(QString(":icons/%1").arg((*i).gettype())));
ui->treeSelectedObjects->addTopLevelItem(item);
}
// Sort objects and select them all
ui->treeSelectedObjects->sortByColumn(0, Qt::AscendingOrder);
ui->treeSelectedObjects->selectAll();
}
VacuumDialog::~VacuumDialog()
{
delete ui;
}
void VacuumDialog::accept()
{
if(ui->treeSelectedObjects->selectedItems().count() == 0)
QDialog::accept();
QApplication::setOverrideCursor(Qt::WaitCursor);
// Commit all changes first
db->save();
// All items selected?
if(ui->treeSelectedObjects->selectedItems().count() == ui->treeSelectedObjects->topLevelItemCount())
{
// Yes, so just execute a simple vacuum command for all objects
db->executeSQL("VACUUM;", false);
} else {
// No, so execute a vacuum command for each selected object individually
QList<QTreeWidgetItem*> selection = ui->treeSelectedObjects->selectedItems();
foreach(QTreeWidgetItem* item, selection)
db->executeSQL(QString("VACUUM `%1`;").arg(item->text(0)), false);
}
db->setDirty(false);
QApplication::restoreOverrideCursor();
QDialog::accept();
}

28
src/VacuumDialog.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef __VACUUMDIALOG_H__
#define __VACUUMDIALOG_H__
#include <QDialog>
namespace Ui {
class VacuumDialog;
}
class DBBrowserDB;
class VacuumDialog : public QDialog
{
Q_OBJECT
public:
explicit VacuumDialog(DBBrowserDB* _db, QWidget* parent = 0);
~VacuumDialog();
private:
Ui::VacuumDialog* ui;
DBBrowserDB* db;
protected slots:
virtual void accept();
};
#endif

127
src/VacuumDialog.ui Normal file
View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VacuumDialog</class>
<widget class="QDialog" name="VacuumDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>475</width>
<height>439</height>
</rect>
</property>
<property name="windowTitle">
<string>Compact Database</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="labelSavepointWarning">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Warning: Compacting the database will commit all changes you made.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Please select the objects to compact:</string>
</property>
<property name="buddy">
<cstring>treeSelectedObjects</cstring>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="treeSelectedObjects">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>treeSelectedObjects</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>VacuumDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>222</x>
<y>374</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>VacuumDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>290</x>
<y>380</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -198,31 +198,6 @@ void DBBrowserDB::close (){
objMap.clear();
}
bool DBBrowserDB::compact ( )
{
char *errmsg;
bool ok=false;
if (!isOpen()) return false;
if (_db){
save();
logSQL(QString("VACUUM;"), kLogMsg_App);
if (SQLITE_OK==sqlite3_exec(_db,"VACUUM;",
NULL,NULL,&errmsg)){
ok=true;
setDirty(false);
}
}
if (!ok){
lastErrorMessage = QString(errmsg);
return false;
}else{
return true;
}
}
bool DBBrowserDB::dump(const QString& filename)
{
// Open file

View File

@@ -69,7 +69,6 @@ public:
bool open ( const QString & db);
bool create ( const QString & db);
void close ();
bool compact ();
bool setRestorePoint(const QString& pointname = "RESTOREPOINT");
bool save (const QString& pointname = "RESTOREPOINT");
bool revert (const QString& pointname = "RESTOREPOINT");

View File

@@ -44,7 +44,8 @@ HEADERS += \
sqlitetablemodel.h \
FilterTableHeader.h \
gen_version.h \
SqlExecutionArea.h
SqlExecutionArea.h \
VacuumDialog.h
SOURCES += \
sqlitedb.cpp \
@@ -64,7 +65,8 @@ SOURCES += \
grammar/Sqlite3Parser.cpp \
sqlitetablemodel.cpp \
FilterTableHeader.cpp \
SqlExecutionArea.cpp
SqlExecutionArea.cpp \
VacuumDialog.cpp
RESOURCES += icons/icons.qrc
@@ -77,7 +79,8 @@ FORMS += \
EditDialog.ui \
ExportCsvDialog.ui \
ImportCsvDialog.ui \
SqlExecutionArea.ui
SqlExecutionArea.ui \
VacuumDialog.ui
LIBPATH_QHEXEDIT=$$PWD/../libs/qhexedit
LIBPATH_ANTLR=$$PWD/../libs/antlr-2.7.7