aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/schemaresolver.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/schemaresolver.cpp
parent1fdc150116cad39aae5c5da407c3312b47a59e3a (diff)
New upstream version 3.4.4+dfsg.upstream/3.4.4+dfsg
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp106
1 files changed, 92 insertions, 14 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
index 4d65461..129bb43 100644
--- a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
@@ -98,14 +98,15 @@ StrHash<QStringList> SchemaResolver::getGroupedTriggers(const QString &database)
StrHash<QStringList> SchemaResolver::getGroupedObjects(const QString &database, const QStringList &inputList, SqliteQueryType type)
{
QString strType = sqliteQueryTypeToString(type);
+ ObjectType objectType = objectTypeFromQueryType(type);
StrHash<QStringList> groupedObjects;
SqliteQueryPtr parsedQuery;
SqliteTableRelatedDdlPtr tableRelatedDdl;
- for (QString object : inputList)
+ for (const QString& object : inputList)
{
- parsedQuery = getParsedObject(database, object, ANY);
+ parsedQuery = getParsedObject(database, object, objectType);
if (!parsedQuery)
{
qWarning() << "Could not get parsed object for " << strType << ":" << object;
@@ -116,7 +117,8 @@ StrHash<QStringList> SchemaResolver::getGroupedObjects(const QString &database,
if (!tableRelatedDdl)
{
qWarning() << "Parsed object is not of expected type. Expected" << strType
- << ", but got" << sqliteQueryTypeToString(parsedQuery->queryType);
+ << ", but got" << sqliteQueryTypeToString(parsedQuery->queryType)
+ << "; Object db and name:" << database << object;
continue;
}
@@ -145,12 +147,12 @@ QSet<QString> SchemaResolver::getDatabases()
return db->getAllAttaches();
}
-QStringList SchemaResolver::getTableColumns(const QString& table)
+QStringList SchemaResolver::getTableColumns(const QString& table, bool onlyReal)
{
- return getTableColumns("main", table);
+ return getTableColumns("main", table, onlyReal);
}
-QStringList SchemaResolver::getTableColumns(const QString &database, const QString &table)
+QStringList SchemaResolver::getTableColumns(const QString &database, const QString &table, bool onlyReal)
{
QStringList columns; // result
@@ -178,7 +180,12 @@ QStringList SchemaResolver::getTableColumns(const QString &database, const QStri
// Now we have a regular table, let's extract columns.
for (SqliteCreateTable::Column* column : createTable->columns)
+ {
+ if (onlyReal && column->hasConstraint(SqliteCreateTable::Column::Constraint::GENERATED))
+ continue;
+
columns << column->name;
+ }
return columns;
}
@@ -272,12 +279,14 @@ QList<SelectResolver::Column> SchemaResolver::getViewColumnObjects(const QString
SqliteCreateTablePtr SchemaResolver::virtualTableAsRegularTable(const QString &database, const QString &table)
{
- QString strippedName = stripObjName(table);
+ // The "table" name here used to be stripped with stripObjName(), but actually [abc] is a proper table name,
+ // that should not be stripped. Any names passed to SchemaResolver cannot be wrapped.
+
QString dbName = getPrefixDb(database);
// Create temp table to see columns.
- QString newTable = db->getUniqueNewObjectName(strippedName);
- QString origTable = wrapObjIfNeeded(strippedName);
+ QString newTable = db->getUniqueNewObjectName(table);
+ QString origTable = wrapObjIfNeeded(table);
SqlQueryPtr tempTableRes = db->exec(QString("CREATE TEMP TABLE %1 AS SELECT * FROM %2.%3 LIMIT 0;").arg(newTable, dbName, origTable), dbFlags);
if (tempTableRes->isError())
qWarning() << "Could not create temp table to identify virtual table columns of virtual table " << origTable << ". Error details:" << tempTableRes->getErrorText();
@@ -303,6 +312,9 @@ QString SchemaResolver::getObjectDdl(const QString& name, ObjectType type)
QString SchemaResolver::getObjectDdl(const QString &database, const QString &name, ObjectType type)
{
+ // The "name" here used to be stripped with stripObjName(), but actually [abc] is a proper object name,
+ // that should not be stripped. Any names passed to SchemaResolver cannot be wrapped.
+
if (name.isNull())
return QString();
@@ -310,13 +322,13 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam
QString dbName = getPrefixDb(database);
// In case of sqlite_master or sqlite_temp_master we have static definitions
- QString lowerName = stripObjName(name).toLower();
+ QString lowerName = name.toLower();
if (lowerName == "sqlite_master")
return getSqliteMasterDdl(false);
else if (lowerName == "sqlite_temp_master")
return getSqliteMasterDdl(true);
else if (lowerName.startsWith("sqlite_autoindex_"))
- return getSqliteAutoIndexDdl(dbName, stripObjName(name));
+ return getSqliteAutoIndexDdl(dbName, name);
// Standalone or temp table?
QString targetTable = "sqlite_master";
@@ -648,7 +660,7 @@ QString SchemaResolver::getSqliteAutoIndexDdl(const QString& database, const QSt
}
// Check the unique flag of the index
- static_qstring(idxUniqueQueryTpl, "SELECT unique FROM %1.pragma_index_list(%2) WHERE name = ?");
+ static_qstring(idxUniqueQueryTpl, "SELECT [unique] FROM %1.pragma_index_list(%2) WHERE name = ?");
SqlQueryPtr uniqRes = db->exec(idxUniqueQueryTpl.arg(dbName, wrapString(table)), {index}, dbFlags);
bool unique = uniqRes->getSingleCell().toInt() > 0;
@@ -846,6 +858,47 @@ QStringList SchemaResolver::getFkReferencingTables(const QString& table, const Q
return tables;
}
+SchemaResolver::ObjectType SchemaResolver::objectTypeFromQueryType(const SqliteQueryType& queryType)
+{
+ switch (queryType)
+ {
+ case SqliteQueryType::CreateIndex:
+ return INDEX;
+ case SqliteQueryType::CreateTrigger:
+ return TRIGGER;
+ case SqliteQueryType::CreateView:
+ return VIEW;
+ case SqliteQueryType::CreateTable:
+ case SqliteQueryType::CreateVirtualTable:
+ return TABLE;
+ case SqliteQueryType::Select:
+ case SqliteQueryType::Pragma:
+ case SqliteQueryType::UNDEFINED:
+ case SqliteQueryType::EMPTY:
+ case SqliteQueryType::AlterTable:
+ case SqliteQueryType::Analyze:
+ case SqliteQueryType::Attach:
+ case SqliteQueryType::BeginTrans:
+ case SqliteQueryType::CommitTrans:
+ case SqliteQueryType::Copy:
+ case SqliteQueryType::Delete:
+ case SqliteQueryType::Detach:
+ case SqliteQueryType::DropIndex:
+ case SqliteQueryType::DropTable:
+ case SqliteQueryType::DropTrigger:
+ case SqliteQueryType::DropView:
+ case SqliteQueryType::Insert:
+ case SqliteQueryType::Reindex:
+ case SqliteQueryType::Release:
+ case SqliteQueryType::Rollback:
+ case SqliteQueryType::Savepoint:
+ case SqliteQueryType::Update:
+ case SqliteQueryType::Vacuum:
+ return ANY;
+ }
+ return ANY;
+}
+
QStringList SchemaResolver::getIndexesForTable(const QString& database, const QString& table)
{
static_qstring(idxForTableTpl, "SELECT name FROM %1.pragma_index_list(%2)");
@@ -1150,7 +1203,7 @@ bool SchemaResolver::isWithoutRowIdTable(const QString& database, const QString&
if (!createTable)
return false;
- return !createTable->withOutRowId.isNull();
+ return createTable->withOutRowId;
}
bool SchemaResolver::isVirtualTable(const QString& database, const QString& table)
@@ -1195,7 +1248,7 @@ QStringList SchemaResolver::getWithoutRowIdTableColumns(const QString& database,
if (!createTable)
return columns;
- if (createTable->withOutRowId.isNull())
+ if (!createTable->withOutRowId)
return columns; // it's not WITHOUT ROWID table
return createTable->getPrimaryKeyColumns();
@@ -1252,6 +1305,31 @@ void SchemaResolver::setNoDbLocking(bool value)
dbFlags ^= Db::Flag::NO_LOCK;
}
+QString SchemaResolver::normalizeCaseObjectName(const QString& name)
+{
+ static_qstring(sql, "SELECT name FROM main.sqlite_master WHERE lower(name) = lower(?);");
+ return normalizeCaseObjectNameByQuery(sql, name);
+}
+
+QString SchemaResolver::normalizeCaseObjectName(const QString& database, const QString& name)
+{
+ static_qstring(sql, "SELECT name FROM %1.sqlite_master WHERE lower(name) = lower(?);");
+ QString query = sql.arg(wrapObjIfNeeded(database));
+ return normalizeCaseObjectNameByQuery(query, name);
+}
+
+QString SchemaResolver::normalizeCaseObjectNameByQuery(const QString& query, const QString& name)
+{
+ SqlQueryPtr results = db->exec(query, {name});
+ if (results->isError())
+ {
+ qCritical() << "Could not get object name normalized case. Object name:" << name << ", error:"
+ << results->getErrorText();
+ return name;
+ }
+
+ return results->getSingleCell().toString();
+}
SchemaResolver::ObjectCacheKey::ObjectCacheKey(Type type, Db* db, const QString& value1, const QString& value2, const QString& value3) :
type(type), db(db), value1(value1), value2(value2), value3(value3)