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 --- .../coreSQLiteStudio/impl/dbattacherimpl.cpp | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp (limited to 'SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp') diff --git a/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp new file mode 100644 index 0000000..75d94eb --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp @@ -0,0 +1,178 @@ +#include "dbattacherimpl.h" +#include "db/db.h" +#include "services/dbmanager.h" +#include "parser/parser.h" +#include "services/notifymanager.h" +#include "common/utils_sql.h" +#include + +DbAttacherImpl::DbAttacherImpl(Db* db) +{ + this->db = db; + dialect = db->getDialect(); +} + +bool DbAttacherImpl::attachDatabases(const QString& query) +{ + Parser parser(dialect); + if (!parser.parse(query)) + return false; + + queries = parser.getQueries(); + return attachDatabases(); +} + +bool DbAttacherImpl::attachDatabases(const QList& queries) +{ + this->queries = queries; + return attachDatabases(); +} + +bool DbAttacherImpl::attachDatabases(SqliteQueryPtr query) +{ + queries.clear(); + queries << query; + return attachDatabases(); +} + +void DbAttacherImpl::detachDatabases() +{ + detachAttached(); +} + +bool DbAttacherImpl::attachDatabases() +{ + dbNameToAttach.clear(); + + prepareNameToDbMap(); + + TokenList dbTokens = getDbTokens(); + QHash groupedDbTokens = groupDbTokens(dbTokens); + + if (!attachAllDbs(groupedDbTokens)) + return false; + + QHash tokenMapping = getTokenMapping(dbTokens); + replaceTokensInQueries(tokenMapping); + + return true; +} + +TokenList DbAttacherImpl::getDbTokens() +{ + TokenList dbTokens; + foreach (SqliteQueryPtr query, queries) + dbTokens += query->getContextDatabaseTokens(); + + return dbTokens; +} + +void DbAttacherImpl::detachAttached() +{ + foreach (const QString& dbName, dbNameToAttach.leftValues()) + db->detach(nameToDbMap[dbName]); + + dbNameToAttach.clear(); + nameToDbMap.clear(); +} + +void DbAttacherImpl::prepareNameToDbMap() +{ + foreach (Db* db, DBLIST->getValidDbList()) + nameToDbMap[db->getName()] = db; +} + +QHash DbAttacherImpl::groupDbTokens(const TokenList& dbTokens) +{ + // Filter out tokens of unknown databases and group results by name + QHash groupedDbTokens; + QString strippedName; + foreach (TokenPtr token, dbTokens) + { + strippedName = stripObjName(token->value, dialect); + if (!nameToDbMap.contains(strippedName, Qt::CaseInsensitive)) + continue; + + groupedDbTokens[strippedName] += token; + } + return groupedDbTokens; +} + +bool DbAttacherImpl::attachAllDbs(const QHash& groupedDbTokens) +{ + QString attachName; + foreach (const QString& dbName, groupedDbTokens.keys()) + { + attachName = db->attach(nameToDbMap[dbName]); + if (attachName.isNull()) + { + notifyError(QObject::tr("Could not attach database %1: %2").arg(dbName).arg(db->getErrorText())); + detachAttached(); + return false; + } + + dbNameToAttach.insert(dbName, attachName); + } + return true; +} + +QHash DbAttacherImpl::getTokenMapping(const TokenList& dbTokens) +{ + QHash tokenMapping; + QString strippedName; + TokenPtr dstToken; + foreach (TokenPtr srcToken, dbTokens) + { + strippedName = stripObjName(srcToken->value, dialect); + if (strippedName.compare("main", Qt::CaseInsensitive) == 0 || + strippedName.compare("temp", Qt::CaseInsensitive) == 0) + continue; + + if (!dbNameToAttach.containsLeft(strippedName, Qt::CaseInsensitive)) + { + qCritical() << "DB token to be replaced, but it's not on nameToAlias map! Token value:" << strippedName + << "and nameToAlias map has keys:" << dbNameToAttach.leftValues(); + continue; + } + dstToken = TokenPtr::create(dbNameToAttach.valueByLeft(strippedName, Qt::CaseInsensitive)); + tokenMapping[srcToken] = dstToken; + } + return tokenMapping; +} + +void DbAttacherImpl::replaceTokensInQueries(const QHash& tokenMapping) +{ + int idx; + QHashIterator it(tokenMapping); + while (it.hasNext()) + { + it.next(); + foreach (SqliteQueryPtr query, queries) + { + idx = query->tokens.indexOf(it.key()); + if (idx < 0) + continue; // token not in this query, most likely in other query + + query->tokens.replace(idx, it.value()); + } + } +} + +BiStrHash DbAttacherImpl::getDbNameToAttach() const +{ + return dbNameToAttach; +} + +QString DbAttacherImpl::getQuery() const +{ + QStringList queryStrings; + foreach (SqliteQueryPtr query, queries) + queryStrings << query->detokenize(); + + return queryStrings.join(";"); +} + +DbAttacher* DbAttacherDefaultFactory::create(Db* db) +{ + return new DbAttacherImpl(db); +} -- cgit v1.2.3