aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2015-04-04 14:41:10 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2015-04-04 14:41:10 -0400
commitb5f93b05578293d1d233b4920a28a5c2fd826f94 (patch)
tree82332679f647e9c76e331206786d07a58dcfa9b8 /SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
parentaf8a7a3e3dccf9c9ad257e3952173d180c8a7421 (diff)
parenta5b034d4a9c44f9bc1e83b01de82530f8fc63013 (diff)
Merge tag 'upstream/3.0.4'
Upstream version 3.0.4 # gpg: Signature made Sat 04 Apr 2015 02:41:09 PM EDT using RSA key ID EBE9BD91 # gpg: Good signature from "Unit 193 <unit193@gmail.com>" # gpg: aka "Unit 193 <unit193@ninthfloor.org>" # gpg: aka "Unit 193 <unit193@ubuntu.com>" # gpg: aka "Unit 193 <unit193@ninthfloor.com>"
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp120
1 files changed, 90 insertions, 30 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
index 8dc36ee..973402a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp
@@ -10,6 +10,7 @@
#include "parser/ast/sqliteupdate.h"
#include "parser/ast/sqliteinsert.h"
#include "parser/ast/sqlitedelete.h"
+#include "common/unused.h"
#include <QDebug>
// TODO no attach/temp db name support in this entire class
@@ -458,7 +459,7 @@ void TableModifier::handleTriggerQueries(SqliteCreateTriggerPtr trigger)
foreach (SqliteQuery* query, trigger->queries)
{
// The handleTriggerQuery() may delete the input query object. Don't refer to it later.
- newQuery = handleTriggerQuery(query, trigger->trigger);
+ newQuery = handleTriggerQuery(query, trigger->trigger, trigger->table);
if (newQuery)
newQueries << newQuery;
else
@@ -497,28 +498,28 @@ void TableModifier::handleView(SqliteCreateViewPtr view)
modifiedViews << view->view;
}
-SqliteQuery* TableModifier::handleTriggerQuery(SqliteQuery* query, const QString& trigName)
+SqliteQuery* TableModifier::handleTriggerQuery(SqliteQuery* query, const QString& trigName, const QString& trigTable)
{
SqliteSelect* select = dynamic_cast<SqliteSelect*>(query);
if (select)
- return handleSelect(select);
+ return handleSelect(select, trigTable);
SqliteUpdate* update = dynamic_cast<SqliteUpdate*>(query);
if (update)
- return handleTriggerUpdate(update, trigName);
+ return handleTriggerUpdate(update, trigName, trigTable);
SqliteInsert* insert = dynamic_cast<SqliteInsert*>(query);
if (insert)
- return handleTriggerInsert(insert, trigName);
+ return handleTriggerInsert(insert, trigName, trigTable);
SqliteDelete* del = dynamic_cast<SqliteDelete*>(query);
if (del)
- return handleTriggerDelete(del, trigName);
+ return handleTriggerDelete(del, trigName, trigTable);
return nullptr;
}
-SqliteSelect* TableModifier::handleSelect(SqliteSelect* select)
+SqliteSelect* TableModifier::handleSelect(SqliteSelect* select, const QString& trigTable)
{
// Table name
TokenList tableTokens = select->getContextTableTokens(false);
@@ -561,76 +562,92 @@ SqliteSelect* TableModifier::handleSelect(SqliteSelect* select)
return nullptr;
}
+ if (!trigTable.isNull() && !handleAllExprWithTrigTable(selectPtr.data(), trigTable))
+ return nullptr;
+
return new SqliteSelect(*selectPtr.data());
}
-SqliteUpdate* TableModifier::handleTriggerUpdate(SqliteUpdate* update, const QString& trigName)
+SqliteUpdate* TableModifier::handleTriggerUpdate(SqliteUpdate* update, const QString& trigName, const QString& trigTable)
{
- // Table name
if (update->table.compare(originalTable, Qt::CaseInsensitive) == 0)
+ {
+ // Table name
update->table = newName;
- // Column names
- handleUpdateColumns(update);
+ // Column names
+ handleUpdateColumns(update);
+ }
// Any embedded selects
- bool embedSelectsOk = handleSubSelects(update);
- if (!embedSelectsOk)
+ bool embedSelectsOk = handleSubSelects(update, trigTable);
+ bool embedExprOk = handleAllExprWithTrigTable(update, trigTable);
+ if (!embedSelectsOk || !embedExprOk)
{
warnings << QObject::tr("There is a problem with updating an %1 statement within %2 trigger. "
- "One of the SELECT substatements which might be referring to table %3 cannot be properly modified. "
- "Manual update of the trigger may be necessary.").arg("UPDATE").arg(trigName).arg(originalTable);
+ "One of the %1 substatements which might be referring to table %3 cannot be properly modified. "
+ "Manual update of the trigger may be necessary.").arg("UPDATE", trigName, originalTable);
}
return update;
}
-SqliteInsert* TableModifier::handleTriggerInsert(SqliteInsert* insert, const QString& trigName)
+SqliteInsert* TableModifier::handleTriggerInsert(SqliteInsert* insert, const QString& trigName, const QString& trigTable)
{
- // Table name
if (insert->table.compare(originalTable, Qt::CaseInsensitive) == 0)
+ {
+ // Table name
insert->table = newName;
- // Column names
- handleColumnNames(insert->columnNames);
+ // Column names
+ handleColumnNames(insert->columnNames);
+ }
// Any embedded selects
- bool embedSelectsOk = handleSubSelects(insert);
- if (!embedSelectsOk)
+ bool embedSelectsOk = handleSubSelects(insert, trigTable);
+ bool embedExprOk = handleAllExprWithTrigTable(insert, trigTable);
+ if (!embedSelectsOk || !embedExprOk)
{
warnings << QObject::tr("There is a problem with updating an %1 statement within %2 trigger. "
- "One of the SELECT substatements which might be referring to table %3 cannot be properly modified. "
+ "One of the %1 substatements which might be referring to table %3 cannot be properly modified. "
"Manual update of the trigger may be necessary.").arg("INSERT", trigName, originalTable);
}
return insert;
}
-SqliteDelete* TableModifier::handleTriggerDelete(SqliteDelete* del, const QString& trigName)
+SqliteDelete* TableModifier::handleTriggerDelete(SqliteDelete* del, const QString& trigName, const QString& trigTable)
{
// Table name
if (del->table.compare(originalTable, Qt::CaseInsensitive) == 0)
del->table = newName;
// Any embedded selects
- bool embedSelectsOk = handleSubSelects(del);
- if (!embedSelectsOk)
+ bool embedSelectsOk = handleSubSelects(del, trigTable);
+ bool embedExprOk = handleAllExprWithTrigTable(del, trigTable);
+ if (!embedSelectsOk || !embedExprOk)
{
warnings << QObject::tr("There is a problem with updating an %1 statement within %2 trigger. "
- "One of the SELECT substatements which might be referring to table %3 cannot be properly modified. "
+ "One of the %1 substatements which might be referring to table %3 cannot be properly modified. "
"Manual update of the trigger may be necessary.").arg("DELETE", trigName, originalTable);
}
return del;
}
-bool TableModifier::handleSubSelects(SqliteStatement* stmt)
+bool TableModifier::handleSubSelects(SqliteStatement* stmt, const QString& trigTable)
{
bool embedSelectsOk = true;
QList<SqliteSelect*> selects = stmt->getAllTypedStatements<SqliteSelect>();
SqliteExpr* expr = nullptr;
foreach (SqliteSelect* select, selects)
{
+ if (select->coreSelects.size() >= 1 && select->coreSelects.first()->valuesMode)
+ {
+ // INSERT with VALUES() as subselect
+ continue;
+ }
+
expr = dynamic_cast<SqliteExpr*>(select->parentStatement());
if (!expr)
{
@@ -638,13 +655,13 @@ bool TableModifier::handleSubSelects(SqliteStatement* stmt)
continue;
}
- if (!handleExprWithSelect(expr))
+ if (!handleExprWithSelect(expr, trigTable))
embedSelectsOk = false;
}
return embedSelectsOk;
}
-bool TableModifier::handleExprWithSelect(SqliteExpr* expr)
+bool TableModifier::handleExprWithSelect(SqliteExpr* expr, const QString& trigTable)
{
if (!expr->select)
{
@@ -652,7 +669,7 @@ bool TableModifier::handleExprWithSelect(SqliteExpr* expr)
return false;
}
- SqliteSelect* newSelect = handleSelect(expr->select);
+ SqliteSelect* newSelect = handleSelect(expr->select, trigTable);
if (!newSelect)
{
qCritical() << "Could not generate new SELECT in TableModifier::handleExprWithSelect()";
@@ -665,6 +682,49 @@ bool TableModifier::handleExprWithSelect(SqliteExpr* expr)
return true;
}
+bool TableModifier::handleAllExprWithTrigTable(SqliteStatement* stmt, const QString& contextTable)
+{
+ if (contextTable != originalTable)
+ return true;
+
+ return handleExprListWithTrigTable(stmt->getAllTypedStatements<SqliteExpr>());
+}
+
+bool TableModifier::handleExprListWithTrigTable(const QList<SqliteExpr*>& exprList)
+{
+ for (SqliteExpr* expr : exprList)
+ {
+ if (!handleExprWithTrigTable(expr))
+ return false;
+ }
+ return true;
+}
+
+bool TableModifier::handleExprWithTrigTable(SqliteExpr* expr)
+{
+ if (expr->mode != SqliteExpr::Mode::ID)
+ return true;
+
+ if (!expr->database.isNull())
+ return true;
+
+ if (expr->table.compare("old", Qt::CaseInsensitive) != 0 && expr->table.compare("new", Qt::CaseInsensitive) != 0)
+ return true;
+
+ QStringList columns = QStringList({expr->column});
+ if (!handleColumnNames(columns))
+ return true;
+
+ if (columns.isEmpty())
+ {
+ qDebug() << "Column in the expression is no longer present in the table. Cannot update the expression automatically.";
+ return false;
+ }
+
+ expr->column = columns.first();
+ return true;
+}
+
void TableModifier::simpleHandleIndexes()
{
SchemaResolver resolver(db);