aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2015-04-19 22:30:43 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2015-04-19 22:30:43 -0400
commit094918f048c81474b22f9ba2940c96dc4033d753 (patch)
tree2b89c77ad7dc9c55e9ba383f23f9f25b82df358e /SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
parent640fff60ceecde402131937dddb3458f7a003e9c (diff)
parenta308f430f694423064ebc86fd0506c8c6fdb3d93 (diff)
Merge tag 'upstream/3.0.5'
Upstream version 3.0.5 # gpg: Signature made Sun 19 Apr 2015 10:30:41 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/schemaresolver.cpp')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp92
1 files changed, 81 insertions, 11 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
index f14d23d..7988748 100644
--- a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp
@@ -14,6 +14,8 @@ const char* sqliteMasterDdl =
const char* sqliteTempMasterDdl =
"CREATE TABLE sqlite_temp_master (type text, name text, tbl_name text, rootpage integer, sql text)";
+ExpiringCache<SchemaResolver::ObjectCacheKey,QVariant> SchemaResolver::cache;
+
SchemaResolver::SchemaResolver(Db *db)
: db(db)
{
@@ -286,12 +288,19 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam
// Prepare db prefix.
QString dbName = getPrefixDb(database, dialect);
+ // Cache
+ QString typeStr = objectTypeToString(type);
+ bool useCache = usesCache();
+ ObjectCacheKey key(ObjectCacheKey::OBJECT_DDL, db, dbName, lowerName, typeStr);
+ if (useCache && cache.contains(key))
+ return cache.object(key, true)->toString();
+
// Get the DDL
QVariant results;
if (type != ANY)
{
results = db->exec(QString(
- "SELECT sql FROM %1.sqlite_master WHERE lower(name) = '%2' AND type = '%3';").arg(dbName, escapeString(lowerName), objectTypeToString(type)),
+ "SELECT sql FROM %1.sqlite_master WHERE lower(name) = '%2' AND type = '%3';").arg(dbName, escapeString(lowerName), typeStr),
dbFlags
)->getSingleCell();
}
@@ -317,6 +326,9 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam
if (!resStr.trimmed().endsWith(";"))
resStr += ";";
+ if (useCache)
+ cache.insert(key, new QVariant(resStr));
+
// Return the DDL
return resStr;
}
@@ -417,6 +429,11 @@ QStringList SchemaResolver::getObjects(const QString &type)
QStringList SchemaResolver::getObjects(const QString &database, const QString &type)
{
+ bool useCache = usesCache();
+ ObjectCacheKey key(ObjectCacheKey::OBJECT_NAMES, db, database, type);
+ if (useCache && cache.contains(key))
+ return cache.object(key, true)->toStringList();
+
QStringList resList;
QString dbName = getPrefixDb(database, db->getDialect());
@@ -430,6 +447,9 @@ QStringList SchemaResolver::getObjects(const QString &database, const QString &t
resList << value;
}
+ if (useCache)
+ cache.insert(key, new QVariant(resList));
+
return resList;
}
@@ -440,6 +460,11 @@ QStringList SchemaResolver::getAllObjects()
QStringList SchemaResolver::getAllObjects(const QString& database)
{
+ bool useCache = usesCache();
+ ObjectCacheKey key(ObjectCacheKey::OBJECT_NAMES, db, database);
+ if (useCache && cache.contains(key))
+ return cache.object(key, true)->toStringList();
+
QStringList resList;
QString dbName = getPrefixDb(database, db->getDialect());
@@ -455,6 +480,9 @@ QStringList SchemaResolver::getAllObjects(const QString& database)
resList << value;
}
+ if (useCache)
+ cache.insert(key, new QVariant(resList));
+
return resList;
}
@@ -605,25 +633,42 @@ StrHash<SchemaResolver::ObjectDetails> SchemaResolver::getAllObjectDetails(const
ObjectDetails detail;
QString type;
- SqlQueryPtr results = db->exec(QString("SELECT name, type, sql FROM %1.sqlite_master").arg(getPrefixDb(database, db->getDialect())), dbFlags);
- if (results->isError())
+ QList<QVariant> rows;
+ bool useCache = usesCache();
+ ObjectCacheKey key(ObjectCacheKey::OBJECT_DETAILS, db, database);
+ if (useCache && cache.contains(key))
+ {
+ rows = cache.object(key, true)->toList();
+ }
+ else
{
- qCritical() << "Error while getting all object details in SchemaResolver:" << results->getErrorCode();
- return details;
+ SqlQueryPtr results = db->exec(QString("SELECT name, type, sql FROM %1.sqlite_master").arg(getPrefixDb(database, db->getDialect())), dbFlags);
+ if (results->isError())
+ {
+ qCritical() << "Error while getting all object details in SchemaResolver:" << results->getErrorCode();
+ return details;
+ }
+
+ for (const SqlResultsRowPtr& row : results->getAll())
+ rows << row->valueMap();
+
+ if (useCache)
+ cache.insert(key, new QVariant(rows));
}
- SqlResultsRowPtr row;
- while (results->hasNext())
+ QHash<QString, QVariant> row;
+ for (const QVariant& rowVariant : rows)
{
- row = results->next();
- type = row->value("type").toString();
+ row = rowVariant.toHash();
+ type = row["type"].toString();
detail.type = stringToObjectType(type);
if (detail.type == ANY)
qCritical() << "Unhlandled db object type:" << type;
- detail.ddl = row->value("sql").toString();
- details[row->value("name").toString()] = detail;
+ detail.ddl = row["sql"].toString();
+ details[row["name"].toString()] = detail;
}
+
return details;
}
@@ -747,6 +792,16 @@ SchemaResolver::ObjectType SchemaResolver::stringToObjectType(const QString& typ
return SchemaResolver::ANY;
}
+void SchemaResolver::staticInit()
+{
+ cache.setExpireTime(3000);
+}
+
+bool SchemaResolver::usesCache()
+{
+ return db->getConnectionOptions().contains(USE_SCHEMA_CACHING) && db->getConnectionOptions()[USE_SCHEMA_CACHING].toBool();
+}
+
QList<SqliteCreateViewPtr> SchemaResolver::getParsedViewsForTable(const QString& database, const QString& table)
{
QList<SqliteCreateViewPtr> createViewList;
@@ -909,3 +964,18 @@ void SchemaResolver::setNoDbLocking(bool value)
dbFlags ^= Db::Flag::NO_LOCK;
}
+
+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)
+{
+}
+
+int qHash(const SchemaResolver::ObjectCacheKey& key)
+{
+ return qHash(key.type) ^ qHash(key.db) ^ qHash(key.value1) ^ qHash(key.value2) ^ qHash(key.value3);
+}
+
+int operator==(const SchemaResolver::ObjectCacheKey& k1, const SchemaResolver::ObjectCacheKey& k2)
+{
+ return (k1.type == k2.type && k1.db == k2.db && k1.value1 == k2.value1 && k1.value2 == k2.value2 && k1.value3 == k2.value3);
+}