Skip to content

Commit 324bb23

Browse files
committed
DBBrowserDB: Merge renameColumn() and dropColumn()
Merge the renameColumn() and dropColumn() methods. They are just way too long and complicated but also very similar that it makes no sense to keep them separated. This also simplifies the code of renameColumn() a bit while fixing the trigger/view/index problem in dropColumn().
1 parent 2463116 commit 324bb23

File tree

4 files changed

+48
-114
lines changed

4 files changed

+48
-114
lines changed

src/EditTableDialog.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void EditTableDialog::removeField()
361361
QString msg = tr("Are you sure you want to delete the field '%1'?\nAll data currently stored in this field will be lost.").arg(ui->treeWidget->currentItem()->text(0));
362362
if(QMessageBox::warning(this, QApplication::applicationName(), msg, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape) == QMessageBox::Yes)
363363
{
364-
if(!pdb->dropColumn(curTable, ui->treeWidget->currentItem()->text(0)))
364+
if(!pdb->renameColumn(curTable, ui->treeWidget->currentItem()->text(0), sqlb::FieldPtr()))
365365
{
366366
QMessageBox::warning(0, QApplication::applicationName(), pdb->lastErrorMessage);
367367
} else {

src/sqlitedb.cpp

+38-112
Original file line numberDiff line numberDiff line change
@@ -523,14 +523,29 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const QString& name, sq
523523
// NOTE: This function is working around the incomplete ALTER TABLE command in SQLite.
524524
// If SQLite should fully support this command one day, this entire
525525
// function can be changed to executing something like this:
526-
//QString sql = QString("ALTER TABLE `%1` MODIFY `%2` %3").arg(tablename).arg(to).arg(type);
526+
//QString sql;
527+
//if(to.isNull())
528+
// sql = QString("ALTER TABLE `%1` DROP COLUMN `%2`;").arg(table).arg(column);
529+
//else
530+
// sql = QString("ALTER TABLE `%1` MODIFY `%2` %3").arg(tablename).arg(to).arg(type); // This is wrong...
527531
//return executeSQL(sql);
528532

529533
// Collect information on the current DB layout
530-
DBBrowserObject table = getObjectByName(tablename);
531-
if(table.getname() == "" || table.getField(name)->name() == "")
534+
QString tableSql = getTableSQL(tablename);
535+
if(tableSql.isEmpty())
532536
{
533-
lastErrorMessage = QObject::tr("renameColumn: cannot find table %1 with column %2").arg(tablename).arg(name);
537+
lastErrorMessage = QObject::tr("renameColumn: cannot find table %1.").arg(tablename);
538+
qWarning() << lastErrorMessage;
539+
return false;
540+
}
541+
542+
// Create table schema
543+
sqlb::Table oldSchema = sqlb::Table::parseSQL(tableSql);
544+
545+
// Check if field actually exists
546+
if(oldSchema.findField(name) == -1)
547+
{
548+
lastErrorMessage = QObject::tr("renameColumn: cannot find column %1.").arg(name);
534549
qWarning() << lastErrorMessage;
535550
return false;
536551
}
@@ -546,16 +561,26 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const QString& name, sq
546561
// Create a new table with a name that hopefully doesn't exist yet.
547562
// Its layout is exactly the same as the one of the table to change - except for the column to change
548563
// of course
549-
sqlb::FieldVector new_table_structure;
550-
for(int i=0;i<table.fldmap.count();i++)
564+
sqlb::Table newSchema = oldSchema;
565+
newSchema.setName("sqlitebrowser_rename_column_new_table");
566+
QString select_cols;
567+
if(to.isNull())
551568
{
552-
// Is this the column to rename?
553-
if(table.fldmap.value(i)->name() == name)
554-
new_table_structure.push_back(to);
555-
else
556-
new_table_structure.push_back(table.fldmap.value(i));
569+
// We want drop the column - so just remove the field
570+
newSchema.removeField(name);
571+
572+
for(int i=0;i<newSchema.fields().count();++i)
573+
select_cols.append(QString("`%1`,").arg(newSchema.fields().at(i)->name()));
574+
select_cols.chop(1); // remove last comma
575+
} else {
576+
// We want to modify it
577+
newSchema.setField(newSchema.findField(name), to);
578+
579+
select_cols = "*";
557580
}
558-
if(!createTable("sqlitebrowser_rename_column_new_table", new_table_structure))
581+
582+
// Create the new table
583+
if(!executeSQL(newSchema.sql()))
559584
{
560585
lastErrorMessage = QObject::tr("renameColumn: creating new table failed. DB says: %1").arg(lastErrorMessage);
561586
qWarning() << lastErrorMessage;
@@ -564,7 +589,7 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const QString& name, sq
564589
}
565590

566591
// Copy the data from the old table to the new one
567-
if(!executeSQL(QString("INSERT INTO sqlitebrowser_rename_column_new_table SELECT * FROM `%1`;").arg(tablename)))
592+
if(!executeSQL(QString("INSERT INTO sqlitebrowser_rename_column_new_table SELECT %1 FROM `%2`;").arg(select_cols).arg(tablename)))
568593
{
569594
lastErrorMessage = QObject::tr("renameColumn: copying data to new table failed. DB says:\n"
570595
"%1").arg(lastErrorMessage);
@@ -620,105 +645,6 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const QString& name, sq
620645
return true;
621646
}
622647

623-
bool DBBrowserDB::dropColumn(const QString& tablename, const QString& column)
624-
{
625-
// NOTE: This function is working around the incomplete ALTER TABLE command in SQLite.
626-
// If SQLite should fully support this command one day, this entire
627-
// function can be changed to executing something like this:
628-
//QString sql = QString("ALTER TABLE `%1` DROP COLUMN `%2`;").arg(table).arg(column);
629-
//return executeSQL(sql);
630-
631-
// Collect information on the current DB layout
632-
QString sTableSql = getTableSQL(tablename);
633-
if(sTableSql.isEmpty())
634-
{
635-
lastErrorMessage = QObject::tr("dropColumn: cannot find table %1.").arg(tablename);
636-
qWarning() << lastErrorMessage;
637-
return false;
638-
}
639-
640-
sqlb::Table oldSchema = sqlb::Table::parseSQL(sTableSql);
641-
642-
if(oldSchema.findField(column) == -1 || oldSchema.fields().count() == 1)
643-
{
644-
lastErrorMessage = QObject::tr("dropColumn: cannot find column %1. "
645-
"Also you can not delete the last column").arg(column);
646-
qWarning() << lastErrorMessage;
647-
return false;
648-
}
649-
650-
// Create savepoint to be able to go back to it in case of any error
651-
if(!executeSQL("SAVEPOINT sqlitebrowser_drop_column;", false))
652-
{
653-
lastErrorMessage = QObject::tr("dropColumn: creating savepoint failed");
654-
qWarning() << lastErrorMessage;
655-
return false;
656-
}
657-
658-
// Create a new table with a name that hopefully doesn't exist yet.
659-
// Its layout is exactly the same as the one of the table to change - except for the column to drop
660-
// of course. Also prepare the columns to be copied in a later step now.
661-
sqlb::Table newSchema = oldSchema;
662-
newSchema.setName("sqlitebrowser_drop_column_new_table");
663-
newSchema.removeField(column);
664-
665-
QString select_cols;
666-
for(int i=0; i<newSchema.fields().count(); ++i)
667-
{
668-
select_cols.append(QString("`%1`,").arg(newSchema.fields().at(i)->name()));
669-
}
670-
// remove last ,
671-
select_cols.remove(select_cols.count() -1, 1);
672-
673-
// create the new table
674-
if(!executeSQL(newSchema.sql(), false))
675-
{
676-
lastErrorMessage = QObject::tr("dropColumn: creating new table failed. DB says: %1").arg(lastErrorMessage);
677-
qWarning() << lastErrorMessage;
678-
executeSQL("ROLLBACK TO SAVEPOINT sqlitebrowser_drop_column;", false);
679-
return false;
680-
}
681-
682-
// Copy the data from the old table to the new one
683-
if(!executeSQL(
684-
QString("INSERT INTO sqlitebrowser_drop_column_new_table SELECT %1 FROM `%2`;").arg(select_cols).arg(tablename),
685-
false))
686-
{
687-
lastErrorMessage = QObject::tr("dropColumn: copying data to new table failed. DB says: %1").arg(lastErrorMessage);
688-
qWarning() << lastErrorMessage;
689-
executeSQL("ROLLBACK TO SAVEPOINT sqlitebrowser_drop_column;");
690-
return false;
691-
}
692-
693-
// Delete the old table
694-
if(!executeSQL(QString("DROP TABLE `%1`;").arg(tablename), false))
695-
{
696-
lastErrorMessage = QObject::tr("dropColumn: deleting old table failed. DB says: %1").arg(lastErrorMessage);
697-
qWarning() << lastErrorMessage;
698-
executeSQL("ROLLBACK TO SAVEPOINT sqlitebrowser_drop_column;");
699-
return false;
700-
}
701-
702-
// Rename the temporary table
703-
if(!renameTable("sqlitebrowser_drop_column_new_table", tablename))
704-
{
705-
executeSQL("ROLLBACK TO SAVEPOINT sqlitebrowser_drop_column;");
706-
return false;
707-
}
708-
709-
// Release the savepoint - everything went fine
710-
if(!executeSQL("RELEASE SAVEPOINT sqlitebrowser_drop_column;", false))
711-
{
712-
lastErrorMessage = QObject::tr("dropColumn: releasing savepoint failed. DB says: %1").arg(lastErrorMessage);
713-
qWarning() << lastErrorMessage;
714-
return false;
715-
}
716-
717-
// Success, update the DB schema before returning
718-
updateSchema();
719-
return true;
720-
}
721-
722648
bool DBBrowserDB::renameTable(const QString& from_table, const QString& to_table)
723649
{
724650
QString sql = QString("ALTER TABLE `%1` RENAME TO `%2`").arg(from_table, to_table);

src/sqlitedb.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,15 @@ class DBBrowserDB
8080
bool createTable(const QString& name, const sqlb::FieldVector& structure);
8181
bool renameTable(const QString& from_table, const QString& to_table);
8282
bool addColumn(const QString& table, const sqlb::FieldPtr& field);
83+
84+
/**
85+
* @brief renameColumn Can be used to rename, modify or drop an existing column of a given table
86+
* @param tablename Specifies the table name
87+
* @param name Name of the column to edit
88+
* @param to The new field definition with changed name, type or the like. If Null-Pointer is given the column is dropped.
89+
* @return true if renaming was successfull, false if not. In the latter case also lastErrorMessage is set
90+
*/
8391
bool renameColumn(const QString& tablename, const QString& name, sqlb::FieldPtr to);
84-
bool dropColumn(const QString& tablename, const QString& column);
8592

8693
QStringList getTableFields(const QString & tablename) const;
8794
QStringList getBrowsableObjectNames() const;

src/sqlitetypes.h

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class Table
8989
void addField(const FieldPtr& f);
9090
bool removeField(const QString& sFieldName);
9191
void setFields(const FieldVector& fields);
92+
void setField(int index, FieldPtr f) { m_fields[index] = f; }
9293
void clear();
9394

9495
/**

0 commit comments

Comments
 (0)