forked from qt-creator/qt-creator
Sqlite: Cleanup Sqlite
We don't need the threading anymore, so we removed it. The indexer will be run in its thread anyway, so an extra thread makes the code only more complicated. And we added namespaces. Change-Id: Ibcba306324763285cf653c28bb08122345e5f8da Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -25,49 +25,20 @@
|
||||
|
||||
#include "columndefinition.h"
|
||||
|
||||
namespace Internal {
|
||||
namespace Sqlite {
|
||||
|
||||
void ColumnDefinition::setName(const Utf8String &name)
|
||||
{
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
const Utf8String &ColumnDefinition::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void ColumnDefinition::setType(ColumnType type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
ColumnType ColumnDefinition::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
Utf8String ColumnDefinition::typeString() const
|
||||
{
|
||||
switch (type_) {
|
||||
case ColumnType::None: return Utf8String();
|
||||
case ColumnType::Numeric: return Utf8StringLiteral("NUMERIC");
|
||||
case ColumnType::Integer: return Utf8StringLiteral("INTEGER");
|
||||
case ColumnType::Real: return Utf8StringLiteral("REAL");
|
||||
case ColumnType::Text: return Utf8StringLiteral("TEXT");
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void ColumnDefinition::setIsPrimaryKey(bool isPrimaryKey)
|
||||
{
|
||||
isPrimaryKey_ = isPrimaryKey;
|
||||
}
|
||||
|
||||
bool ColumnDefinition::isPrimaryKey() const
|
||||
{
|
||||
return isPrimaryKey_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -28,25 +28,58 @@
|
||||
#include "sqliteglobal.h"
|
||||
#include "utf8string.h"
|
||||
|
||||
namespace Internal {
|
||||
namespace Sqlite {
|
||||
|
||||
class ColumnDefinition
|
||||
{
|
||||
public:
|
||||
void setName(const Utf8String &name);
|
||||
const Utf8String &name() const;
|
||||
void setName(const Utf8String &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void setType(ColumnType type);
|
||||
ColumnType type() const;
|
||||
Utf8String typeString() const;
|
||||
const Utf8String &name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void setIsPrimaryKey(bool isPrimaryKey);
|
||||
bool isPrimaryKey() const;
|
||||
void setType(ColumnType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
ColumnType type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
Utf8String typeString() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case ColumnType::None: return Utf8String();
|
||||
case ColumnType::Numeric: return Utf8StringLiteral("NUMERIC");
|
||||
case ColumnType::Integer: return Utf8StringLiteral("INTEGER");
|
||||
case ColumnType::Real: return Utf8StringLiteral("REAL");
|
||||
case ColumnType::Text: return Utf8StringLiteral("TEXT");
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void setIsPrimaryKey(bool isPrimaryKey)
|
||||
{
|
||||
m_isPrimaryKey = isPrimaryKey;
|
||||
}
|
||||
|
||||
bool isPrimaryKey() const
|
||||
{
|
||||
return m_isPrimaryKey;
|
||||
}
|
||||
|
||||
private:
|
||||
Utf8String name_;
|
||||
ColumnType type_;
|
||||
bool isPrimaryKey_ = false;
|
||||
Utf8String m_name;
|
||||
ColumnType m_type;
|
||||
bool m_isPrimaryKey = false;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Sqlite
|
||||
|
@@ -1,36 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "createtablecommand.h"
|
||||
|
||||
namespace Internal {
|
||||
|
||||
void CreateTableCommand::registerType()
|
||||
{
|
||||
qRegisterMetaType<CreateTableCommand>("CreateTableCommand");
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -1,49 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "columndefinition.h"
|
||||
#include "utf8string.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVector>
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class CreateTableCommand
|
||||
{
|
||||
public:
|
||||
QVector<ColumnDefinition> definitions;
|
||||
Utf8String tableName;
|
||||
bool useWithoutRowId;
|
||||
|
||||
static void registerType();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Q_DECLARE_METATYPE(Internal::CreateTableCommand)
|
@@ -27,79 +27,79 @@
|
||||
|
||||
#include "utf8stringvector.h"
|
||||
|
||||
namespace Internal {
|
||||
namespace Sqlite {
|
||||
|
||||
CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
|
||||
: sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")),
|
||||
useWithoutRowId(false)
|
||||
: m_sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")),
|
||||
m_useWithoutRowId(false)
|
||||
{
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setTable(const Utf8String &tableName)
|
||||
{
|
||||
sqlStatementBuilder.clear();
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
this->tableName = tableName;
|
||||
this->m_tableName = tableName;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::addColumnDefinition(const Utf8String &columnName,
|
||||
ColumnType columnType,
|
||||
bool isPrimaryKey)
|
||||
{
|
||||
sqlStatementBuilder.clear();
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
ColumnDefinition columnDefinition;
|
||||
columnDefinition.setName(columnName);
|
||||
columnDefinition.setType(columnType);
|
||||
columnDefinition.setIsPrimaryKey(isPrimaryKey);
|
||||
|
||||
columnDefinitions.append(columnDefinition);
|
||||
m_columnDefinitions.append(columnDefinition);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setColumnDefinitions(const QVector<ColumnDefinition> &columnDefinitions)
|
||||
{
|
||||
sqlStatementBuilder.clear();
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
this->columnDefinitions = columnDefinitions;
|
||||
this->m_columnDefinitions = columnDefinitions;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
|
||||
{
|
||||
this->useWithoutRowId = useWithoutRowId;
|
||||
this->m_useWithoutRowId = useWithoutRowId;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::clear()
|
||||
{
|
||||
sqlStatementBuilder.clear();
|
||||
columnDefinitions.clear();
|
||||
tableName.clear();
|
||||
useWithoutRowId = false;
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columnDefinitions.clear();
|
||||
m_tableName.clear();
|
||||
m_useWithoutRowId = false;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::clearColumns()
|
||||
{
|
||||
sqlStatementBuilder.clear();
|
||||
columnDefinitions.clear();
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columnDefinitions.clear();
|
||||
}
|
||||
|
||||
Utf8String CreateTableSqlStatementBuilder::sqlStatement() const
|
||||
{
|
||||
if (!sqlStatementBuilder.isBuild())
|
||||
if (!m_sqlStatementBuilder.isBuild())
|
||||
bindAll();
|
||||
|
||||
return sqlStatementBuilder.sqlStatement();
|
||||
return m_sqlStatementBuilder.sqlStatement();
|
||||
}
|
||||
|
||||
bool CreateTableSqlStatementBuilder::isValid() const
|
||||
{
|
||||
return tableName.hasContent() && !columnDefinitions.isEmpty();
|
||||
return m_tableName.hasContent() && !m_columnDefinitions.isEmpty();
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
|
||||
{
|
||||
Utf8StringVector columnDefinitionStrings;
|
||||
|
||||
foreach (const ColumnDefinition &columnDefinition, columnDefinitions) {
|
||||
foreach (const ColumnDefinition &columnDefinition, m_columnDefinitions) {
|
||||
Utf8String columnDefinitionString = columnDefinition.name() + Utf8StringLiteral(" ") + columnDefinition.typeString();
|
||||
|
||||
if (columnDefinition.isPrimaryKey())
|
||||
@@ -108,19 +108,19 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
|
||||
columnDefinitionStrings.append(columnDefinitionString);
|
||||
}
|
||||
|
||||
sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings);
|
||||
m_sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindAll() const
|
||||
{
|
||||
sqlStatementBuilder.bind(Utf8StringLiteral("$table"), tableName);
|
||||
m_sqlStatementBuilder.bind(Utf8StringLiteral("$table"), m_tableName);
|
||||
|
||||
bindColumnDefinitions();
|
||||
|
||||
if (useWithoutRowId)
|
||||
sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID"));
|
||||
if (m_useWithoutRowId)
|
||||
m_sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID"));
|
||||
else
|
||||
sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId"));
|
||||
m_sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId"));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Sqlite
|
||||
|
@@ -30,17 +30,17 @@
|
||||
|
||||
#include <QVector>
|
||||
|
||||
namespace Internal {
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT CreateTableSqlStatementBuilder
|
||||
{
|
||||
public:
|
||||
CreateTableSqlStatementBuilder();
|
||||
|
||||
void setTable(const Utf8String &tableName);
|
||||
void setTable(const Utf8String &m_tableName);
|
||||
void addColumnDefinition(const Utf8String &columnName, ColumnType columnType, bool isPrimaryKey = false);
|
||||
void setColumnDefinitions(const QVector<ColumnDefinition> & columnDefinitions);
|
||||
void setUseWithoutRowId(bool useWithoutRowId);
|
||||
void setColumnDefinitions(const QVector<ColumnDefinition> & m_columnDefinitions);
|
||||
void setUseWithoutRowId(bool m_useWithoutRowId);
|
||||
|
||||
void clear();
|
||||
void clearColumns();
|
||||
@@ -54,10 +54,10 @@ protected:
|
||||
void bindAll() const;
|
||||
|
||||
private:
|
||||
mutable SqlStatementBuilder sqlStatementBuilder;
|
||||
Utf8String tableName;
|
||||
QVector<ColumnDefinition> columnDefinitions;
|
||||
bool useWithoutRowId;
|
||||
mutable SqlStatementBuilder m_sqlStatementBuilder;
|
||||
Utf8String m_tableName;
|
||||
QVector<ColumnDefinition> m_columnDefinitions;
|
||||
bool m_useWithoutRowId;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Sqlite
|
||||
|
@@ -12,18 +12,14 @@ include(../3rdparty/sqlite/sqlite.pri)
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/columndefinition.cpp \
|
||||
$$PWD/createtablecommand.cpp \
|
||||
$$PWD/createtablesqlstatementbuilder.cpp \
|
||||
$$PWD/sqlitedatabasebackend.cpp \
|
||||
$$PWD/sqlitedatabaseconnection.cpp \
|
||||
$$PWD/sqlitedatabaseconnectionproxy.cpp \
|
||||
$$PWD/sqliteexception.cpp \
|
||||
$$PWD/sqliteglobal.cpp \
|
||||
$$PWD/sqlitereadstatement.cpp \
|
||||
$$PWD/sqlitereadwritestatement.cpp \
|
||||
$$PWD/sqlitestatement.cpp \
|
||||
$$PWD/sqlitetransaction.cpp \
|
||||
$$PWD/sqliteworkerthread.cpp \
|
||||
$$PWD/sqlitewritestatement.cpp \
|
||||
$$PWD/sqlstatementbuilder.cpp \
|
||||
$$PWD/sqlstatementbuilderexception.cpp \
|
||||
@@ -31,22 +27,17 @@ SOURCES += \
|
||||
$$PWD/utf8stringvector.cpp \
|
||||
$$PWD/sqlitedatabase.cpp \
|
||||
$$PWD/sqlitetable.cpp \
|
||||
$$PWD/sqlitecolumn.cpp \
|
||||
$$PWD/tablewriteworker.cpp \
|
||||
$$PWD/tablewriteworkerproxy.cpp
|
||||
$$PWD/sqlitecolumn.cpp
|
||||
HEADERS += \
|
||||
$$PWD/columndefinition.h \
|
||||
$$PWD/createtablesqlstatementbuilder.h \
|
||||
$$PWD/sqlitedatabasebackend.h \
|
||||
$$PWD/sqlitedatabaseconnection.h \
|
||||
$$PWD/sqlitedatabaseconnectionproxy.h \
|
||||
$$PWD/sqliteexception.h \
|
||||
$$PWD/sqliteglobal.h \
|
||||
$$PWD/sqlitereadstatement.h \
|
||||
$$PWD/sqlitereadwritestatement.h \
|
||||
$$PWD/sqlitestatement.h \
|
||||
$$PWD/sqlitetransaction.h \
|
||||
$$PWD/sqliteworkerthread.h \
|
||||
$$PWD/sqlitewritestatement.h \
|
||||
$$PWD/sqlstatementbuilder.h \
|
||||
$$PWD/sqlstatementbuilderexception.h \
|
||||
@@ -54,10 +45,7 @@ HEADERS += \
|
||||
$$PWD/utf8stringvector.h \
|
||||
$$PWD/sqlitedatabase.h \
|
||||
$$PWD/sqlitetable.h \
|
||||
$$PWD/sqlitecolumn.h \
|
||||
$$PWD/tablewriteworker.h \
|
||||
$$PWD/tablewriteworkerproxy.h \
|
||||
$$PWD/createtablecommand.h
|
||||
$$PWD/sqlitecolumn.h
|
||||
|
||||
DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
|
||||
|
||||
|
@@ -25,57 +25,7 @@
|
||||
|
||||
#include "sqlitecolumn.h"
|
||||
|
||||
SqliteColumn::SqliteColumn()
|
||||
: type_(ColumnType::Numeric),
|
||||
isPrimaryKey_(false)
|
||||
{
|
||||
namespace Sqlite {
|
||||
|
||||
}
|
||||
|
||||
void SqliteColumn::clear()
|
||||
{
|
||||
name_.clear();
|
||||
type_ = ColumnType::Numeric;
|
||||
isPrimaryKey_ = false;
|
||||
}
|
||||
|
||||
void SqliteColumn::setName(const Utf8String &newName)
|
||||
{
|
||||
name_ = newName;
|
||||
}
|
||||
|
||||
const Utf8String &SqliteColumn::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void SqliteColumn::setType(ColumnType newType)
|
||||
{
|
||||
type_ = newType;
|
||||
}
|
||||
|
||||
ColumnType SqliteColumn::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
void SqliteColumn::setIsPrimaryKey(bool isPrimaryKey)
|
||||
{
|
||||
isPrimaryKey_ = isPrimaryKey;
|
||||
}
|
||||
|
||||
bool SqliteColumn::isPrimaryKey() const
|
||||
{
|
||||
return isPrimaryKey_;
|
||||
}
|
||||
|
||||
Internal::ColumnDefinition SqliteColumn::columnDefintion() const
|
||||
{
|
||||
Internal::ColumnDefinition columnDefinition;
|
||||
|
||||
columnDefinition.setName(name_);
|
||||
columnDefinition.setType(type_);
|
||||
columnDefinition.setIsPrimaryKey(isPrimaryKey_);
|
||||
|
||||
return columnDefinition;
|
||||
}
|
||||
} // namespace Sqlite
|
||||
|
@@ -30,27 +30,70 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class SQLITE_EXPORT SqliteColumn : public QObject
|
||||
namespace Sqlite {
|
||||
|
||||
class SqliteColumn
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SqliteColumn();
|
||||
SqliteColumn()
|
||||
: m_type(ColumnType::Numeric),
|
||||
m_isPrimaryKey(false)
|
||||
{
|
||||
|
||||
void clear();
|
||||
}
|
||||
|
||||
void setName(const Utf8String &newName);
|
||||
const Utf8String &name() const;
|
||||
void clear()
|
||||
{
|
||||
m_name.clear();
|
||||
m_type = ColumnType::Numeric;
|
||||
m_isPrimaryKey = false;
|
||||
}
|
||||
|
||||
void setType(ColumnType newType);
|
||||
ColumnType type() const;
|
||||
void setName(const Utf8String &newName)
|
||||
{
|
||||
m_name = newName;
|
||||
}
|
||||
|
||||
void setIsPrimaryKey(bool isPrimaryKey);
|
||||
bool isPrimaryKey() const;
|
||||
const Utf8String &name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
Internal::ColumnDefinition columnDefintion() const;
|
||||
void setType(ColumnType newType)
|
||||
{
|
||||
m_type = newType;
|
||||
}
|
||||
|
||||
ColumnType type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void setIsPrimaryKey(bool isPrimaryKey)
|
||||
{
|
||||
m_isPrimaryKey = isPrimaryKey;
|
||||
}
|
||||
|
||||
bool isPrimaryKey() const
|
||||
{
|
||||
return m_isPrimaryKey;
|
||||
}
|
||||
|
||||
ColumnDefinition columnDefintion() const
|
||||
{
|
||||
ColumnDefinition columnDefinition;
|
||||
|
||||
columnDefinition.setName(m_name);
|
||||
columnDefinition.setType(m_type);
|
||||
columnDefinition.setIsPrimaryKey(m_isPrimaryKey);
|
||||
|
||||
return columnDefinition;
|
||||
}
|
||||
|
||||
private:
|
||||
Utf8String name_;
|
||||
ColumnType type_;
|
||||
bool isPrimaryKey_;
|
||||
Utf8String m_name;
|
||||
ColumnType m_type;
|
||||
bool m_isPrimaryKey;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,103 +27,66 @@
|
||||
|
||||
#include "sqlitetable.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteDatabase::SqliteDatabase()
|
||||
: readDatabaseConnection(QStringLiteral("ReadWorker")),
|
||||
writeDatabaseConnection(QStringLiteral("WriterWorker")),
|
||||
journalMode_(JournalMode::Wal)
|
||||
: m_journalMode(JournalMode::Wal)
|
||||
{
|
||||
connect(&readDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsOpened, this, &SqliteDatabase::handleReadDatabaseConnectionIsOpened);
|
||||
connect(&writeDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsOpened, this, &SqliteDatabase::handleWriteDatabaseConnectionIsOpened);
|
||||
connect(&readDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsClosed, this, &SqliteDatabase::handleReadDatabaseConnectionIsClosed);
|
||||
connect(&writeDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsClosed, this, &SqliteDatabase::handleWriteDatabaseConnectionIsClosed);
|
||||
}
|
||||
|
||||
SqliteDatabase::~SqliteDatabase()
|
||||
{
|
||||
qDeleteAll(sqliteTables);
|
||||
qDeleteAll(m_sqliteTables);
|
||||
}
|
||||
|
||||
void SqliteDatabase::open()
|
||||
{
|
||||
writeDatabaseConnection.setDatabaseFilePath(databaseFilePath());
|
||||
writeDatabaseConnection.setJournalMode(journalMode());
|
||||
m_sqliteDatabaseBackEnd.open(m_databaseFilePath);
|
||||
m_sqliteDatabaseBackEnd.setJournalMode(journalMode());
|
||||
initializeTables();
|
||||
m_isOpen = true;
|
||||
}
|
||||
|
||||
void SqliteDatabase::close()
|
||||
{
|
||||
writeDatabaseConnection.close();
|
||||
m_isOpen = false;
|
||||
m_sqliteDatabaseBackEnd.close();
|
||||
}
|
||||
|
||||
bool SqliteDatabase::isOpen() const
|
||||
{
|
||||
return readDatabaseConnection.isOpen() && writeDatabaseConnection.isOpen();
|
||||
return m_isOpen;
|
||||
}
|
||||
|
||||
void SqliteDatabase::addTable(SqliteTable *newSqliteTable)
|
||||
{
|
||||
newSqliteTable->setSqliteDatabase(this);
|
||||
sqliteTables.append(newSqliteTable);
|
||||
m_sqliteTables.append(newSqliteTable);
|
||||
}
|
||||
|
||||
const QVector<SqliteTable *> &SqliteDatabase::tables() const
|
||||
{
|
||||
return sqliteTables;
|
||||
return m_sqliteTables;
|
||||
}
|
||||
|
||||
void SqliteDatabase::setDatabaseFilePath(const QString &databaseFilePath)
|
||||
{
|
||||
databaseFilePath_ = databaseFilePath;
|
||||
m_databaseFilePath = databaseFilePath;
|
||||
}
|
||||
|
||||
const QString &SqliteDatabase::databaseFilePath() const
|
||||
{
|
||||
return databaseFilePath_;
|
||||
return m_databaseFilePath;
|
||||
}
|
||||
|
||||
void SqliteDatabase::setJournalMode(JournalMode journalMode)
|
||||
{
|
||||
journalMode_ = journalMode;
|
||||
m_journalMode = journalMode;
|
||||
}
|
||||
|
||||
JournalMode SqliteDatabase::journalMode() const
|
||||
{
|
||||
return journalMode_;
|
||||
}
|
||||
|
||||
QThread *SqliteDatabase::writeWorkerThread() const
|
||||
{
|
||||
return writeDatabaseConnection.connectionThread();
|
||||
}
|
||||
|
||||
QThread *SqliteDatabase::readWorkerThread() const
|
||||
{
|
||||
return readDatabaseConnection.connectionThread();
|
||||
}
|
||||
|
||||
void SqliteDatabase::handleReadDatabaseConnectionIsOpened()
|
||||
{
|
||||
if (writeDatabaseConnection.isOpen() && readDatabaseConnection.isOpen()) {
|
||||
initializeTables();
|
||||
emit databaseIsOpened();
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteDatabase::handleWriteDatabaseConnectionIsOpened()
|
||||
{
|
||||
readDatabaseConnection.setDatabaseFilePath(databaseFilePath());
|
||||
}
|
||||
|
||||
void SqliteDatabase::handleReadDatabaseConnectionIsClosed()
|
||||
{
|
||||
if (!writeDatabaseConnection.isOpen() && !readDatabaseConnection.isOpen()) {
|
||||
shutdownTables();
|
||||
emit databaseIsClosed();
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteDatabase::handleWriteDatabaseConnectionIsClosed()
|
||||
{
|
||||
readDatabaseConnection.close();
|
||||
return m_journalMode;
|
||||
}
|
||||
|
||||
void SqliteDatabase::initializeTables()
|
||||
@@ -132,10 +95,4 @@ void SqliteDatabase::initializeTables()
|
||||
table->initialize();
|
||||
}
|
||||
|
||||
void SqliteDatabase::shutdownTables()
|
||||
{
|
||||
for (SqliteTable *table: tables())
|
||||
table->shutdown();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -25,18 +25,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sqlitedatabaseconnectionproxy.h"
|
||||
#include "sqlitedatabasebackend.h"
|
||||
#include "sqliteglobal.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SqliteTable;
|
||||
|
||||
class SQLITE_EXPORT SqliteDatabase : public QObject
|
||||
class SQLITE_EXPORT SqliteDatabase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SqliteDatabase();
|
||||
~SqliteDatabase();
|
||||
@@ -55,25 +55,16 @@ public:
|
||||
void setJournalMode(JournalMode journalMode);
|
||||
JournalMode journalMode() const;
|
||||
|
||||
QThread *writeWorkerThread() const;
|
||||
QThread *readWorkerThread() const;
|
||||
|
||||
signals:
|
||||
void databaseIsOpened();
|
||||
void databaseIsClosed();
|
||||
|
||||
private:
|
||||
void handleReadDatabaseConnectionIsOpened();
|
||||
void handleWriteDatabaseConnectionIsOpened();
|
||||
void handleReadDatabaseConnectionIsClosed();
|
||||
void handleWriteDatabaseConnectionIsClosed();
|
||||
void initializeTables();
|
||||
void shutdownTables();
|
||||
|
||||
private:
|
||||
SqliteDatabaseConnectionProxy readDatabaseConnection;
|
||||
SqliteDatabaseConnectionProxy writeDatabaseConnection;
|
||||
QVector<SqliteTable*> sqliteTables;
|
||||
QString databaseFilePath_;
|
||||
JournalMode journalMode_;
|
||||
SqliteDatabaseBackend m_sqliteDatabaseBackEnd;
|
||||
QVector<SqliteTable*> m_sqliteTables;
|
||||
QString m_databaseFilePath;
|
||||
JournalMode m_journalMode;
|
||||
bool m_isOpen = false;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -46,11 +46,13 @@
|
||||
|
||||
#define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray)
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
QTC_THREAD_LOCAL SqliteDatabaseBackend *sqliteDatabaseBackend = nullptr;
|
||||
|
||||
SqliteDatabaseBackend::SqliteDatabaseBackend()
|
||||
: databaseHandle(nullptr),
|
||||
cachedTextEncoding(Utf8)
|
||||
: m_databaseHandle(nullptr),
|
||||
m_cachedTextEncoding(Utf8)
|
||||
{
|
||||
sqliteDatabaseBackend = this;
|
||||
}
|
||||
@@ -108,7 +110,7 @@ void SqliteDatabaseBackend::open(const QString &databaseFilePath)
|
||||
|
||||
QByteArray databaseUtf8Path = databaseFilePath.toUtf8();
|
||||
int resultCode = sqlite3_open_v2(databaseUtf8Path.data(),
|
||||
&databaseHandle,
|
||||
&m_databaseHandle,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
NULL);
|
||||
|
||||
@@ -123,7 +125,7 @@ sqlite3 *SqliteDatabaseBackend::sqliteDatabaseHandle()
|
||||
{
|
||||
checkDatabaseBackendIsNotNull();
|
||||
checkDatabaseHandleIsNotNull();
|
||||
return threadLocalInstance()->databaseHandle;
|
||||
return threadLocalInstance()->m_databaseHandle;
|
||||
}
|
||||
|
||||
void SqliteDatabaseBackend::setPragmaValue(const Utf8String &pragmaKey, const Utf8String &newPragmaValue)
|
||||
@@ -157,7 +159,7 @@ void SqliteDatabaseBackend::setTextEncoding(TextEncoding textEncoding)
|
||||
|
||||
TextEncoding SqliteDatabaseBackend::textEncoding()
|
||||
{
|
||||
return cachedTextEncoding;
|
||||
return m_cachedTextEncoding;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,11 +183,11 @@ void SqliteDatabaseBackend::close()
|
||||
{
|
||||
checkForOpenDatabaseWhichCanBeClosed();
|
||||
|
||||
int resultCode = sqlite3_close(databaseHandle);
|
||||
int resultCode = sqlite3_close(m_databaseHandle);
|
||||
|
||||
checkDatabaseClosing(resultCode);
|
||||
|
||||
databaseHandle = nullptr;
|
||||
m_databaseHandle = nullptr;
|
||||
|
||||
}
|
||||
|
||||
@@ -197,14 +199,14 @@ SqliteDatabaseBackend *SqliteDatabaseBackend::threadLocalInstance()
|
||||
|
||||
bool SqliteDatabaseBackend::databaseIsOpen() const
|
||||
{
|
||||
return databaseHandle != nullptr;
|
||||
return m_databaseHandle != nullptr;
|
||||
}
|
||||
|
||||
void SqliteDatabaseBackend::closeWithoutException()
|
||||
{
|
||||
if (databaseHandle) {
|
||||
int resultCode = sqlite3_close_v2(databaseHandle);
|
||||
databaseHandle = nullptr;
|
||||
if (m_databaseHandle) {
|
||||
int resultCode = sqlite3_close_v2(m_databaseHandle);
|
||||
m_databaseHandle = nullptr;
|
||||
if (resultCode != SQLITE_OK)
|
||||
qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!";
|
||||
}
|
||||
@@ -235,12 +237,12 @@ int SqliteDatabaseBackend::busyHandlerCallback(void *, int counter)
|
||||
|
||||
void SqliteDatabaseBackend::cacheTextEncoding()
|
||||
{
|
||||
cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding")));
|
||||
m_cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding")));
|
||||
}
|
||||
|
||||
void SqliteDatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
|
||||
{
|
||||
if (databaseHandle == nullptr)
|
||||
if (m_databaseHandle == nullptr)
|
||||
throwException("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
|
||||
}
|
||||
|
||||
@@ -280,7 +282,7 @@ void SqliteDatabaseBackend::checkPragmaValue(const Utf8String &databaseValue, co
|
||||
|
||||
void SqliteDatabaseBackend::checkDatabaseHandleIsNotNull()
|
||||
{
|
||||
if (sqliteDatabaseBackend->databaseHandle == nullptr)
|
||||
if (sqliteDatabaseBackend->m_databaseHandle == nullptr)
|
||||
throwException("SqliteDatabaseBackend: database is not open!");
|
||||
}
|
||||
|
||||
@@ -383,8 +385,10 @@ TextEncoding SqliteDatabaseBackend::pragmaToTextEncoding(const Utf8String &pragm
|
||||
|
||||
void SqliteDatabaseBackend::throwException(const char *whatHasHappens)
|
||||
{
|
||||
if (sqliteDatabaseBackend && sqliteDatabaseBackend->databaseHandle)
|
||||
throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->databaseHandle));
|
||||
if (sqliteDatabaseBackend && sqliteDatabaseBackend->m_databaseHandle)
|
||||
throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->m_databaseHandle));
|
||||
else
|
||||
throw SqliteException(whatHasHappens);
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -33,6 +33,8 @@
|
||||
|
||||
struct sqlite3;
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteDatabaseBackend
|
||||
{
|
||||
public:
|
||||
@@ -102,7 +104,9 @@ protected:
|
||||
Q_NORETURN static void throwException(const char *whatHasHappens);
|
||||
|
||||
private:
|
||||
sqlite3 *databaseHandle;
|
||||
TextEncoding cachedTextEncoding;
|
||||
sqlite3 *m_databaseHandle;
|
||||
TextEncoding m_cachedTextEncoding;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -1,97 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sqlitedatabaseconnection.h"
|
||||
|
||||
#include "sqliteexception.h"
|
||||
#include "sqliteglobal.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
SqliteDatabaseConnection::SqliteDatabaseConnection(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SqliteDatabaseConnection::~SqliteDatabaseConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
sqlite3 *SqliteDatabaseConnection::currentSqliteDatabase()
|
||||
{
|
||||
return SqliteDatabaseBackend::sqliteDatabaseHandle();
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnection::setDatabaseFilePath(const QString &databaseFilePath)
|
||||
{
|
||||
|
||||
prioritizeThreadDown();
|
||||
|
||||
try {
|
||||
databaseBackend.open(databaseFilePath);
|
||||
|
||||
emit databaseConnectionIsOpened();
|
||||
} catch (SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnection::setJournalMode(JournalMode journalMode)
|
||||
{
|
||||
try {
|
||||
databaseBackend.setJournalMode(journalMode);
|
||||
} catch (SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnection::close()
|
||||
{
|
||||
databaseBackend.closeWithoutException();
|
||||
|
||||
emit databaseConnectionIsClosed();
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnection::prioritizeThreadDown()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
pid_t processId = syscall(SYS_gettid);
|
||||
int returnCode = setpriority(PRIO_PROCESS, processId, 10);
|
||||
if (returnCode == -1)
|
||||
qWarning() << "cannot renice" << strerror(errno);
|
||||
#endif
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sqlitedatabasebackend.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
struct sqlite3;
|
||||
|
||||
class SQLITE_EXPORT SqliteDatabaseConnection final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SqliteDatabaseConnection(QObject *parent = 0);
|
||||
~SqliteDatabaseConnection();
|
||||
|
||||
static sqlite3 *currentSqliteDatabase();
|
||||
|
||||
public slots:
|
||||
void setDatabaseFilePath(const QString &databaseName);
|
||||
void setJournalMode(JournalMode journalMode);
|
||||
void close();
|
||||
|
||||
protected:
|
||||
void prioritizeThreadDown();
|
||||
|
||||
signals:
|
||||
void databaseConnectionIsOpened();
|
||||
void databaseConnectionIsClosed();
|
||||
|
||||
private:
|
||||
SqliteDatabaseBackend databaseBackend;
|
||||
};
|
@@ -1,92 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sqlitedatabaseconnectionproxy.h"
|
||||
|
||||
#include "sqlitedatabaseconnection.h"
|
||||
#include "sqliteworkerthread.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
||||
SqliteDatabaseConnectionProxy::SqliteDatabaseConnectionProxy(const QString &threadName) :
|
||||
QObject(),
|
||||
databaseConnectionIsOpen(false)
|
||||
{
|
||||
|
||||
databaseConnectionThread = new SqliteWorkerThread;
|
||||
databaseConnectionThread->setObjectName(threadName);
|
||||
|
||||
databaseConnectionThread->start(QThread::LowPriority);
|
||||
|
||||
SqliteDatabaseConnection *connection = databaseConnectionThread->databaseConnection();
|
||||
|
||||
|
||||
connect(this, &SqliteDatabaseConnectionProxy::setDatabaseFilePath, connection, &SqliteDatabaseConnection::setDatabaseFilePath);
|
||||
connect(this, &SqliteDatabaseConnectionProxy::setJournalMode, connection, &SqliteDatabaseConnection::setJournalMode);
|
||||
connect(this, &SqliteDatabaseConnectionProxy::close, connection, &SqliteDatabaseConnection::close);
|
||||
|
||||
connect(connection, &SqliteDatabaseConnection::databaseConnectionIsOpened, this, &SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsOpened);
|
||||
connect(connection, &SqliteDatabaseConnection::databaseConnectionIsClosed, this, &SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsClosed);
|
||||
|
||||
}
|
||||
|
||||
SqliteDatabaseConnectionProxy::~SqliteDatabaseConnectionProxy()
|
||||
{
|
||||
if (databaseConnectionThread) {
|
||||
databaseConnectionThread->quit();
|
||||
databaseConnectionThread->wait();
|
||||
databaseConnectionThread->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
QThread *SqliteDatabaseConnectionProxy::connectionThread() const
|
||||
{
|
||||
return databaseConnectionThread;
|
||||
}
|
||||
|
||||
bool SqliteDatabaseConnectionProxy::isOpen() const
|
||||
{
|
||||
return databaseConnectionIsOpen;
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnectionProxy::registerTypes()
|
||||
{
|
||||
qRegisterMetaType<JournalMode>("JournalMode");
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsOpened()
|
||||
{
|
||||
databaseConnectionIsOpen = true;
|
||||
|
||||
emit connectionIsOpened();
|
||||
}
|
||||
|
||||
void SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsClosed()
|
||||
{
|
||||
databaseConnectionIsOpen = false;
|
||||
|
||||
emit connectionIsClosed();
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sqliteglobal.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
struct sqlite3;
|
||||
class SqliteWorkerThread;
|
||||
|
||||
class SQLITE_EXPORT SqliteDatabaseConnectionProxy final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SqliteDatabaseConnectionProxy(const QString &threadName);
|
||||
~SqliteDatabaseConnectionProxy();
|
||||
|
||||
QThread *connectionThread() const;
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
static void registerTypes();
|
||||
|
||||
signals:
|
||||
void setDatabaseFilePath(const QString &databaseFilePath);
|
||||
void setJournalMode(JournalMode journal);
|
||||
void connectionIsOpened();
|
||||
void connectionIsClosed();
|
||||
void close();
|
||||
|
||||
private slots:
|
||||
void handleDatabaseConnectionIsOpened();
|
||||
void handleDatabaseConnectionIsClosed();
|
||||
|
||||
private:
|
||||
QPointer<SqliteWorkerThread> databaseConnectionThread;
|
||||
bool databaseConnectionIsOpen;
|
||||
};
|
@@ -27,17 +27,20 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteException::SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage)
|
||||
: whatErrorHasHappen(whatErrorHasHappen),
|
||||
sqliteErrorMessage_(sqliteErrorMessage)
|
||||
: m_whatErrorHasHappen(whatErrorHasHappen),
|
||||
m_sqliteErrorMessage(sqliteErrorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
void SqliteException::printWarning() const
|
||||
{
|
||||
if (!sqliteErrorMessage_.isEmpty())
|
||||
qWarning() << whatErrorHasHappen << sqliteErrorMessage_;
|
||||
if (!m_sqliteErrorMessage.isEmpty())
|
||||
qWarning() << m_whatErrorHasHappen << m_sqliteErrorMessage;
|
||||
else
|
||||
qWarning() << whatErrorHasHappen;
|
||||
qWarning() << m_whatErrorHasHappen;
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -29,14 +29,18 @@
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteException
|
||||
{
|
||||
public:
|
||||
SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage = 0);
|
||||
SqliteException(const char *m_whatErrorHasHappen, const char *sqliteErrorMessage = 0);
|
||||
|
||||
void printWarning() const;
|
||||
|
||||
private:
|
||||
const char *whatErrorHasHappen;
|
||||
QByteArray sqliteErrorMessage_;
|
||||
const char *m_whatErrorHasHappen;
|
||||
QByteArray m_sqliteErrorMessage;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -25,15 +25,8 @@
|
||||
|
||||
#include "sqliteglobal.h"
|
||||
|
||||
#include "createtablecommand.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
void registerTypes()
|
||||
{
|
||||
Internal::CreateTableCommand::registerType();
|
||||
|
||||
qRegisterMetaType<JournalMode>("JournalMode");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteReadStatement::SqliteReadStatement(const Utf8String &sqlStatementUtf8)
|
||||
: SqliteStatement(sqlStatementUtf8)
|
||||
{
|
||||
@@ -38,3 +40,5 @@ void SqliteReadStatement::checkIsReadOnlyStatement()
|
||||
if (!isReadOnlyStatement())
|
||||
throwException("SqliteStatement::SqliteReadStatement: is not read only statement!");
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqlitestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteReadStatement final : private SqliteStatement
|
||||
{
|
||||
public:
|
||||
@@ -49,3 +51,5 @@ public:
|
||||
protected:
|
||||
void checkIsReadOnlyStatement();
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -25,8 +25,11 @@
|
||||
|
||||
#include "sqlitereadwritestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteReadWriteStatement::SqliteReadWriteStatement(const Utf8String &sqlStatementUft8)
|
||||
: SqliteStatement(sqlStatementUft8)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqlitestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteReadWriteStatement final : private SqliteStatement
|
||||
{
|
||||
public:
|
||||
@@ -48,3 +50,5 @@ public:
|
||||
using SqliteStatement::toValue;
|
||||
using SqliteStatement::execute;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -39,11 +39,13 @@
|
||||
# pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
||||
#endif
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteStatement::SqliteStatement(const Utf8String &sqlStatementUtf8)
|
||||
: compiledStatement(nullptr, deleteCompiledStatement),
|
||||
bindingParameterCount(0),
|
||||
columnCount_(0),
|
||||
isReadyToFetchValues(false)
|
||||
: m_compiledStatement(nullptr, deleteCompiledStatement),
|
||||
m_bindingParameterCount(0),
|
||||
m_columnCount(0),
|
||||
m_isReadyToFetchValues(false)
|
||||
{
|
||||
prepare(sqlStatementUtf8);
|
||||
setBindingParameterCount();
|
||||
@@ -108,11 +110,11 @@ void SqliteStatement::waitForUnlockNotify() const
|
||||
|
||||
void SqliteStatement::reset() const
|
||||
{
|
||||
int resultCode = sqlite3_reset(compiledStatement.get());
|
||||
int resultCode = sqlite3_reset(m_compiledStatement.get());
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::reset: can't reset statement!");
|
||||
|
||||
isReadyToFetchValues = false;
|
||||
m_isReadyToFetchValues = false;
|
||||
}
|
||||
|
||||
bool SqliteStatement::next() const
|
||||
@@ -120,10 +122,10 @@ bool SqliteStatement::next() const
|
||||
int resultCode;
|
||||
|
||||
do {
|
||||
resultCode = sqlite3_step(compiledStatement.get());
|
||||
resultCode = sqlite3_step(m_compiledStatement.get());
|
||||
if (resultCode == SQLITE_LOCKED) {
|
||||
waitForUnlockNotify();
|
||||
sqlite3_reset(compiledStatement.get());
|
||||
sqlite3_reset(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
} while (resultCode == SQLITE_LOCKED);
|
||||
@@ -154,7 +156,7 @@ void SqliteStatement::writeUnchecked(const RowDictionary &rowDictionary)
|
||||
|
||||
int SqliteStatement::columnCount() const
|
||||
{
|
||||
return columnCount_;
|
||||
return m_columnCount;
|
||||
}
|
||||
|
||||
Utf8StringVector SqliteStatement::columnNames() const
|
||||
@@ -163,28 +165,28 @@ Utf8StringVector SqliteStatement::columnNames() const
|
||||
int columnCount = SqliteStatement::columnCount();
|
||||
columnNames.reserve(columnCount);
|
||||
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
|
||||
columnNames.append(Utf8String(sqlite3_column_origin_name(compiledStatement.get(), columnIndex), -1));
|
||||
columnNames.append(Utf8String(sqlite3_column_origin_name(m_compiledStatement.get(), columnIndex), -1));
|
||||
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
void SqliteStatement::bind(int index, int value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_int(compiledStatement.get(), index, value);
|
||||
int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
|
||||
}
|
||||
|
||||
void SqliteStatement::bind(int index, qint64 value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_int64(compiledStatement.get(), index, value);
|
||||
int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind 64 bit integer!");
|
||||
}
|
||||
|
||||
void SqliteStatement::bind(int index, double value)
|
||||
{
|
||||
int resultCode = sqlite3_bind_double(compiledStatement.get(), index, value);
|
||||
int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value);
|
||||
if (resultCode != SQLITE_OK)
|
||||
throwException("SqliteStatement::bind: cant' bind double!");
|
||||
}
|
||||
@@ -194,9 +196,9 @@ void SqliteStatement::bind(int index, const QString &text)
|
||||
int resultCode;
|
||||
if (databaseTextEncoding() == Utf8) {
|
||||
QByteArray textUtf8 = text.toUtf8();
|
||||
resultCode = sqlite3_bind_text(compiledStatement.get(), index, textUtf8.constData(), textUtf8.size(), SQLITE_TRANSIENT);
|
||||
resultCode = sqlite3_bind_text(m_compiledStatement.get(), index, textUtf8.constData(), textUtf8.size(), SQLITE_TRANSIENT);
|
||||
} else {
|
||||
resultCode = sqlite3_bind_text16(compiledStatement.get(), index, text.constData(), text.size() * 2, SQLITE_TRANSIENT);
|
||||
resultCode = sqlite3_bind_text16(m_compiledStatement.get(), index, text.constData(), text.size() * 2, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
if (resultCode != SQLITE_OK)
|
||||
@@ -205,7 +207,7 @@ void SqliteStatement::bind(int index, const QString &text)
|
||||
|
||||
void SqliteStatement::bind(int index, const QByteArray &blob)
|
||||
{
|
||||
sqlite3_bind_blob(compiledStatement.get(), index, blob.constData(), blob.size(), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_blob(m_compiledStatement.get(), index, blob.constData(), blob.size(), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
void SqliteStatement::bind(int index, const QVariant &value)
|
||||
@@ -232,7 +234,7 @@ void SqliteStatement::bind(int index, const QVariant &value)
|
||||
bind(index, value.toByteArray());
|
||||
break;
|
||||
default:
|
||||
sqlite3_bind_null(compiledStatement.get(), index);
|
||||
sqlite3_bind_null(m_compiledStatement.get(), index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +255,7 @@ template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const
|
||||
|
||||
int SqliteStatement::bindingIndexForName(const Utf8String &name)
|
||||
{
|
||||
return sqlite3_bind_parameter_index(compiledStatement.get(), name.constData());
|
||||
return sqlite3_bind_parameter_index(m_compiledStatement.get(), name.constData());
|
||||
}
|
||||
|
||||
void SqliteStatement::bind(const RowDictionary &rowDictionary)
|
||||
@@ -261,7 +263,7 @@ void SqliteStatement::bind(const RowDictionary &rowDictionary)
|
||||
checkBindingValueMapIsEmpty(rowDictionary);
|
||||
|
||||
int columnIndex = 1;
|
||||
foreach (const Utf8String &columnName, bindingColumnNames_) {
|
||||
foreach (const Utf8String &columnName, m_bindingColumnNames) {
|
||||
checkParameterCanBeBound(rowDictionary, columnName);
|
||||
QVariant value = rowDictionary.value(columnName);
|
||||
bind(columnIndex, value);
|
||||
@@ -274,7 +276,7 @@ void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
|
||||
checkBindingValueMapIsEmpty(rowDictionary);
|
||||
|
||||
int columnIndex = 1;
|
||||
foreach (const Utf8String &columnName, bindingColumnNames_) {
|
||||
foreach (const Utf8String &columnName, m_bindingColumnNames) {
|
||||
if (rowDictionary.contains(columnName)) {
|
||||
QVariant value = rowDictionary.value(columnName);
|
||||
bind(columnIndex, value);
|
||||
@@ -285,12 +287,12 @@ void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
|
||||
|
||||
void SqliteStatement::setBindingColumnNames(const Utf8StringVector &bindingColumnNames)
|
||||
{
|
||||
bindingColumnNames_ = bindingColumnNames;
|
||||
m_bindingColumnNames = bindingColumnNames;
|
||||
}
|
||||
|
||||
const Utf8StringVector &SqliteStatement::bindingColumnNames() const
|
||||
{
|
||||
return bindingColumnNames_;
|
||||
return m_bindingColumnNames;
|
||||
}
|
||||
|
||||
void SqliteStatement::execute(const Utf8String &sqlStatementUtf8)
|
||||
@@ -306,7 +308,7 @@ void SqliteStatement::prepare(const Utf8String &sqlStatementUtf8)
|
||||
do {
|
||||
sqlite3_stmt *sqliteStatement = nullptr;
|
||||
resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(), sqlStatementUtf8.constData(), sqlStatementUtf8.byteSize(), &sqliteStatement, nullptr);
|
||||
compiledStatement.reset(sqliteStatement);
|
||||
m_compiledStatement.reset(sqliteStatement);
|
||||
|
||||
if (resultCode == SQLITE_LOCKED)
|
||||
waitForUnlockNotify();
|
||||
@@ -362,41 +364,41 @@ void SqliteStatement::checkForPrepareError(int resultCode) const
|
||||
void SqliteStatement::setIfIsReadyToFetchValues(int resultCode) const
|
||||
{
|
||||
if (resultCode == SQLITE_ROW)
|
||||
isReadyToFetchValues = true;
|
||||
m_isReadyToFetchValues = true;
|
||||
else
|
||||
isReadyToFetchValues = false;
|
||||
m_isReadyToFetchValues = false;
|
||||
|
||||
}
|
||||
|
||||
void SqliteStatement::checkIfIsReadyToFetchValues() const
|
||||
{
|
||||
if (!isReadyToFetchValues)
|
||||
if (!m_isReadyToFetchValues)
|
||||
throwException("SqliteStatement::value: there are no values to fetch!");
|
||||
}
|
||||
|
||||
void SqliteStatement::checkColumnsAreValid(const QVector<int> &columns) const
|
||||
{
|
||||
foreach (int column, columns) {
|
||||
if (column < 0 || column >= columnCount_)
|
||||
if (column < 0 || column >= m_columnCount)
|
||||
throwException("SqliteStatement::values: column index out of bound!");
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteStatement::checkColumnIsValid(int column) const
|
||||
{
|
||||
if (column < 0 || column >= columnCount_)
|
||||
if (column < 0 || column >= m_columnCount)
|
||||
throwException("SqliteStatement::values: column index out of bound!");
|
||||
}
|
||||
|
||||
void SqliteStatement::checkBindingIndex(int index) const
|
||||
{
|
||||
if (index <= 0 || index > bindingParameterCount)
|
||||
if (index <= 0 || index > m_bindingParameterCount)
|
||||
throwException("SqliteStatement::bind: binding index is out of bound!");
|
||||
}
|
||||
|
||||
void SqliteStatement::checkBindingName(int index) const
|
||||
{
|
||||
if (index <= 0 || index > bindingParameterCount)
|
||||
if (index <= 0 || index > m_bindingParameterCount)
|
||||
throwException("SqliteStatement::bind: binding name are not exists in this statement!");
|
||||
}
|
||||
|
||||
@@ -408,7 +410,7 @@ void SqliteStatement::checkParameterCanBeBound(const RowDictionary &rowDictionar
|
||||
|
||||
void SqliteStatement::setBindingParameterCount()
|
||||
{
|
||||
bindingParameterCount = sqlite3_bind_parameter_count(compiledStatement.get());
|
||||
m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
Utf8String chopFirstLetter(const char *rawBindingName)
|
||||
@@ -421,15 +423,15 @@ Utf8String chopFirstLetter(const char *rawBindingName)
|
||||
|
||||
void SqliteStatement::setBindingColumnNamesFromStatement()
|
||||
{
|
||||
for (int index = 1; index <= bindingParameterCount; index++) {
|
||||
Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(compiledStatement.get(), index));
|
||||
bindingColumnNames_.append(bindingName);
|
||||
for (int index = 1; index <= m_bindingParameterCount; index++) {
|
||||
Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(m_compiledStatement.get(), index));
|
||||
m_bindingColumnNames.append(bindingName);
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteStatement::setColumnCount()
|
||||
{
|
||||
columnCount_ = sqlite3_column_count(compiledStatement.get());
|
||||
m_columnCount = sqlite3_column_count(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const
|
||||
@@ -440,7 +442,7 @@ void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictio
|
||||
|
||||
bool SqliteStatement::isReadOnlyStatement() const
|
||||
{
|
||||
return sqlite3_stmt_readonly(compiledStatement.get());
|
||||
return sqlite3_stmt_readonly(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
void SqliteStatement::throwException(const char *whatHasHappened)
|
||||
@@ -450,7 +452,7 @@ void SqliteStatement::throwException(const char *whatHasHappened)
|
||||
|
||||
QString SqliteStatement::columnName(int column) const
|
||||
{
|
||||
return QString::fromUtf8(sqlite3_column_name(compiledStatement.get(), column));
|
||||
return QString::fromUtf8(sqlite3_column_name(m_compiledStatement.get(), column));
|
||||
}
|
||||
|
||||
static bool columnIsBlob(sqlite3_stmt *sqlStatment, int column)
|
||||
@@ -521,7 +523,7 @@ int SqliteStatement::value<int>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return sqlite3_column_int(compiledStatement.get(), column);
|
||||
return sqlite3_column_int(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -529,7 +531,7 @@ qint64 SqliteStatement::value<qint64>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return sqlite3_column_int64(compiledStatement.get(), column);
|
||||
return sqlite3_column_int64(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -537,7 +539,7 @@ double SqliteStatement::value<double>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return sqlite3_column_double(compiledStatement.get(), column);
|
||||
return sqlite3_column_double(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -545,7 +547,7 @@ QByteArray SqliteStatement::value<QByteArray>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return byteArrayForColumn(compiledStatement.get(), column);
|
||||
return byteArrayForColumn(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -553,7 +555,7 @@ Utf8String SqliteStatement::value<Utf8String>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return convertedToUtf8StringForColumn(compiledStatement.get(), column);
|
||||
return convertedToUtf8StringForColumn(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -561,7 +563,7 @@ QString SqliteStatement::value<QString>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return textForColumn(compiledStatement.get(), column);
|
||||
return textForColumn(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -569,7 +571,7 @@ QVariant SqliteStatement::value<QVariant>(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return variantForColumn(compiledStatement.get(), column);
|
||||
return variantForColumn(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
@@ -592,7 +594,7 @@ QMap<QString, QVariant> SqliteStatement::rowColumnValueMap() const
|
||||
|
||||
if (next()) {
|
||||
for (int column = 0; column < columnCount(); column++)
|
||||
values.insert(columnName(column), variantForColumn(compiledStatement.get(), column));
|
||||
values.insert(columnName(column), variantForColumn(m_compiledStatement.get(), column));
|
||||
}
|
||||
|
||||
return values;
|
||||
@@ -605,7 +607,7 @@ QMap<QString, QVariant> SqliteStatement::twoColumnValueMap() const
|
||||
reset();
|
||||
|
||||
while (next())
|
||||
values.insert(textForColumn(compiledStatement.get(), 0), variantForColumn(compiledStatement.get(), 1));
|
||||
values.insert(textForColumn(m_compiledStatement.get(), 0), variantForColumn(m_compiledStatement.get(), 1));
|
||||
|
||||
return values;
|
||||
}
|
||||
@@ -669,3 +671,4 @@ template SQLITE_EXPORT QByteArray SqliteStatement::toValue<QByteArray>(const Utf
|
||||
template SQLITE_EXPORT Utf8String SqliteStatement::toValue<Utf8String>(const Utf8String &sqlStatementUtf8);
|
||||
template SQLITE_EXPORT QVariant SqliteStatement::toValue<QVariant>(const Utf8String &sqlStatementUtf8);
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -40,12 +40,14 @@
|
||||
struct sqlite3_stmt;
|
||||
struct sqlite3;
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteStatement
|
||||
{
|
||||
protected:
|
||||
explicit SqliteStatement(const Utf8String &sqlStatementUtf8);
|
||||
|
||||
static void deleteCompiledStatement(sqlite3_stmt *compiledStatement);
|
||||
static void deleteCompiledStatement(sqlite3_stmt *m_compiledStatement);
|
||||
|
||||
bool next() const;
|
||||
void step() const;
|
||||
@@ -120,9 +122,11 @@ protected:
|
||||
QString columnName(int column) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> compiledStatement;
|
||||
Utf8StringVector bindingColumnNames_;
|
||||
int bindingParameterCount;
|
||||
int columnCount_;
|
||||
mutable bool isReadyToFetchValues;
|
||||
std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement;
|
||||
Utf8StringVector m_bindingColumnNames;
|
||||
int m_bindingParameterCount;
|
||||
int m_columnCount;
|
||||
mutable bool m_isReadyToFetchValues;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,88 +27,91 @@
|
||||
|
||||
#include "sqlitecolumn.h"
|
||||
#include "sqlitedatabase.h"
|
||||
#include "createtablesqlstatementbuilder.h"
|
||||
#include "sqlitewritestatement.h"
|
||||
#include "sqlitetransaction.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteTable::SqliteTable()
|
||||
: withoutRowId(false)
|
||||
: m_withoutRowId(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SqliteTable::~SqliteTable()
|
||||
{
|
||||
qDeleteAll(sqliteColumns);
|
||||
qDeleteAll(m_sqliteColumns);
|
||||
}
|
||||
|
||||
void SqliteTable::setName(const Utf8String &name)
|
||||
{
|
||||
tableName = name;
|
||||
m_tableName = name;
|
||||
}
|
||||
|
||||
const Utf8String &SqliteTable::name() const
|
||||
{
|
||||
return tableName;
|
||||
return m_tableName;
|
||||
}
|
||||
|
||||
void SqliteTable::setUseWithoutRowId(bool useWithoutWorId)
|
||||
{
|
||||
withoutRowId = useWithoutWorId;
|
||||
m_withoutRowId = useWithoutWorId;
|
||||
}
|
||||
|
||||
bool SqliteTable::useWithoutRowId() const
|
||||
{
|
||||
return withoutRowId;
|
||||
return m_withoutRowId;
|
||||
}
|
||||
|
||||
void SqliteTable::addColumn(SqliteColumn *newColumn)
|
||||
{
|
||||
sqliteColumns.append(newColumn);
|
||||
m_sqliteColumns.append(newColumn);
|
||||
}
|
||||
|
||||
const QVector<SqliteColumn *> &SqliteTable::columns() const
|
||||
{
|
||||
return sqliteColumns;
|
||||
return m_sqliteColumns;
|
||||
}
|
||||
|
||||
void SqliteTable::setSqliteDatabase(SqliteDatabase *database)
|
||||
{
|
||||
sqliteDatabase = database;
|
||||
writeWorker.moveWorkerToThread(sqliteDatabase->writeWorkerThread());
|
||||
m_sqliteDatabase = database;
|
||||
}
|
||||
|
||||
void SqliteTable::initialize()
|
||||
{
|
||||
writeWorker.connectWithWorker(this);
|
||||
try {
|
||||
CreateTableSqlStatementBuilder createTableSqlStatementBuilder;
|
||||
|
||||
writeWorker.createTable(createTableCommand());
|
||||
createTableSqlStatementBuilder.setTable(m_tableName);
|
||||
createTableSqlStatementBuilder.setUseWithoutRowId(m_withoutRowId);
|
||||
createTableSqlStatementBuilder.setColumnDefinitions(createColumnDefintions());
|
||||
|
||||
SqliteImmediateTransaction transaction;
|
||||
SqliteWriteStatement::execute(createTableSqlStatementBuilder.sqlStatement());
|
||||
transaction.commit();
|
||||
|
||||
m_isReady = true;
|
||||
|
||||
} catch (const SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteTable::shutdown()
|
||||
bool SqliteTable::isReady() const
|
||||
{
|
||||
writeWorker.disconnectWithWorker(this);
|
||||
return m_isReady;
|
||||
}
|
||||
|
||||
void SqliteTable::handleTableCreated()
|
||||
QVector<ColumnDefinition> SqliteTable::createColumnDefintions() const
|
||||
{
|
||||
emit tableIsReady();
|
||||
}
|
||||
QVector<ColumnDefinition> columnDefintions;
|
||||
|
||||
Internal::CreateTableCommand SqliteTable::createTableCommand() const
|
||||
{
|
||||
Internal::CreateTableCommand createTableCommand;
|
||||
|
||||
createTableCommand.tableName = tableName;
|
||||
createTableCommand.useWithoutRowId = withoutRowId;
|
||||
createTableCommand.definitions = createColumnDefintions();
|
||||
|
||||
return createTableCommand;
|
||||
}
|
||||
|
||||
QVector<Internal::ColumnDefinition> SqliteTable::createColumnDefintions() const
|
||||
{
|
||||
QVector<Internal::ColumnDefinition> columnDefintions;
|
||||
|
||||
for (SqliteColumn *sqliteColumn: sqliteColumns)
|
||||
for (SqliteColumn *sqliteColumn : m_sqliteColumns)
|
||||
columnDefintions.append(sqliteColumn->columnDefintion());
|
||||
|
||||
return columnDefintions;
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -26,21 +26,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "sqliteglobal.h"
|
||||
#include "tablewriteworkerproxy.h"
|
||||
#include "columndefinition.h"
|
||||
#include "utf8string.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SqliteColumn;
|
||||
class SqliteDatabase;
|
||||
|
||||
class SQLITE_EXPORT SqliteTable : public QObject
|
||||
class SQLITE_EXPORT SqliteTable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class Internal::TableWriteWorkerProxy;
|
||||
|
||||
public:
|
||||
SqliteTable();
|
||||
~SqliteTable();
|
||||
@@ -57,20 +55,19 @@ public:
|
||||
void setSqliteDatabase(SqliteDatabase *database);
|
||||
|
||||
void initialize();
|
||||
void shutdown();
|
||||
|
||||
signals:
|
||||
void tableIsReady();
|
||||
bool isReady() const;
|
||||
|
||||
private:
|
||||
void handleTableCreated();
|
||||
Internal::CreateTableCommand createTableCommand() const;
|
||||
QVector<Internal::ColumnDefinition> createColumnDefintions() const;
|
||||
QVector<ColumnDefinition> createColumnDefintions() const;
|
||||
|
||||
private:
|
||||
Internal::TableWriteWorkerProxy writeWorker;
|
||||
QVector<SqliteColumn*> sqliteColumns;
|
||||
Utf8String tableName;
|
||||
SqliteDatabase *sqliteDatabase;
|
||||
bool withoutRowId;
|
||||
QVector<SqliteColumn*> m_sqliteColumns;
|
||||
Utf8String m_tableName;
|
||||
SqliteDatabase *m_sqliteDatabase;
|
||||
bool m_withoutRowId;
|
||||
|
||||
bool m_isReady = false;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,16 +27,18 @@
|
||||
|
||||
#include "sqlitewritestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteAbstractTransaction::~SqliteAbstractTransaction()
|
||||
{
|
||||
if (!isAlreadyCommited)
|
||||
if (!m_isAlreadyCommited)
|
||||
SqliteWriteStatement::execute(Utf8StringLiteral("ROLLBACK"));
|
||||
}
|
||||
|
||||
void SqliteAbstractTransaction::commit()
|
||||
{
|
||||
SqliteWriteStatement::execute(Utf8StringLiteral("COMMIT"));
|
||||
isAlreadyCommited = true;
|
||||
m_isAlreadyCommited = true;
|
||||
}
|
||||
|
||||
SqliteTransaction::SqliteTransaction()
|
||||
@@ -53,3 +55,5 @@ SqliteExclusiveTransaction::SqliteExclusiveTransaction()
|
||||
{
|
||||
SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN EXCLUSIVE"));
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqliteglobal.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteAbstractTransaction
|
||||
{
|
||||
public:
|
||||
@@ -35,7 +37,7 @@ public:
|
||||
void commit();
|
||||
|
||||
private:
|
||||
bool isAlreadyCommited = false;
|
||||
bool m_isAlreadyCommited = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -59,3 +61,5 @@ public:
|
||||
SqliteExclusiveTransaction();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -1,59 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sqliteworkerthread.h"
|
||||
|
||||
#include "sqlitedatabaseconnection.h"
|
||||
|
||||
#include <QMutexLocker>
|
||||
|
||||
SqliteWorkerThread::SqliteWorkerThread(QObject *parent) :
|
||||
QThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void SqliteWorkerThread::run()
|
||||
{
|
||||
QMutexLocker locker(&connectionMutex);
|
||||
|
||||
connection = new SqliteDatabaseConnection;
|
||||
|
||||
locker.unlock();
|
||||
connectionChanged.wakeAll();
|
||||
|
||||
QThread::run();
|
||||
|
||||
locker.relock();
|
||||
delete connection;
|
||||
connection = 0;
|
||||
}
|
||||
|
||||
SqliteDatabaseConnection *SqliteWorkerThread::databaseConnection() const
|
||||
{
|
||||
QMutexLocker locker(&connectionMutex);
|
||||
connectionChanged.wait(&connectionMutex);
|
||||
|
||||
return connection;
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
|
||||
class SqliteDatabaseConnection;
|
||||
|
||||
class SqliteWorkerThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SqliteWorkerThread(QObject *parent = 0);
|
||||
|
||||
void run() override;
|
||||
|
||||
SqliteDatabaseConnection *databaseConnection() const;
|
||||
|
||||
private:
|
||||
mutable QMutex connectionMutex;
|
||||
mutable QWaitCondition connectionChanged;
|
||||
QPointer<SqliteDatabaseConnection> connection;
|
||||
};
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "sqlitewritestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqliteWriteStatement::SqliteWriteStatement(const Utf8String &sqlStatementUtf8)
|
||||
: SqliteStatement(sqlStatementUtf8)
|
||||
{
|
||||
@@ -36,3 +38,5 @@ void SqliteWriteStatement::checkIsWritableStatement()
|
||||
if (isReadOnlyStatement())
|
||||
throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sqlitestatement.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement
|
||||
{
|
||||
public:
|
||||
@@ -46,3 +48,5 @@ public:
|
||||
protected:
|
||||
void checkIsWritableStatement();
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -30,8 +30,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqlStatementBuilder::SqlStatementBuilder(const Utf8String &sqlTemplate)
|
||||
: sqlTemplate(sqlTemplate)
|
||||
: m_sqlTemplate(sqlTemplate)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,8 +101,8 @@ void SqlStatementBuilder::bindWithUpdateTemplateNames(const Utf8String &name, co
|
||||
|
||||
void SqlStatementBuilder::clear()
|
||||
{
|
||||
bindings.clear();
|
||||
sqlStatement_.clear();
|
||||
m_bindings.clear();
|
||||
m_sqlStatement_.clear();
|
||||
}
|
||||
|
||||
const Utf8String SqlStatementBuilder::insertTemplateParameters(const Utf8StringVector &columns)
|
||||
@@ -130,7 +132,7 @@ const Utf8String SqlStatementBuilder::updateTemplateNames(const Utf8StringVector
|
||||
|
||||
void SqlStatementBuilder::sortBindings() const
|
||||
{
|
||||
std::sort(bindings.begin(), bindings.end(), [] (const BindingPair &lhs,const BindingPair &rhs)
|
||||
std::sort(m_bindings.begin(), m_bindings.end(), [] (const BindingPair &lhs,const BindingPair &rhs)
|
||||
{
|
||||
return lhs.first.byteSize() == rhs.first.byteSize() ? lhs.first.toByteArray() < rhs.first.toByteArray() : lhs.first.byteSize() > rhs.first.byteSize();
|
||||
});
|
||||
@@ -141,12 +143,12 @@ Utf8String SqlStatementBuilder::sqlStatement() const
|
||||
if (!isBuild())
|
||||
generateSqlStatement();
|
||||
|
||||
return sqlStatement_;
|
||||
return m_sqlStatement_;
|
||||
}
|
||||
|
||||
bool SqlStatementBuilder::isBuild() const
|
||||
{
|
||||
return sqlStatement_.hasContent();
|
||||
return m_sqlStatement_.hasContent();
|
||||
}
|
||||
|
||||
Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
|
||||
@@ -164,15 +166,15 @@ Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
|
||||
|
||||
void SqlStatementBuilder::generateSqlStatement() const
|
||||
{
|
||||
sqlStatement_ = sqlTemplate;
|
||||
m_sqlStatement_ = m_sqlTemplate;
|
||||
|
||||
sortBindings();
|
||||
|
||||
auto bindingIterator = bindings.cbegin();
|
||||
while (bindingIterator != bindings.cend()) {
|
||||
auto bindingIterator = m_bindings.cbegin();
|
||||
while (bindingIterator != m_bindings.cend()) {
|
||||
const Utf8String &placeHolderToken = bindingIterator->first;
|
||||
const Utf8String &replacementToken = bindingIterator->second;
|
||||
sqlStatement_.replace(placeHolderToken, replacementToken);
|
||||
m_sqlStatement_.replace(placeHolderToken, replacementToken);
|
||||
++bindingIterator;
|
||||
}
|
||||
|
||||
@@ -182,52 +184,54 @@ void SqlStatementBuilder::generateSqlStatement() const
|
||||
void SqlStatementBuilder::changeBinding(const Utf8String &name, const Utf8String &text)
|
||||
{
|
||||
|
||||
auto findBindingIterator = std::find_if(bindings.begin(), bindings.end(), [name] (const BindingPair &binding) {
|
||||
auto findBindingIterator = std::find_if(m_bindings.begin(), m_bindings.end(), [name] (const BindingPair &binding) {
|
||||
return binding.first == name;
|
||||
});
|
||||
|
||||
if (findBindingIterator == bindings.end())
|
||||
bindings.push_back(std::make_pair(name, text));
|
||||
if (findBindingIterator == m_bindings.end())
|
||||
m_bindings.push_back(std::make_pair(name, text));
|
||||
else
|
||||
findBindingIterator->second = text;
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::clearSqlStatement()
|
||||
{
|
||||
sqlStatement_.clear();
|
||||
m_sqlStatement_.clear();
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::checkIfPlaceHolderExists(const Utf8String &name) const
|
||||
{
|
||||
if (name.byteSize() < 2 || !name.startsWith('$') || !sqlTemplate.contains(name))
|
||||
if (name.byteSize() < 2 || !name.startsWith('$') || !m_sqlTemplate.contains(name))
|
||||
throwException("SqlStatementBuilder::bind: placeholder name does not exists!", name.constData());
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::checkIfNoPlaceHoldersAynmoreExists() const
|
||||
{
|
||||
if (sqlStatement_.contains('$'))
|
||||
throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", sqlTemplate.constData());
|
||||
if (m_sqlStatement_.contains('$'))
|
||||
throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", m_sqlTemplate.constData());
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::checkBindingTextIsNotEmpty(const Utf8String &text) const
|
||||
{
|
||||
if (text.isEmpty())
|
||||
throwException("SqlStatementBuilder::bind: binding text it empty!", sqlTemplate.constData());
|
||||
throwException("SqlStatementBuilder::bind: binding text it empty!", m_sqlTemplate.constData());
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const
|
||||
{
|
||||
if (textVector.isEmpty())
|
||||
throwException("SqlStatementBuilder::bind: binding text vector it empty!", sqlTemplate.constData());
|
||||
throwException("SqlStatementBuilder::bind: binding text vector it empty!", m_sqlTemplate.constData());
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const
|
||||
{
|
||||
if (integerVector.isEmpty())
|
||||
throwException("SqlStatementBuilder::bind: binding integer vector it empty!", sqlTemplate.constData());
|
||||
throwException("SqlStatementBuilder::bind: binding integer vector it empty!", m_sqlTemplate.constData());
|
||||
}
|
||||
|
||||
void SqlStatementBuilder::throwException(const char *whatHasHappened, const char *errorMessage)
|
||||
{
|
||||
throw SqlStatementBuilderException(whatHasHappened, errorMessage);
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -30,11 +30,13 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqlStatementBuilder
|
||||
{
|
||||
using BindingPair = std::pair<Utf8String, Utf8String>;
|
||||
public:
|
||||
SqlStatementBuilder(const Utf8String &sqlTemplate);
|
||||
SqlStatementBuilder(const Utf8String &m_sqlTemplate);
|
||||
|
||||
void bindEmptyText(const Utf8String &name);
|
||||
void bind(const Utf8String &name, const Utf8String &text);
|
||||
@@ -72,7 +74,9 @@ protected:
|
||||
Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage);
|
||||
|
||||
private:
|
||||
Utf8String sqlTemplate;
|
||||
mutable Utf8String sqlStatement_;
|
||||
mutable std::vector<BindingPair> bindings;
|
||||
Utf8String m_sqlTemplate;
|
||||
mutable Utf8String m_sqlStatement_;
|
||||
mutable std::vector<BindingPair> m_bindings;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -25,7 +25,11 @@
|
||||
|
||||
#include "sqlstatementbuilderexception.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
SqlStatementBuilderException::SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage)
|
||||
: SqliteException(whatErrorHasHappen, errorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -27,8 +27,12 @@
|
||||
|
||||
#include "sqliteexception.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SQLITE_EXPORT SqlStatementBuilderException : public SqliteException
|
||||
{
|
||||
public:
|
||||
SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage = 0);
|
||||
SqlStatementBuilderException(const char *m_whatErrorHasHappen, const char *errorMessage = 0);
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -1,65 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "tablewriteworker.h"
|
||||
|
||||
#include "createtablesqlstatementbuilder.h"
|
||||
#include "sqlitetransaction.h"
|
||||
#include "sqlitewritestatement.h"
|
||||
|
||||
namespace Internal {
|
||||
|
||||
TableWriteWorker::TableWriteWorker(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TableWriteWorker::~TableWriteWorker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TableWriteWorker::createTable(const CreateTableCommand &command)
|
||||
{
|
||||
try {
|
||||
CreateTableSqlStatementBuilder createTableSqlStatementBuilder;
|
||||
|
||||
createTableSqlStatementBuilder.setTable(command.tableName);
|
||||
createTableSqlStatementBuilder.setUseWithoutRowId(command.useWithoutRowId);
|
||||
createTableSqlStatementBuilder.setColumnDefinitions(command.definitions);
|
||||
|
||||
SqliteImmediateTransaction transaction;
|
||||
SqliteWriteStatement::execute(createTableSqlStatementBuilder.sqlStatement());
|
||||
transaction.commit();
|
||||
|
||||
emit tableCreated();
|
||||
} catch (const SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -1,48 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "createtablecommand.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class TableWriteWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TableWriteWorker(QObject *parent = 0);
|
||||
~TableWriteWorker();
|
||||
|
||||
void createTable(const CreateTableCommand &command);
|
||||
|
||||
signals:
|
||||
void tableCreated();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Internal
|
@@ -1,62 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "tablewriteworkerproxy.h"
|
||||
|
||||
#include "createtablecommand.h"
|
||||
#include "sqlitetable.h"
|
||||
#include "tablewriteworker.h"
|
||||
|
||||
namespace Internal {
|
||||
|
||||
TableWriteWorkerProxy::TableWriteWorkerProxy()
|
||||
: worker(new TableWriteWorker)
|
||||
{
|
||||
}
|
||||
|
||||
TableWriteWorkerProxy::~TableWriteWorkerProxy()
|
||||
{
|
||||
delete worker;
|
||||
}
|
||||
|
||||
void TableWriteWorkerProxy::connectWithWorker(SqliteTable *sqliterTable)
|
||||
{
|
||||
connect(this, &TableWriteWorkerProxy::createTable, worker, &TableWriteWorker::createTable);
|
||||
connect(worker, &TableWriteWorker::tableCreated, sqliterTable, &SqliteTable::handleTableCreated);
|
||||
}
|
||||
|
||||
void TableWriteWorkerProxy::disconnectWithWorker(SqliteTable *sqliterTable)
|
||||
{
|
||||
disconnect(this, &TableWriteWorkerProxy::createTable, worker, &TableWriteWorker::createTable);
|
||||
disconnect(worker, &TableWriteWorker::tableCreated, sqliterTable, &SqliteTable::handleTableCreated);
|
||||
}
|
||||
|
||||
void TableWriteWorkerProxy::moveWorkerToThread(QThread *workerThread)
|
||||
{
|
||||
worker->moveToThread(workerThread);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -1,63 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "createtablecommand.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QThread;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class SqliteTable;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class TableWriteWorker;
|
||||
|
||||
class TableWriteWorkerProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TableWriteWorkerProxy();
|
||||
~TableWriteWorkerProxy();
|
||||
|
||||
void connectWithWorker(SqliteTable *sqliterTable);
|
||||
void disconnectWithWorker(SqliteTable *sqliterTable);
|
||||
|
||||
void moveWorkerToThread(QThread *workerThread);
|
||||
|
||||
signals:
|
||||
void createTable(const CreateTableCommand &command);
|
||||
|
||||
private:
|
||||
TableWriteWorker *worker;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
@@ -32,18 +32,21 @@
|
||||
|
||||
#include <utf8stringvector.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::ColumnDefinition;
|
||||
using Sqlite::SqlStatementBuilderException;
|
||||
|
||||
class CreateTableSqlStatementBuilder : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
|
||||
void bindValues();
|
||||
static const QVector<Internal::ColumnDefinition> createColumnDefintions();
|
||||
static const Internal::ColumnDefinition createColumnDefintion(const Utf8String &name,
|
||||
ColumnType type,
|
||||
bool isPrimaryKey = false);
|
||||
|
||||
Internal::CreateTableSqlStatementBuilder builder;
|
||||
static const QVector<ColumnDefinition> createColumnDefintions();
|
||||
static const ColumnDefinition createColumnDefintion(const Utf8String &name,
|
||||
ColumnType type,
|
||||
bool isPrimaryKey = false);
|
||||
protected:
|
||||
Sqlite::CreateTableSqlStatementBuilder builder;
|
||||
};
|
||||
|
||||
TEST_F(CreateTableSqlStatementBuilder, IsNotValidAfterCreation)
|
||||
@@ -146,11 +149,6 @@ TEST_F(CreateTableSqlStatementBuilder, SetColumnDefinitions)
|
||||
Utf8StringLiteral("CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)"));
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::SetUp()
|
||||
{
|
||||
builder = Internal::CreateTableSqlStatementBuilder();
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindValues()
|
||||
{
|
||||
builder.clear();
|
||||
@@ -160,9 +158,9 @@ void CreateTableSqlStatementBuilder::bindValues()
|
||||
builder.addColumnDefinition(Utf8StringLiteral("number"),ColumnType:: Numeric);
|
||||
}
|
||||
|
||||
const QVector<Internal::ColumnDefinition> CreateTableSqlStatementBuilder::createColumnDefintions()
|
||||
const QVector<ColumnDefinition> CreateTableSqlStatementBuilder::createColumnDefintions()
|
||||
{
|
||||
QVector<Internal::ColumnDefinition> columnDefinitions;
|
||||
QVector<ColumnDefinition> columnDefinitions;
|
||||
columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("id"), ColumnType::Integer, true));
|
||||
columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("name"), ColumnType::Text));
|
||||
columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("number"), ColumnType::Numeric));
|
||||
@@ -170,9 +168,9 @@ const QVector<Internal::ColumnDefinition> CreateTableSqlStatementBuilder::create
|
||||
return columnDefinitions;
|
||||
}
|
||||
|
||||
const Internal::ColumnDefinition CreateTableSqlStatementBuilder::createColumnDefintion(const Utf8String &name, ColumnType type, bool isPrimaryKey)
|
||||
const ColumnDefinition CreateTableSqlStatementBuilder::createColumnDefintion(const Utf8String &name, ColumnType type, bool isPrimaryKey)
|
||||
{
|
||||
Internal::ColumnDefinition columnDefinition;
|
||||
ColumnDefinition columnDefinition;
|
||||
|
||||
columnDefinition.setName(name);
|
||||
columnDefinition.setType(type);
|
||||
@@ -180,3 +178,5 @@ const Internal::ColumnDefinition CreateTableSqlStatementBuilder::createColumnDef
|
||||
|
||||
return columnDefinition;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,12 +29,14 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::ColumnDefinition;
|
||||
|
||||
class SqliteColumn : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
|
||||
::SqliteColumn column;
|
||||
Sqlite::SqliteColumn column;
|
||||
};
|
||||
|
||||
TEST_F(SqliteColumn, ChangeName)
|
||||
@@ -72,7 +74,7 @@ TEST_F(SqliteColumn, GetColumnDefinition)
|
||||
{
|
||||
column.setName(Utf8StringLiteral("Claudia"));
|
||||
|
||||
Internal::ColumnDefinition columnDefintion = column.columnDefintion();
|
||||
ColumnDefinition columnDefintion = column.columnDefintion();
|
||||
|
||||
ASSERT_THAT(columnDefintion.name(), Utf8StringLiteral("Claudia"));
|
||||
ASSERT_THAT(columnDefintion.type(), ColumnType::Numeric);
|
||||
|
@@ -36,6 +36,10 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using testing::Contains;
|
||||
|
||||
using Sqlite::SqliteTable;
|
||||
|
||||
class SqliteDatabase : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@@ -44,7 +48,7 @@ protected:
|
||||
|
||||
SpyDummy spyDummy;
|
||||
QString databaseFilePath = QStringLiteral(":memory:");
|
||||
::SqliteDatabase database;
|
||||
Sqlite::SqliteDatabase database;
|
||||
};
|
||||
|
||||
TEST_F(SqliteDatabase, SetDatabaseFilePath)
|
||||
@@ -62,20 +66,16 @@ TEST_F(SqliteDatabase, SetJournalMode)
|
||||
TEST_F(SqliteDatabase, OpenDatabase)
|
||||
{
|
||||
database.close();
|
||||
QSignalSpy signalSpy(&spyDummy, &SpyDummy::databaseIsOpened);
|
||||
|
||||
database.open();
|
||||
|
||||
ASSERT_TRUE(signalSpy.wait(100000));
|
||||
ASSERT_TRUE(database.isOpen());
|
||||
}
|
||||
|
||||
TEST_F(SqliteDatabase, CloseDatabase)
|
||||
{
|
||||
QSignalSpy signalSpy(&spyDummy, &SpyDummy::databaseIsClosed);
|
||||
|
||||
database.close();
|
||||
|
||||
ASSERT_TRUE(signalSpy.wait(100000));
|
||||
ASSERT_FALSE(database.isOpen());
|
||||
}
|
||||
|
||||
@@ -85,20 +85,19 @@ TEST_F(SqliteDatabase, AddTable)
|
||||
|
||||
database.addTable(sqliteTable);
|
||||
|
||||
ASSERT_THAT(database.tables().first(), sqliteTable);
|
||||
ASSERT_THAT(database.tables(), Contains(sqliteTable));
|
||||
}
|
||||
|
||||
void SqliteDatabase::SetUp()
|
||||
{
|
||||
QObject::connect(&database, &::SqliteDatabase::databaseIsOpened, &spyDummy, &SpyDummy::databaseIsOpened);
|
||||
QObject::connect(&database, &::SqliteDatabase::databaseIsClosed, &spyDummy, &SpyDummy::databaseIsClosed);
|
||||
|
||||
database.setJournalMode(JournalMode::Memory);
|
||||
database.setDatabaseFilePath(databaseFilePath);
|
||||
database.open();
|
||||
}
|
||||
|
||||
void SqliteDatabase::TearDown()
|
||||
{
|
||||
database.close();
|
||||
if (database.isOpen())
|
||||
database.close();
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::SqliteException;
|
||||
using Sqlite::SqliteWriteStatement;
|
||||
|
||||
class SqliteDatabaseBackend : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@@ -40,7 +43,7 @@ protected:
|
||||
void TearDown() override;
|
||||
|
||||
QString databaseFilePath = QDir::tempPath() + QStringLiteral("/SqliteDatabaseBackendTest.db");
|
||||
::SqliteDatabaseBackend databaseBackend;
|
||||
Sqlite::SqliteDatabaseBackend databaseBackend;
|
||||
};
|
||||
|
||||
using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend;
|
||||
@@ -53,6 +56,7 @@ TEST_F(SqliteDatabaseBackend, OpenAlreadyOpenDatabase)
|
||||
TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase)
|
||||
{
|
||||
databaseBackend.close();
|
||||
|
||||
ASSERT_THROW(databaseBackend.close(), SqliteException);
|
||||
}
|
||||
|
||||
|
@@ -39,6 +39,13 @@
|
||||
#include <QVariant>
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::SqliteException;
|
||||
using Sqlite::SqliteDatabaseBackend;
|
||||
using Sqlite::SqliteReadStatement;
|
||||
using Sqlite::SqliteReadWriteStatement;
|
||||
using Sqlite::SqliteWriteStatement;
|
||||
|
||||
class SqliteStatement : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
@@ -36,6 +36,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::SqliteColumn;
|
||||
using Sqlite::SqliteDatabase;
|
||||
|
||||
class SqliteTable : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@@ -45,8 +48,8 @@ protected:
|
||||
SqliteColumn *addColumn(const Utf8String &columnName);
|
||||
|
||||
SpyDummy spyDummy;
|
||||
SqliteDatabase *database = nullptr;
|
||||
::SqliteTable *table = nullptr;
|
||||
SqliteDatabase database;
|
||||
Sqlite::SqliteTable *table = new Sqlite::SqliteTable;
|
||||
Utf8String tableName = Utf8StringLiteral("testTable");
|
||||
};
|
||||
|
||||
@@ -74,31 +77,25 @@ TEST_F(SqliteTable, SetUseWithoutRowid)
|
||||
|
||||
TEST_F(SqliteTable, TableIsReadyAfterOpenDatabase)
|
||||
{
|
||||
QSignalSpy signalSpy(&spyDummy, &SpyDummy::tableIsReady);
|
||||
table->setName(tableName);
|
||||
addColumn(Utf8StringLiteral("name"));
|
||||
|
||||
database->open();
|
||||
database.open();
|
||||
|
||||
ASSERT_TRUE(signalSpy.wait(100000));
|
||||
ASSERT_TRUE(table->isReady());
|
||||
}
|
||||
|
||||
void SqliteTable::SetUp()
|
||||
{
|
||||
table = new ::SqliteTable;
|
||||
QObject::connect(table, &::SqliteTable::tableIsReady, &spyDummy, &SpyDummy::tableIsReady);
|
||||
|
||||
database = new SqliteDatabase;
|
||||
database->setJournalMode(JournalMode::Memory);
|
||||
database->setDatabaseFilePath( QStringLiteral(":memory:"));
|
||||
database->addTable(table);
|
||||
database.setJournalMode(JournalMode::Memory);
|
||||
database.setDatabaseFilePath( QStringLiteral(":memory:"));
|
||||
database.addTable(table);
|
||||
}
|
||||
|
||||
void SqliteTable::TearDown()
|
||||
{
|
||||
database->close();
|
||||
delete database;
|
||||
database = nullptr;
|
||||
if (database.isOpen())
|
||||
database.close();
|
||||
table = nullptr;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,9 @@
|
||||
|
||||
using namespace ::testing;
|
||||
|
||||
using Sqlite::SqlStatementBuilder;
|
||||
using Sqlite::SqlStatementBuilderException;
|
||||
|
||||
TEST(SqlStatementBuilder, Bind)
|
||||
{
|
||||
SqlStatementBuilder sqlStatementBuilder(Utf8StringLiteral("SELECT $columns FROM $table WHERE $column = 'foo' AND rowid=$row AND rowid IN ($rows)"));
|
||||
|
@@ -44,8 +44,6 @@ int main(int argc, char *argv[])
|
||||
qputenv("TMPDIR", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8());
|
||||
qputenv("TEMP", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8());
|
||||
|
||||
Sqlite::registerTypes();
|
||||
|
||||
QCoreApplication application(argc, argv);
|
||||
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("*.info=false\n*.debug=false\n*.warning=true"));
|
||||
|
Reference in New Issue
Block a user