Some improvements to the Export SQL dialog

When possible, don't write 'CREATE TABLE/VIEW/... `name`' but 'CREATE
TABLE/VIEW/... IF NOT EXISTS `name`' to the file.

Add an option to add DROP TABLE statements before each create statement.
This needs to be enhanced to apply to views, indices, and triggers as
well. See issue #629.

Clean up code.
This commit is contained in:
Martin Kleusberg
2017-05-12 15:38:46 +02:00
parent c74204c700
commit 037b3c0113
7 changed files with 84 additions and 24 deletions

View File

@@ -10,6 +10,14 @@
static QString sSettingsGroup("exportsql");
static QString sSettingsInsertColNames("insertcolnames");
static QString sSettingsInsertMultiple("insertmultiple");
static QString sSettingsOldSchema("oldschema");
enum WhatComboEntries
{
ExportEverything,
ExportSchemaOnly,
ExportDataOnly,
};
ExportSqlDialog::ExportSqlDialog(DBBrowserDB* db, QWidget* parent, const QString& selection)
: QDialog(parent),
@@ -23,6 +31,7 @@ ExportSqlDialog::ExportSqlDialog(DBBrowserDB* db, QWidget* parent, const QString
settings.beginGroup(sSettingsGroup);
ui->checkColNames->setChecked(settings.value(sSettingsInsertColNames, false).toBool());
ui->checkMultiple->setChecked(settings.value(sSettingsInsertMultiple, false).toBool());
ui->comboOldSchema->setCurrentIndex(settings.value(sSettingsOldSchema, 0).toInt());
// Get list of tables to export
objectMap objects = pdb->getBrowsableObjects();
@@ -93,6 +102,7 @@ void ExportSqlDialog::accept()
settings.beginGroup(sSettingsGroup);
settings.setValue(sSettingsInsertColNames, ui->checkColNames->isChecked());
settings.setValue(sSettingsInsertMultiple, ui->checkMultiple->isChecked());
settings.setValue(sSettingsOldSchema, ui->comboOldSchema->currentIndex());
settings.endGroup();
QStringList tables;
@@ -100,8 +110,9 @@ void ExportSqlDialog::accept()
tables.push_back(item->text());
// Check what to export. The indices here depend on the order of the items in the combobox in the ui file
bool exportSchema = ui->comboWhat->currentIndex() == 0 || ui->comboWhat->currentIndex() == 1;
bool exportData = ui->comboWhat->currentIndex() == 0 || ui->comboWhat->currentIndex() == 2;
bool exportSchema = ui->comboWhat->currentIndex() == ExportEverything || ui->comboWhat->currentIndex() == ExportSchemaOnly;
bool exportData = ui->comboWhat->currentIndex() == ExportEverything || ui->comboWhat->currentIndex() == ExportDataOnly;
bool keepSchema = ui->comboOldSchema->currentIndex() == 0;
// Perform actual export
bool dumpOk = pdb->dump(fileName,
@@ -109,7 +120,8 @@ void ExportSqlDialog::accept()
ui->checkColNames->isChecked(),
ui->checkMultiple->isChecked(),
exportSchema,
exportData);
exportData,
keepSchema);
if (dumpOk)
QMessageBox::information(this, QApplication::applicationName(), tr("Export completed."));
else
@@ -118,5 +130,12 @@ void ExportSqlDialog::accept()
QDialog::accept();
}
void ExportSqlDialog::whatChanged(int index)
{
// Only show the combobox for deciding what to do with the old schema when importing into an existing database when we're
// actually exporting the schema here
if(index != ExportDataOnly)
ui->comboOldSchema->setVisible(true);
else
ui->comboOldSchema->setVisible(false);
}

View File

@@ -21,6 +21,7 @@ private slots:
virtual void accept();
void doSelectAll();
void doDeselectAll();
void whatChanged(int index);
private:
Ui::ExportSqlDialog* ui;

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>497</width>
<height>338</height>
<height>352</height>
</rect>
</property>
<property name="windowTitle">
@@ -96,7 +96,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -128,6 +128,20 @@
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QComboBox" name="comboOldSchema">
<item>
<property name="text">
<string>Keep old schema (CREATE TABLE IF NOT EXISTS)</string>
</property>
</item>
<item>
<property name="text">
<string>Overwrite old schema (DROP TABLE, then CREATE TABLE)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
@@ -163,8 +177,8 @@
<slot>doDeselectAll()</slot>
<hints>
<hint type="sourcelabel">
<x>298</x>
<y>150</y>
<x>488</x>
<y>129</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
@@ -179,8 +193,8 @@
<slot>doSelectAll()</slot>
<hints>
<hint type="sourcelabel">
<x>80</x>
<y>150</y>
<x>140</x>
<y>129</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
@@ -204,8 +218,25 @@
</hint>
</hints>
</connection>
<connection>
<sender>comboWhat</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>ExportSqlDialog</receiver>
<slot>whatChanged(int)</slot>
<hints>
<hint type="sourcelabel">
<x>320</x>
<y>234</y>
</hint>
<hint type="destinationlabel">
<x>492</x>
<y>226</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>showCustomCharEdits()</slot>
<slot>whatChanged(int)</slot>
</slots>
</ui>

View File

@@ -453,7 +453,8 @@ bool DBBrowserDB::dump(const QString& filename,
bool insertColNames,
bool insertNewSyntx,
bool exportSchema,
bool exportData)
bool exportData,
bool keepOldSchema)
{
// Open file
QFile file(filename);
@@ -501,8 +502,11 @@ bool DBBrowserDB::dump(const QString& filename,
// Write the SQL string used to create this table to the output file
if(exportSchema)
{
if(!keepOldSchema)
stream << "DROP TABLE IF EXISTS " << sqlb::escapeIdentifier((*it)->name()) << ";\n";
if((*it)->fullyParsed())
stream << (*it)->sql() << "\n";
stream << (*it)->sql(true) << "\n";
else
stream << (*it)->originalSql() << ";\n";
}
@@ -610,7 +614,7 @@ bool DBBrowserDB::dump(const QString& filename,
if(!(*it)->originalSql().isEmpty())
{
if((*it)->fullyParsed())
stream << (*it)->sql() << "\n";
stream << (*it)->sql(true) << "\n";
else
stream << (*it)->originalSql() << ";\n";
}

View File

@@ -34,7 +34,7 @@ public:
bool revertToSavepoint(const QString& pointname = "RESTOREPOINT");
bool releaseAllSavepoints();
bool revertAll();
bool dump(const QString & filename, const QStringList &tablesToDump, bool insertColNames, bool insertNew, bool exportSchema, bool exportData);
bool dump(const QString & filename, const QStringList &tablesToDump, bool insertColNames, bool insertNew, bool exportSchema, bool exportData, bool keepOldSchema);
bool executeSQL(QString statement, bool dirtyDB = true, bool logsql = true);
bool executeMultiSQL(const QString& statement, bool dirty = true, bool log = false);
const QString& lastError() const { return lastErrorMessage; }

View File

@@ -427,14 +427,17 @@ ObjectPtr Table::parseSQL(const QString &sSQL)
return TablePtr(new Table(""));
}
QString Table::sql() const
QString Table::sql(bool ifNotExists) const
{
// Special handling for virtual tables: just build an easy create statement and copy the using part in there
if(isVirtual())
return QString("CREATE VIRTUAL TABLE %1 USING %2;").arg(escapeIdentifier(m_name)).arg(m_virtual);
// This is a normal table, not a virtual one
QString sql = QString("CREATE %1TABLE %2 (\n").arg(m_temporary ? QString("TEMPORARY ") : QString("")).arg(escapeIdentifier(m_name));
QString sql = QString("CREATE %1TABLE%2 %3 (\n")
.arg(m_temporary ? QString("TEMPORARY ") : QString(""))
.arg(ifNotExists ? QString(" IF NOT EXISTS") : QString(""))
.arg(escapeIdentifier(m_name));
sql += fieldList().join(",\n");
@@ -1137,11 +1140,12 @@ QStringList Index::columnSqlList() const
return sl;
}
QString Index::sql() const
QString Index::sql(bool ifNotExists) const
{
// Start CREATE (UNIQUE) INDEX statement
QString sql = QString("CREATE %1INDEX %2 ON %3 (\n")
QString sql = QString("CREATE %1INDEX%2 %3 ON %4 (\n")
.arg(m_unique ? QString("UNIQUE ") : QString(""))
.arg(ifNotExists ? QString(" IF NOT EXISTS") : QString(""))
.arg(escapeIdentifier(m_name))
.arg(escapeIdentifier(m_table));

View File

@@ -89,9 +89,10 @@ public:
/**
* @brief Returns the CREATE statement for this object
* @param ifNotExists If set to true the "IF NOT EXISTS" qualifier will be added to the create statement
* @return A QString with the CREATE statement.
*/
virtual QString sql() const = 0;
virtual QString sql(bool ifNotExists = false) const = 0;
/**
* @brief parseSQL Parses the CREATE statement in sSQL.
@@ -282,7 +283,7 @@ public:
* @brief Returns the CREATE TABLE statement for this table object
* @return A QString with the CREATE TABLE object.
*/
QString sql() const;
QString sql(bool ifNotExists = false) const;
void addField(const FieldPtr& f);
bool removeField(const QString& sFieldName);
@@ -402,7 +403,7 @@ public:
* @brief Returns the CREATE INDEX statement for this index object
* @return A QString with the CREATE INDEX object.
*/
QString sql() const;
QString sql(bool ifNotExists = false) const;
/**
* @brief parseSQL Parses the CREATE INDEX statement in sSQL.
@@ -430,7 +431,7 @@ public:
virtual Types type() const { return Object::View; }
QString sql() const { /* TODO */ return m_originalSql; }
QString sql(bool ifNotExists = false) const { /* TODO */ Q_UNUSED(ifNotExists); return m_originalSql; }
static ObjectPtr parseSQL(const QString& sSQL);
@@ -455,7 +456,7 @@ public:
virtual Types type() const { return Object::Trigger; }
QString sql() const { /* TODO */ return m_originalSql; }
QString sql(bool ifNotExists = false) const { /* TODO */ Q_UNUSED(ifNotExists); return m_originalSql; }
static ObjectPtr parseSQL(const QString& sSQL);