From feda8a7db8d1d7c5439aa8f8feef7cc0dd2b59a0 Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Fri, 27 Jul 2018 23:51:12 -0400 Subject: New upstream version 3.2.1+dfsg1 --- SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h | 69 ++++++++++++++++++------- 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h') diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h index 7419f8c..51465f9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include /** * @brief Complete implementation of SQLite 2 driver for SQLiteStudio. @@ -42,9 +44,11 @@ class AbstractDb2 : public AbstractDb * All values from this constructor are just passed to AbstractDb constructor. */ AbstractDb2(const QString& name, const QString& path, const QHash& connOptions); - ~AbstractDb2(); + bool loadExtension(const QString& filePath, const QString& initFunc = QString()); + bool isComplete(const QString& sql) const; + protected: bool isOpenInternal(); void interruptExecution(); @@ -131,6 +135,7 @@ class AbstractDb2 : public AbstractDb int dbErrorCode = SQLITE_OK; QList userDataList; QList queries; + QMutex* dbOperMutex = nullptr; }; //------------------------------------------------------------------------------------ @@ -141,15 +146,31 @@ template AbstractDb2::AbstractDb2(const QString& name, const QString& path, const QHash& connOptions) : AbstractDb(name, path, connOptions) { + dbOperMutex = new QMutex(QMutex::Recursive); } template AbstractDb2::~AbstractDb2() { + safe_delete(dbOperMutex); if (isOpenInternal()) closeInternal(); } +template +bool AbstractDb2::loadExtension(const QString& filePath, const QString& initFunc) +{ + UNUSED(filePath); + UNUSED(initFunc); + return false; +} + +template +bool AbstractDb2::isComplete(const QString& sql) const +{ + return sqlite_complete(sql.toUtf8().constData()); +} + template bool AbstractDb2::isOpenInternal() { @@ -168,6 +189,7 @@ void AbstractDb2::interruptExecution() if (!isOpenInternal()) return; + QMutexLocker mutexLocker(dbOperMutex); sqlite_interrupt(dbHandle); } @@ -189,6 +211,7 @@ bool AbstractDb2::openInternal() resetError(); sqlite* handle = nullptr; char* errMsg = nullptr; + QMutexLocker mutexLocker(dbOperMutex); handle = sqlite_open(path.toUtf8().constData(), 0, &errMsg); if (!handle) { @@ -214,6 +237,7 @@ bool AbstractDb2::closeInternal() cleanUp(); + QMutexLocker mutexLocker(dbOperMutex); sqlite_close(dbHandle); dbHandle = nullptr; return true; @@ -243,6 +267,7 @@ bool AbstractDb2::deregisterFunction(const QString& name, int argCount) if (!dbHandle) return false; + QMutexLocker mutexLocker(dbOperMutex); sqlite_create_function(dbHandle, name.toLatin1().data(), argCount, nullptr, nullptr); sqlite_create_aggregate(dbHandle, name.toLatin1().data(), argCount, nullptr, nullptr, nullptr); @@ -273,6 +298,7 @@ bool AbstractDb2::registerScalarFunction(const QString& name, int argCount) userData->argCount = argCount; userDataList << userData; + QMutexLocker mutexLocker(dbOperMutex); int res = sqlite_create_function(dbHandle, name.toUtf8().constData(), argCount, &AbstractDb2::evaluateScalar, userData); @@ -291,6 +317,7 @@ bool AbstractDb2::registerAggregateFunction(const QString& name, int argCount userData->argCount = argCount; userDataList << userData; + QMutexLocker mutexLocker(dbOperMutex); int res = sqlite_create_aggregate(dbHandle, name.toUtf8().constData(), argCount, &AbstractDb2::evaluateAggregateStep, &AbstractDb2::evaluateAggregateFinal, @@ -527,6 +554,7 @@ int AbstractDb2::Query::prepareStmt(const QString& processedQuery) char* errMsg = nullptr; const char* tail; QByteArray queryBytes = processedQuery.toUtf8(); + QMutexLocker mutexLocker(db->dbOperMutex); int res = sqlite_compile(db->dbHandle, queryBytes.constData(), &tail, &stmt, &errMsg); if (res != SQLITE_OK) { @@ -556,6 +584,7 @@ int AbstractDb2::Query::resetStmt() nextRowValues.clear(); char* errMsg = nullptr; + QMutexLocker mutexLocker(db->dbOperMutex); int res = sqlite_reset(stmt, &errMsg); if (res != SQLITE_OK) { @@ -576,23 +605,27 @@ bool AbstractDb2::Query::execInternal(const QList& args) if (!checkDbState()) return false; - ReadWriteLocker locker(&(db->dbOperLock), query, Dialect::Sqlite2, flags.testFlag(Db::Flag::NO_LOCK)); + QMutexLocker mutexLocker(db->dbOperMutex); logSql(db.data(), query, args, flags); - QueryWithParamCount queryWithParams = getQueryWithParamCount(query, Dialect::Sqlite2); - QString singleStr = replaceNamedParams(queryWithParams.first); - int res; if (stmt) res = resetStmt(); else - res = prepareStmt(singleStr); + res = prepareStmt(query); if (res != SQLITE_OK) return false; - for (int paramIdx = 1; paramIdx <= queryWithParams.second; paramIdx++) + int maxParamIdx = args.size(); + if (!flags.testFlag(Db::Flag::SKIP_PARAM_COUNTING)) + { + QueryWithParamCount queryWithParams = getQueryWithParamCount(query, Dialect::Sqlite2); + maxParamIdx = qMin(maxParamIdx, queryWithParams.second); + } + + for (int paramIdx = 1; paramIdx <= maxParamIdx; paramIdx++) { res = bindParam(paramIdx, args[paramIdx-1]); if (res != SQLITE_OK) @@ -612,7 +645,7 @@ bool AbstractDb2::Query::execInternal(const QHash& args) if (!checkDbState()) return false; - ReadWriteLocker locker(&(db->dbOperLock), query, Dialect::Sqlite2, flags.testFlag(Db::Flag::NO_LOCK)); + QMutexLocker mutexLocker(db->dbOperMutex); logSql(db.data(), query, args, flags); @@ -629,7 +662,7 @@ bool AbstractDb2::Query::execInternal(const QHash& args) return false; int paramIdx = 1; - foreach (const QString& paramName, queryWithParams.second) + for (const QString& paramName : queryWithParams.second) { if (!args.contains(paramName)) { @@ -665,9 +698,7 @@ template int AbstractDb2::Query::bindParam(int paramIdx, const QVariant& value) { if (value.isNull()) - { return sqlite_bind(stmt, paramIdx, nullptr, 0, 0); - } switch (value.type()) { @@ -686,6 +717,7 @@ int AbstractDb2::Query::bindParam(int paramIdx, const QVariant& value) } } + qWarning() << "sqlite_bind() MISUSE"; return SQLITE_MISUSE; // not going to happen } template @@ -747,19 +779,14 @@ bool AbstractDb2::Query::hasNextInternal() template int AbstractDb2::Query::fetchFirst() { + QMutexLocker mutexLocker(db->dbOperMutex); rowAvailable = true; int res = fetchNext(); + affected = 0; if (res == SQLITE_OK) { - if (colCount == 0) - { - affected = 0; - } - else - { - affected = sqlite_changes(db->dbHandle); - insertRowId["ROWID"] = sqlite_last_insert_rowid(db->dbHandle); - } + affected = sqlite_changes(db->dbHandle); + insertRowId["ROWID"] = sqlite_last_insert_rowid(db->dbHandle); } return res; } @@ -783,6 +810,7 @@ QString AbstractDb2::Query::finalize() if (stmt) { char* errMsg = nullptr; + QMutexLocker mutexLocker(db->dbOperMutex); sqlite_finalize(stmt, &errMsg); stmt = nullptr; if (errMsg) @@ -814,6 +842,7 @@ int AbstractDb2::Query::fetchNext() int res; int secondsSpent = 0; + QMutexLocker mutexLocker(db->dbOperMutex); while ((res = sqlite_step(stmt, &columnsCount, &values, &columns)) == SQLITE_BUSY && secondsSpent < db->getTimeout()) { QThread::sleep(1); -- cgit v1.2.3