Improve movement of tables between different schemata

This improves the Edit Table dialog to better handle moving tables from
one schema to another, though the UI currently only knows about the main
and the temp schema.

This also simplifies the grammar code by removing the temporary flag
from all classes because it's redundant now that we support multiple
schemata.
This commit is contained in:
Martin Kleusberg
2017-09-04 17:38:08 +02:00
parent a5ca75655c
commit 7db96cdf13
5 changed files with 17 additions and 23 deletions

View File

@@ -40,7 +40,7 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier&
// for error checking etc.
ui->checkWithoutRowid->blockSignals(true);
ui->checkWithoutRowid->setChecked(m_table.isWithoutRowidTable());
ui->checkTemporary->setChecked(m_table.isTemporary());
ui->checkTemporary->setChecked(curTable.schema() == "temp");
ui->checkWithoutRowid->blockSignals(false);
populateFields();
@@ -720,16 +720,13 @@ void EditTableDialog::setWithoutRowid(bool without_rowid)
void EditTableDialog::setTemporary(bool is_temp)
{
// Set the temporary flag in the table definition
m_table.setTemporary(is_temp);
// Update the SQL preview
updateSqlText();
// Update table if we're editing an existing table
if(!m_bNewTable)
{
if(!pdb.renameColumn(curTable, m_table, QString(), sqlb::FieldPtr(), 0))
if(!pdb.renameColumn(curTable, m_table, QString(), sqlb::FieldPtr(), 0, is_temp ? "temp" : "main"))
{
QMessageBox::warning(this, QApplication::applicationName(),
tr("Setting the temporary flag for the table failed. Error message:\n%1").arg(pdb.lastError()));

View File

@@ -1038,7 +1038,7 @@ bool DBBrowserDB::addColumn(const sqlb::ObjectIdentifier& tablename, const sqlb:
return executeSQL(sql);
}
bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sqlb::Table& table, const QString& name, sqlb::FieldPtr to, int move)
bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sqlb::Table& table, const QString& name, sqlb::FieldPtr to, int move, QString newSchemaName)
{
/*
* USE CASES:
@@ -1089,7 +1089,6 @@ bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sq
newSchema.setName("sqlitebrowser_rename_column_new_table");
newSchema.setConstraints(table.allConstraints());
newSchema.setRowidColumn(table.rowidColumn());
newSchema.setTemporary(table.isTemporary());
QString select_cols;
if(to.isNull())
{
@@ -1123,9 +1122,13 @@ bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sq
newSchema.setField(index + move, to);
}
// If no new schema name has been set, we just use the old schema name
if(newSchemaName.isNull())
newSchemaName = tablename.schema();
// Create the new table
NoStructureUpdateChecks nup(*this);
if(!executeSQL(newSchema.sql(tablename.schema()), true, true))
if(!executeSQL(newSchema.sql(newSchemaName), true, true))
{
QString error(tr("renameColumn: creating new table failed. DB says: %1").arg(lastErrorMessage));
revertToSavepoint(savepointName);
@@ -1135,7 +1138,7 @@ bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sq
// Copy the data from the old table to the new one
if(!executeSQL(QString("INSERT INTO %1.sqlitebrowser_rename_column_new_table SELECT %2 FROM %3;")
.arg(tablename.schema())
.arg(newSchemaName)
.arg(select_cols)
.arg(tablename.toString())))
{
@@ -1173,9 +1176,10 @@ bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sq
;
}
// Only try to add the index later if it has any columns remaining
// Only try to add the index later if it has any columns remaining. Also use the new schema name here, too, to basically move
// any index that references the table to the same new schema as the table.
if(idx->columns().size())
otherObjectsSql << idx->sql();
otherObjectsSql << idx->sql(newSchemaName);
} else {
// If it's a view or a trigger we don't have any chance to corrections yet. Just store the statement as is and
// hope for the best.
@@ -1202,7 +1206,7 @@ bool DBBrowserDB::renameColumn(const sqlb::ObjectIdentifier& tablename, const sq
}
// Rename the temporary table
if(!renameTable(tablename.schema(), "sqlitebrowser_rename_column_new_table", tablename.name()))
if(!renameTable(newSchemaName, "sqlitebrowser_rename_column_new_table", tablename.name()))
{
revertToSavepoint(savepointName);
return false;
@@ -1362,8 +1366,6 @@ void DBBrowserDB::updateSchema()
if(!val_sql.isEmpty())
{
sqlb::ObjectPtr object = sqlb::Object::parseSQL(type, val_sql);
if(schema_name == "temp")
object->setTemporary(true);
// If parsing wasn't successful set the object name manually, so that at least the name is going to be correct
if(!object->fullyParsed())

View File

@@ -84,9 +84,10 @@ public:
* @param name Name of the column to edit
* @param to The new field definition with changed name, type or the like. If Null-Pointer is given the column is dropped.
* @param move Set this to a value != 0 to move the new column to a different position
* @param newSchema Set this to a non-empty string to move the table to a new schema
* @return true if renaming was successful, false if not. In the latter case also lastErrorMessage is set
*/
bool renameColumn(const sqlb::ObjectIdentifier& tablename, const sqlb::Table& table, const QString& name, sqlb::FieldPtr to, int move = 0);
bool renameColumn(const sqlb::ObjectIdentifier& tablename, const sqlb::Table& table, const QString& name, sqlb::FieldPtr to, int move = 0, QString newSchemaName = QString());
objectMap getBrowsableObjects(const QString& schema) const;
const sqlb::ObjectPtr getObjectByName(const sqlb::ObjectIdentifier& name) const;

View File

@@ -253,7 +253,6 @@ void Table::clear()
m_fields.clear();
m_constraints.clear();
m_virtual = QString();
m_temporary = false;
}
Table::~Table()
{
@@ -456,8 +455,7 @@ QString Table::sql(const QString& schema, bool ifNotExists) const
return QString("CREATE VIRTUAL TABLE %1 USING %2;").arg(ObjectIdentifier(schema, m_name).toString(true)).arg(m_virtual);
// This is a normal table, not a virtual one
QString sql = QString("CREATE %1TABLE%2 %3 (\n")
.arg(m_temporary ? QString("TEMPORARY ") : QString(""))
QString sql = QString("CREATE TABLE%1 %2 (\n")
.arg(ifNotExists ? QString(" IF NOT EXISTS") : QString(""))
.arg(ObjectIdentifier(schema, m_name).toString(true));

View File

@@ -142,7 +142,7 @@ public:
Trigger
};
explicit Object(const QString& name): m_name(name), m_temporary(false), m_fullyParsed(false) {}
explicit Object(const QString& name): m_name(name), m_fullyParsed(false) {}
virtual ~Object() {}
virtual Types type() const = 0;
@@ -154,9 +154,6 @@ public:
void setOriginalSql(const QString& original_sql) { m_originalSql = original_sql; }
QString originalSql() const { return m_originalSql; }
void setTemporary(bool temp) { m_temporary = temp; }
bool isTemporary() const { return m_temporary; }
virtual QString baseTable() const { return QString(); }
void setFullyParsed(bool fully_parsed) { m_fullyParsed = fully_parsed; }
@@ -185,7 +182,6 @@ public:
protected:
QString m_name;
QString m_originalSql;
bool m_temporary;
bool m_fullyParsed;
};