aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2023-04-30 18:30:36 -0400
committerLibravatarUnit 193 <unit193@unit193.net>2023-04-30 18:30:36 -0400
commit3565aad630864ecdbe53fdaa501ea708555b3c7c (patch)
treec743e4ad0bad39ebdb2f514c7cc52d34a257ebbe /SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
parent1fdc150116cad39aae5c5da407c3312b47a59e3a (diff)
New upstream version 3.4.4+dfsg.upstream/3.4.4+dfsg
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp74
1 files changed, 49 insertions, 25 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
index 59d978c..1a8abb6 100644
--- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
@@ -41,12 +41,14 @@ void TableModifier::alterTable(SqliteCreateTablePtr newCreateTable)
handleFkConstrains(newCreateTable.data(), createTable->table, newName);
QString tempTableName;
+ bool doCopyData = !getColumnsToCopyData(newCreateTable).isEmpty();
if (table.compare(newName, Qt::CaseInsensitive) == 0)
- tempTableName = renameToTemp();
+ tempTableName = renameToTemp(doCopyData);
newCreateTable->rebuildTokens();
sqls << newCreateTable->detokenize();
- copyDataTo(newCreateTable);
+ if (doCopyData)
+ copyDataTo(newCreateTable);
handleFks();
@@ -61,24 +63,24 @@ void TableModifier::alterTable(SqliteCreateTablePtr newCreateTable)
sqls << "PRAGMA foreign_keys = 1;";
}
-void TableModifier::renameTo(const QString& newName)
+void TableModifier::renameTo(const QString& newName, bool doCopyData)
{
if (!createTable)
return;
// Using ALTER TABLE RENAME TO is not a good solution here, because it automatically renames all occurrences in REFERENCES,
// which we don't want, because we rename a lot to temporary tables and drop them.
- sqls << QString("CREATE TABLE %1 AS SELECT * FROM %2;").arg(wrapObjIfNeeded(newName), wrapObjIfNeeded(table))
+ sqls << QString("CREATE TABLE %1 AS SELECT * FROM %2%3;").arg(wrapObjIfNeeded(newName), wrapObjIfNeeded(table), doCopyData ? "" : " LIMIT 0")
<< QString("DROP TABLE %1;").arg(wrapObjIfNeeded(table));
table = newName;
createTable->table = newName;
}
-QString TableModifier::renameToTemp()
+QString TableModifier::renameToTemp(bool doCopyData)
{
QString name = getTempTableName();
- renameTo(name);
+ renameTo(name, doCopyData);
return name;
}
@@ -189,16 +191,30 @@ bool TableModifier::handleFks(SqliteForeignKey* fk, const QString& oldName, cons
bool TableModifier::handleFkConstrains(SqliteCreateTable* stmt, const QString& oldName, const QString& theNewName)
{
bool modified = false;
- for (SqliteCreateTable::Constraint* fk : stmt->getForeignKeysByTable(oldName))
+ for (SqliteCreateTable::Constraint*& fk : stmt->getForeignKeysByTable(oldName))
{
if (handleFks(fk->foreignKey, oldName, theNewName))
+ {
modified = true;
+ if (fk->foreignKey->indexedColumns.isEmpty())
+ {
+ stmt->constraints.removeOne(fk);
+ delete fk;
+ }
+ }
}
- for (SqliteCreateTable::Column::Constraint* fk : stmt->getColumnForeignKeysByTable(oldName))
+ for (SqliteCreateTable::Column::Constraint*& fk : stmt->getColumnForeignKeysByTable(oldName))
{
if (handleFks(fk->foreignKey, oldName, theNewName))
+ {
modified = true;
+ if (fk->foreignKey->indexedColumns.isEmpty())
+ {
+ stmt->removeColumnConstraint(fk);
+ delete fk;
+ }
+ }
}
return modified;
}
@@ -302,7 +318,6 @@ bool TableModifier::handleColumnTokens(TokenList& columnsToUpdate)
bool TableModifier::handleUpdateColumns(SqliteUpdate* update)
{
bool modified = false;
- QString lowerName;
QVariant colName;
QString newName;
QStringList newNames;
@@ -401,20 +416,29 @@ QStringList TableModifier::getModifiedTables() const
return modifiedTables;
}
-void TableModifier::copyDataTo(SqliteCreateTablePtr newCreateTable)
+QList<SqliteCreateTable::Column*> TableModifier::getColumnsToCopyData(SqliteCreateTablePtr newCreateTable)
{
- QStringList existingColumns = createTable->getColumnNames();
-
- QStringList srcCols;
- QStringList dstCols;
- for (SqliteCreateTable::Column* column : newCreateTable->columns)
+ QList<SqliteCreateTable::Column*> resultColumns;
+ QStringList existingColumnsBefore = createTable->getColumnNames();
+ for (SqliteCreateTable::Column*& column : newCreateTable->columns)
{
if (column->hasConstraint(SqliteCreateTable::Column::Constraint::GENERATED))
continue;
- if (!existingColumns.contains(column->originalName))
+ if (!existingColumnsBefore.contains(column->originalName))
continue; // not copying columns that didn't exist before
+ resultColumns << column;
+ }
+ return resultColumns;
+}
+
+void TableModifier::copyDataTo(SqliteCreateTablePtr newCreateTable)
+{
+ QStringList srcCols;
+ QStringList dstCols;
+ for (SqliteCreateTable::Column*& column : getColumnsToCopyData(newCreateTable))
+ {
srcCols << wrapObjIfNeeded(column->originalName);
dstCols << wrapObjIfNeeded(column->name);
}
@@ -427,7 +451,7 @@ void TableModifier::handleIndexes()
SchemaResolver resolver(db);
resolver.setIgnoreSystemObjects(true);
QList<SqliteCreateIndexPtr> parsedIndexesForTable = resolver.getParsedIndexesForTable(originalTable);
- for (SqliteCreateIndexPtr index : parsedIndexesForTable)
+ for (SqliteCreateIndexPtr& index : parsedIndexesForTable)
handleIndex(index);
}
@@ -454,7 +478,7 @@ void TableModifier::handleTriggers()
SchemaResolver resolver(db);
resolver.setIgnoreSystemObjects(true);
QList<SqliteCreateTriggerPtr> parsedTriggersForTable = resolver.getParsedTriggersForTable(originalTable, true);
- for (SqliteCreateTriggerPtr trig : parsedTriggersForTable)
+ for (SqliteCreateTriggerPtr& trig : parsedTriggersForTable)
handleTrigger(trig);
}
@@ -527,7 +551,7 @@ void TableModifier::handleTriggerQueries(SqliteCreateTriggerPtr trigger)
{
SqliteQuery* newQuery = nullptr;
QList<SqliteQuery*> newQueries;
- for (SqliteQuery* query : trigger->queries)
+ for (SqliteQuery*& query : trigger->queries)
{
// The handleTriggerQuery() may delete the input query object. Don't refer to it later.
newQuery = handleTriggerQuery(query, trigger->trigger, trigger->table);
@@ -544,7 +568,7 @@ void TableModifier::handleViews()
SchemaResolver resolver(db);
resolver.setIgnoreSystemObjects(true);
QList<SqliteCreateViewPtr> parsedViewsForTable = resolver.getParsedViewsForTable(originalTable);
- for (SqliteCreateViewPtr view : parsedViewsForTable)
+ for (SqliteCreateViewPtr& view : parsedViewsForTable)
handleView(view);
}
@@ -608,12 +632,12 @@ SqliteSelect* TableModifier::handleSelect(SqliteSelect* select, const QString& t
QList<SqliteSelect::Core::SingleSource*> selSources = select->getAllTypedStatements<SqliteSelect::Core::SingleSource>();
TokenList tableTokens;
StrHash<SelectResolver::Table> resolvedTables;
- for (SqliteSelect::Core* core : select->coreSelects)
+ for (SqliteSelect::Core*& core : select->coreSelects)
{
resolvedTables = tablesAsNameHash(selectResolver.resolveTables(core));
tableTokens = core->getContextTableTokens(false);
- for (TokenPtr token : tableTokens)
+ for (TokenPtr& token : tableTokens)
{
if (token->value.compare(originalTable, Qt::CaseInsensitive) != 0)
continue;
@@ -868,7 +892,7 @@ bool TableModifier::handleExpr(SqliteExpr* expr)
if (!exprList.isEmpty())
{
bool res = true;
- for (SqliteExpr* e : exprList)
+ for (SqliteExpr*& e : exprList)
{
res &= handleExpr(e);
if (!res)
@@ -906,7 +930,7 @@ void TableModifier::simpleHandleIndexes()
SchemaResolver resolver(db);
resolver.setIgnoreSystemObjects(true);
QList<SqliteCreateIndexPtr> parsedIndexesForTable = resolver.getParsedIndexesForTable(originalTable);
- for (SqliteCreateIndexPtr index : parsedIndexesForTable)
+ for (SqliteCreateIndexPtr& index : parsedIndexesForTable)
sqls << index->detokenize();
}
@@ -920,7 +944,7 @@ void TableModifier::simpleHandleTriggers(const QString& view)
else
parsedTriggers = resolver.getParsedTriggersForTable(originalTable);
- for (SqliteCreateTriggerPtr trig : parsedTriggers)
+ for (SqliteCreateTriggerPtr& trig : parsedTriggers)
sqls << trig->detokenize();
}