From 7167ce41b61d2ba2cdb526777a4233eb84a3b66a Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Sat, 6 Dec 2014 17:33:25 -0500 Subject: Imported Upstream version 2.99.6 --- SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp | 127 ++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp (limited to 'SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp') diff --git a/SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp b/SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp new file mode 100644 index 0000000..36ab457 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/viewmodifier.cpp @@ -0,0 +1,127 @@ +#include "viewmodifier.h" +#include "common/utils_sql.h" +#include "parser/parser.h" +#include "schemaresolver.h" +#include "selectresolver.h" +#include "parser/ast/sqlitecreatetrigger.h" +#include "common/unused.h" + +ViewModifier::ViewModifier(Db* db, const QString& view) : + ViewModifier(db, "main", view) +{ +} + +ViewModifier::ViewModifier(Db* db, const QString& database, const QString& view) : + db(db), database(database), view(view) +{ + dialect = db->getDialect(); +} + +void ViewModifier::alterView(const QString& newView) +{ + Parser parser(dialect); + if (!parser.parse(newView) || parser.getQueries().size() == 0) + { + errors << QObject::tr("Could not parse DDL of the view to be created. Details: %1").arg(parser.getErrorString()); + return; + } + + SqliteQueryPtr query = parser.getQueries().first(); + createView = query.dynamicCast(); + + if (!createView) + { + errors << QObject::tr("Parsed query is not CREATE VIEW. It's: %1").arg(sqliteQueryTypeToString(query->queryType)); + return; + } + + alterView(createView); +} + +void ViewModifier::alterView(SqliteCreateViewPtr newView) +{ + createView = newView; + + addMandatorySql(QString("DROP VIEW %1").arg(wrapObjIfNeeded(view, dialect))); + addMandatorySql(newView->detokenize()); + + collectNewColumns(); + handleTriggers(); + + // TODO handle other views selecting from this view +} + +void ViewModifier::handleTriggers() +{ + SchemaResolver resolver(db); + QList triggers = resolver.getParsedTriggersForView(view, true); + foreach (SqliteCreateTriggerPtr trigger, triggers) + { + addOptionalSql(QString("DROP TRIGGER %1").arg(wrapObjIfNeeded(trigger->trigger, dialect))); + + if (!handleNewColumns(trigger)) + continue; + + addOptionalSql(trigger->detokenize()); + } +} + +bool ViewModifier::handleNewColumns(SqliteCreateTriggerPtr trigger) +{ + UNUSED(trigger); + // TODO update all occurances of columns in "UPDATE OF" and statements inside, just like it would be done in TableModifier. + return true; +} + +void ViewModifier::collectNewColumns() +{ + SelectResolver resolver(db, createView->select->detokenize()); + QList > multiColumns = resolver.resolve(createView->select); + if (multiColumns.size() < 1) + { + warnings << QObject::tr("SQLiteStudio was unable to resolve columns returned by the new view, " + "therefore it won't be able to tell which triggers might fail during the recreation process."); + return; + } + + foreach (const SelectResolver::Column& col, multiColumns.first()) + newColumns << col.column; +} + +void ViewModifier::addMandatorySql(const QString& sql) +{ + sqls << sql; + sqlMandatoryFlags << true; +} + +void ViewModifier::addOptionalSql(const QString& sql) +{ + + sqls << sql; + sqlMandatoryFlags << false; +} + +QStringList ViewModifier::generateSqls() const +{ + return sqls; +} + +QList ViewModifier::getMandatoryFlags() const +{ + return sqlMandatoryFlags; +} + +QStringList ViewModifier::getWarnings() const +{ + return warnings; +} + +QStringList ViewModifier::getErrors() const +{ + return errors; +} + +bool ViewModifier::hasMessages() const +{ + return errors.size() > 0 || warnings.size() > 0; +} -- cgit v1.2.3