aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.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/db/abstractdb.cpp
parent1fdc150116cad39aae5c5da407c3312b47a59e3a (diff)
New upstream version 3.4.4+dfsg.upstream/3.4.4+dfsg
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp81
1 files changed, 56 insertions, 25 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp
index 9bfb46f..b137c1f 100644
--- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp
@@ -1,15 +1,13 @@
#include "abstractdb.h"
-#include "services/dbmanager.h"
+#include "services/collationmanager.h"
#include "common/utils.h"
#include "asyncqueryrunner.h"
#include "sqlresultsrow.h"
#include "common/utils_sql.h"
-#include "services/config.h"
#include "sqlerrorresults.h"
#include "sqlerrorcodes.h"
#include "services/notifymanager.h"
#include "services/sqliteextensionmanager.h"
-#include "log.h"
#include "parser/lexer.h"
#include "common/compatibility.h"
#include <QDebug>
@@ -25,10 +23,12 @@ quint32 AbstractDb::asyncId = 1;
AbstractDb::AbstractDb(const QString& name, const QString& path, const QHash<QString, QVariant>& connOptions) :
name(name), path(path), connOptions(connOptions)
{
+ connect(SQLITESTUDIO, SIGNAL(aboutToQuit()), this, SLOT(appIsAboutToQuit()));
}
AbstractDb::~AbstractDb()
{
+ disconnect(SQLITESTUDIO, SIGNAL(aboutToQuit()), this, SLOT(appIsAboutToQuit()));
}
bool AbstractDb::open()
@@ -47,7 +47,11 @@ bool AbstractDb::close()
if (deny)
return false;
- bool res = !isOpen() || closeQuiet();
+ bool open = isOpen();
+ if (open)
+ flushWal();
+
+ bool res = !open || closeQuiet();
if (res)
emit disconnected();
@@ -71,7 +75,7 @@ bool AbstractDb::closeQuiet()
registeredFunctions.clear();
registeredCollations.clear();
if (FUNCTIONS) // FUNCTIONS is already null when closing db while closing entire app
- disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions()));
+ disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerUserFunctions()));
return res;
}
@@ -89,40 +93,49 @@ bool AbstractDb::openForProbing()
return res;
}
-void AbstractDb::registerAllFunctions()
+void AbstractDb::registerUserFunctions()
{
- for (const RegisteredFunction& regFn : registeredFunctions)
+ QMutableSetIterator<RegisteredFunction> it(registeredFunctions);
+ while (it.hasNext())
{
+ const RegisteredFunction& regFn = it.next();
+ if (regFn.builtIn)
+ continue;
+
if (!deregisterFunction(regFn.name, regFn.argCount))
qWarning() << "Failed to deregister custom SQL function:" << regFn.name;
- }
- registeredFunctions.clear();
+ it.remove();
+ }
RegisteredFunction regFn;
- for (FunctionManager::ScriptFunction* fnPtr : FUNCTIONS->getScriptFunctionsForDatabase(getName()))
+ for (FunctionManager::ScriptFunction*& fnPtr : FUNCTIONS->getScriptFunctionsForDatabase(getName()))
{
regFn.argCount = fnPtr->undefinedArgs ? -1 : fnPtr->arguments.count();
regFn.name = fnPtr->name;
regFn.type = fnPtr->type;
+ regFn.deterministic = fnPtr->deterministic;
registerFunction(regFn);
}
+}
- for (FunctionManager::NativeFunction* fnPtr : FUNCTIONS->getAllNativeFunctions())
+void AbstractDb::registerBuiltInFunctions()
+{
+ RegisteredFunction regFn;
+ for (FunctionManager::NativeFunction*& fnPtr : FUNCTIONS->getAllNativeFunctions())
{
regFn.argCount = fnPtr->undefinedArgs ? -1 : fnPtr->arguments.count();
regFn.name = fnPtr->name;
regFn.type = fnPtr->type;
+ regFn.builtIn = true;
+ regFn.deterministic = fnPtr->deterministic;
registerFunction(regFn);
}
-
- disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions()));
- connect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions()));
}
-void AbstractDb::registerAllCollations()
+void AbstractDb::registerUserCollations()
{
- for (const QString& name : registeredCollations)
+ for (QString& name : registeredCollations)
{
if (!deregisterCollation(name))
qWarning() << "Failed to deregister custom collation:" << name;
@@ -130,16 +143,16 @@ void AbstractDb::registerAllCollations()
registeredCollations.clear();
- for (const CollationManager::CollationPtr& collPtr : COLLATIONS->getCollationsForDatabase(getName()))
+ for (CollationManager::CollationPtr& collPtr : COLLATIONS->getCollationsForDatabase(getName()))
registerCollation(collPtr->name);
- disconnect(COLLATIONS, SIGNAL(collationListChanged()), this, SLOT(registerAllCollations()));
- connect(COLLATIONS, SIGNAL(collationListChanged()), this, SLOT(registerAllCollations()));
+ disconnect(COLLATIONS, SIGNAL(collationListChanged()), this, SLOT(registerUserCollations()));
+ connect(COLLATIONS, SIGNAL(collationListChanged()), this, SLOT(registerUserCollations()));
}
void AbstractDb::loadExtensions()
{
- for (const SqliteExtensionManager::ExtensionPtr& extPtr : SQLITE_EXTENSIONS->getExtensionForDatabase(getName()))
+ for (SqliteExtensionManager::ExtensionPtr& extPtr : SQLITE_EXTENSIONS->getExtensionForDatabase(getName()))
loadedExtensionCount += loadExtension(extPtr->filePath, extPtr->initFunc) ? 1 : 0;
connect(SQLITE_EXTENSIONS, SIGNAL(extensionListChanged()), this, SLOT(reloadExtensions()));
@@ -377,14 +390,20 @@ bool AbstractDb::openAndSetup()
// Implementation specific initialization
initAfterOpen();
+ // Built-in SQL functions
+ registerBuiltInFunctions();
+
// Load extension
loadExtensions();
// Custom SQL functions
- registerAllFunctions();
+ registerUserFunctions();
// Custom collations
- registerAllCollations();
+ registerUserCollations();
+
+ disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerUserFunctions()));
+ connect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerUserFunctions()));
return result;
}
@@ -616,6 +635,12 @@ void AbstractDb::asyncQueryFinished(AsyncQueryRunner *runner)
emit idle();
}
+void AbstractDb::appIsAboutToQuit()
+{
+ if (isOpen())
+ flushWal();
+}
+
QString AbstractDb::attach(Db* otherDb, bool silent)
{
QWriteLocker locker(&dbOperLock);
@@ -716,7 +741,7 @@ QString AbstractDb::getUniqueNewObjectName(const QString &attachedDbName)
QSet<QString> existingNames;
SqlQueryPtr results = exec(QString("SELECT name FROM %1.sqlite_master").arg(dbName));
- for (SqlResultsRowPtr row : results->getAll())
+ for (SqlResultsRowPtr& row : results->getAll())
existingNames << row->value(0).toString();
return randStrNotIn(16, existingNames, false);
@@ -875,10 +900,10 @@ void AbstractDb::registerFunction(const AbstractDb::RegisteredFunction& function
switch (function.type)
{
case FunctionManager::ScriptFunction::SCALAR:
- successful = registerScalarFunction(function.name, function.argCount);
+ successful = registerScalarFunction(function.name, function.argCount, function.deterministic);
break;
case FunctionManager::ScriptFunction::AGGREGATE:
- successful = registerAggregateFunction(function.name, function.argCount);
+ successful = registerAggregateFunction(function.name, function.argCount, function.deterministic);
break;
}
@@ -888,6 +913,12 @@ void AbstractDb::registerFunction(const AbstractDb::RegisteredFunction& function
qCritical() << "Could not register SQL function:" << function.name << function.argCount << function.type;
}
+void AbstractDb::flushWal()
+{
+ if (!flushWalInternal())
+ notifyWarn(tr("Failed to make full WAL checkpoint on database '%1'. Error returned from SQLite engine: %2").arg(name, getErrorTextInternal()));
+}
+
int qHash(const AbstractDb::RegisteredFunction& fn)
{
return qHash(fn.name) ^ fn.argCount ^ fn.type;