mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 11:00:44 -06:00
Allow (un)setting the WITHOUT ROWID flag for existing tables
When editing an existing table and changing the WITHOUT ROWID flag, this modification is now actually applied to the table and saved. See issue #51.
This commit is contained in:
@@ -32,7 +32,13 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const QString& tableName, bool
|
||||
QPair<sqlb::Table, bool> parse_result = sqlb::Table::parseSQL(sTablesql);
|
||||
m_table = parse_result.first;
|
||||
ui->labelEditWarning->setVisible(!parse_result.second);
|
||||
|
||||
// Set without rowid checkbox. No need to trigger any events here as we're only loading a table exactly as it is stored by SQLite, so no need
|
||||
// for error checking etc.
|
||||
ui->checkWithoutRowid->blockSignals(true);
|
||||
ui->checkWithoutRowid->setChecked(m_table.isWithoutRowidTable());
|
||||
ui->checkWithoutRowid->blockSignals(false);
|
||||
|
||||
populateFields();
|
||||
} else {
|
||||
ui->labelEditWarning->setVisible(false);
|
||||
@@ -657,7 +663,12 @@ void EditTableDialog::setWithoutRowid(bool without_rowid)
|
||||
tr("Please add a field which meets the following criteria before setting the without rowid flag:\n"
|
||||
" - Primary key flag set\n"
|
||||
" - Auto increment disabled"));
|
||||
|
||||
// Reset checkbox state to unchecked. Block any signals while doing this in order to avoid an extra call to
|
||||
// this function being triggered.
|
||||
ui->checkWithoutRowid->blockSignals(true);
|
||||
ui->checkWithoutRowid->setChecked(false);
|
||||
ui->checkWithoutRowid->blockSignals(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -671,7 +682,15 @@ void EditTableDialog::setWithoutRowid(bool without_rowid)
|
||||
// Update the SQL preview
|
||||
updateSqlText();
|
||||
|
||||
// TODO: Update table if we're editing an existing table
|
||||
// Update table if we're editing an existing table
|
||||
if(!m_bNewTable)
|
||||
{
|
||||
if(!pdb.renameColumn(m_table, QString(), sqlb::FieldPtr(), 0))
|
||||
{
|
||||
QMessageBox::warning(this, QApplication::applicationName(),
|
||||
tr("Setting the rowid column for the table failed. Error message:\n%1").arg(pdb.lastErrorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EditTableDialog::fieldNameExists(const QString& name)
|
||||
|
||||
@@ -969,6 +969,14 @@ bool DBBrowserDB::addColumn(const QString& tablename, const sqlb::FieldPtr& fiel
|
||||
|
||||
bool DBBrowserDB::renameColumn(const sqlb::Table& table, const QString& name, sqlb::FieldPtr to, int move)
|
||||
{
|
||||
/*
|
||||
* USE CASES:
|
||||
* 1) Set table; unset name, to and move: Change table constraints only.
|
||||
* 2) Set table and name; unset to and move: Change table constraints and remove column.
|
||||
* 3) Set table, name and to; unset move: Change table constraints and rename/edit column.
|
||||
* 4) Set table, name, to and move: Change table constraints, rename/edit column and move it.
|
||||
*/
|
||||
|
||||
// NOTE: This function is working around the incomplete ALTER TABLE command in SQLite.
|
||||
// If SQLite should fully support this command one day, this entire
|
||||
// function can be changed to executing something like this:
|
||||
@@ -981,9 +989,9 @@ bool DBBrowserDB::renameColumn(const sqlb::Table& table, const QString& name, sq
|
||||
|
||||
// TODO: This function needs to be cleaned up. It might make sense to split it up in several parts than can be reused
|
||||
// more easily. Besides that, it might make sense to support some potential use cases in a more sophisticated way. These include:
|
||||
// 1) Skip the entire column editing part when only the table constraints are changed.
|
||||
// 2) Allow modifying multiple columns at once in order to only have to call this function (including all its overhead) once instead of once per change.
|
||||
// 3) Include the addColumn() use case in here, so the calling side doesn't need to know anything about how this class handles table modifications.
|
||||
// 1) Allow modifying multiple columns at once in order to only have to call this function (including all its overhead) once instead of once per change.
|
||||
// 2) Include the addColumn() use case in here, so the calling side doesn't need to know anything about how this class handles table modifications.
|
||||
// 3) Maybe rename this function to alterTable() or something
|
||||
|
||||
// Collect information on the current DB layout
|
||||
QString tableSql = getObjectByName(table.name()).getsql();
|
||||
@@ -997,7 +1005,7 @@ bool DBBrowserDB::renameColumn(const sqlb::Table& table, const QString& name, sq
|
||||
sqlb::Table oldSchema = sqlb::Table::parseSQL(tableSql).first;
|
||||
|
||||
// Check if field actually exists
|
||||
if(oldSchema.findField(name) == -1)
|
||||
if(!name.isNull() && oldSchema.findField(name) == -1)
|
||||
{
|
||||
lastErrorMessage = tr("renameColumn: cannot find column %1.").arg(name);
|
||||
return false;
|
||||
@@ -1016,11 +1024,14 @@ bool DBBrowserDB::renameColumn(const sqlb::Table& table, const QString& name, sq
|
||||
sqlb::Table newSchema = oldSchema;
|
||||
newSchema.setName("sqlitebrowser_rename_column_new_table");
|
||||
newSchema.setConstraints(table.allConstraints());
|
||||
newSchema.setRowidColumn(table.rowidColumn());
|
||||
QString select_cols;
|
||||
if(to.isNull())
|
||||
{
|
||||
// We want drop the column - so just remove the field
|
||||
newSchema.removeField(name);
|
||||
// We want drop the column - so just remove the field. If the name is set to null, skip this step. This effectively leaves all fields as they are,
|
||||
// thus only changing the table constraints.
|
||||
if(!name.isNull())
|
||||
newSchema.removeField(name);
|
||||
|
||||
for(int i=0;i<newSchema.fields().count();++i)
|
||||
select_cols.append(sqlb::escapeIdentifier(newSchema.fields().at(i)->name()) + ',');
|
||||
|
||||
Reference in New Issue
Block a user