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:
Marco Bubke
2017-07-26 16:02:24 +02:00
parent 94ba1b8b5d
commit 3dcce060b2
50 changed files with 461 additions and 1196 deletions

View File

@@ -25,49 +25,20 @@
#include "columndefinition.h" #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

View File

@@ -28,25 +28,58 @@
#include "sqliteglobal.h" #include "sqliteglobal.h"
#include "utf8string.h" #include "utf8string.h"
namespace Internal { namespace Sqlite {
class ColumnDefinition class ColumnDefinition
{ {
public: public:
void setName(const Utf8String &name); void setName(const Utf8String &name)
const Utf8String &name() const; {
m_name = name;
}
void setType(ColumnType type); const Utf8String &name() const
ColumnType type() const; {
Utf8String typeString() const; return m_name;
}
void setIsPrimaryKey(bool isPrimaryKey); void setType(ColumnType type)
bool isPrimaryKey() const; {
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: private:
Utf8String name_; Utf8String m_name;
ColumnType type_; ColumnType m_type;
bool isPrimaryKey_ = false; bool m_isPrimaryKey = false;
}; };
} } // namespace Sqlite

View File

@@ -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

View File

@@ -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)

View File

@@ -27,79 +27,79 @@
#include "utf8stringvector.h" #include "utf8stringvector.h"
namespace Internal { namespace Sqlite {
CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder() CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
: sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")), : m_sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")),
useWithoutRowId(false) m_useWithoutRowId(false)
{ {
} }
void CreateTableSqlStatementBuilder::setTable(const Utf8String &tableName) void CreateTableSqlStatementBuilder::setTable(const Utf8String &tableName)
{ {
sqlStatementBuilder.clear(); m_sqlStatementBuilder.clear();
this->tableName = tableName; this->m_tableName = tableName;
} }
void CreateTableSqlStatementBuilder::addColumnDefinition(const Utf8String &columnName, void CreateTableSqlStatementBuilder::addColumnDefinition(const Utf8String &columnName,
ColumnType columnType, ColumnType columnType,
bool isPrimaryKey) bool isPrimaryKey)
{ {
sqlStatementBuilder.clear(); m_sqlStatementBuilder.clear();
ColumnDefinition columnDefinition; ColumnDefinition columnDefinition;
columnDefinition.setName(columnName); columnDefinition.setName(columnName);
columnDefinition.setType(columnType); columnDefinition.setType(columnType);
columnDefinition.setIsPrimaryKey(isPrimaryKey); columnDefinition.setIsPrimaryKey(isPrimaryKey);
columnDefinitions.append(columnDefinition); m_columnDefinitions.append(columnDefinition);
} }
void CreateTableSqlStatementBuilder::setColumnDefinitions(const QVector<ColumnDefinition> &columnDefinitions) void CreateTableSqlStatementBuilder::setColumnDefinitions(const QVector<ColumnDefinition> &columnDefinitions)
{ {
sqlStatementBuilder.clear(); m_sqlStatementBuilder.clear();
this->columnDefinitions = columnDefinitions; this->m_columnDefinitions = columnDefinitions;
} }
void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId) void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
{ {
this->useWithoutRowId = useWithoutRowId; this->m_useWithoutRowId = useWithoutRowId;
} }
void CreateTableSqlStatementBuilder::clear() void CreateTableSqlStatementBuilder::clear()
{ {
sqlStatementBuilder.clear(); m_sqlStatementBuilder.clear();
columnDefinitions.clear(); m_columnDefinitions.clear();
tableName.clear(); m_tableName.clear();
useWithoutRowId = false; m_useWithoutRowId = false;
} }
void CreateTableSqlStatementBuilder::clearColumns() void CreateTableSqlStatementBuilder::clearColumns()
{ {
sqlStatementBuilder.clear(); m_sqlStatementBuilder.clear();
columnDefinitions.clear(); m_columnDefinitions.clear();
} }
Utf8String CreateTableSqlStatementBuilder::sqlStatement() const Utf8String CreateTableSqlStatementBuilder::sqlStatement() const
{ {
if (!sqlStatementBuilder.isBuild()) if (!m_sqlStatementBuilder.isBuild())
bindAll(); bindAll();
return sqlStatementBuilder.sqlStatement(); return m_sqlStatementBuilder.sqlStatement();
} }
bool CreateTableSqlStatementBuilder::isValid() const bool CreateTableSqlStatementBuilder::isValid() const
{ {
return tableName.hasContent() && !columnDefinitions.isEmpty(); return m_tableName.hasContent() && !m_columnDefinitions.isEmpty();
} }
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
{ {
Utf8StringVector columnDefinitionStrings; Utf8StringVector columnDefinitionStrings;
foreach (const ColumnDefinition &columnDefinition, columnDefinitions) { foreach (const ColumnDefinition &columnDefinition, m_columnDefinitions) {
Utf8String columnDefinitionString = columnDefinition.name() + Utf8StringLiteral(" ") + columnDefinition.typeString(); Utf8String columnDefinitionString = columnDefinition.name() + Utf8StringLiteral(" ") + columnDefinition.typeString();
if (columnDefinition.isPrimaryKey()) if (columnDefinition.isPrimaryKey())
@@ -108,19 +108,19 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
columnDefinitionStrings.append(columnDefinitionString); columnDefinitionStrings.append(columnDefinitionString);
} }
sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings); m_sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings);
} }
void CreateTableSqlStatementBuilder::bindAll() const void CreateTableSqlStatementBuilder::bindAll() const
{ {
sqlStatementBuilder.bind(Utf8StringLiteral("$table"), tableName); m_sqlStatementBuilder.bind(Utf8StringLiteral("$table"), m_tableName);
bindColumnDefinitions(); bindColumnDefinitions();
if (useWithoutRowId) if (m_useWithoutRowId)
sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID")); m_sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID"));
else else
sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId")); m_sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId"));
} }
} } // namespace Sqlite

View File

@@ -30,17 +30,17 @@
#include <QVector> #include <QVector>
namespace Internal { namespace Sqlite {
class SQLITE_EXPORT CreateTableSqlStatementBuilder class SQLITE_EXPORT CreateTableSqlStatementBuilder
{ {
public: public:
CreateTableSqlStatementBuilder(); CreateTableSqlStatementBuilder();
void setTable(const Utf8String &tableName); void setTable(const Utf8String &m_tableName);
void addColumnDefinition(const Utf8String &columnName, ColumnType columnType, bool isPrimaryKey = false); void addColumnDefinition(const Utf8String &columnName, ColumnType columnType, bool isPrimaryKey = false);
void setColumnDefinitions(const QVector<ColumnDefinition> & columnDefinitions); void setColumnDefinitions(const QVector<ColumnDefinition> & m_columnDefinitions);
void setUseWithoutRowId(bool useWithoutRowId); void setUseWithoutRowId(bool m_useWithoutRowId);
void clear(); void clear();
void clearColumns(); void clearColumns();
@@ -54,10 +54,10 @@ protected:
void bindAll() const; void bindAll() const;
private: private:
mutable SqlStatementBuilder sqlStatementBuilder; mutable SqlStatementBuilder m_sqlStatementBuilder;
Utf8String tableName; Utf8String m_tableName;
QVector<ColumnDefinition> columnDefinitions; QVector<ColumnDefinition> m_columnDefinitions;
bool useWithoutRowId; bool m_useWithoutRowId;
}; };
} } // namespace Sqlite

View File

@@ -12,18 +12,14 @@ include(../3rdparty/sqlite/sqlite.pri)
SOURCES += \ SOURCES += \
$$PWD/columndefinition.cpp \ $$PWD/columndefinition.cpp \
$$PWD/createtablecommand.cpp \
$$PWD/createtablesqlstatementbuilder.cpp \ $$PWD/createtablesqlstatementbuilder.cpp \
$$PWD/sqlitedatabasebackend.cpp \ $$PWD/sqlitedatabasebackend.cpp \
$$PWD/sqlitedatabaseconnection.cpp \
$$PWD/sqlitedatabaseconnectionproxy.cpp \
$$PWD/sqliteexception.cpp \ $$PWD/sqliteexception.cpp \
$$PWD/sqliteglobal.cpp \ $$PWD/sqliteglobal.cpp \
$$PWD/sqlitereadstatement.cpp \ $$PWD/sqlitereadstatement.cpp \
$$PWD/sqlitereadwritestatement.cpp \ $$PWD/sqlitereadwritestatement.cpp \
$$PWD/sqlitestatement.cpp \ $$PWD/sqlitestatement.cpp \
$$PWD/sqlitetransaction.cpp \ $$PWD/sqlitetransaction.cpp \
$$PWD/sqliteworkerthread.cpp \
$$PWD/sqlitewritestatement.cpp \ $$PWD/sqlitewritestatement.cpp \
$$PWD/sqlstatementbuilder.cpp \ $$PWD/sqlstatementbuilder.cpp \
$$PWD/sqlstatementbuilderexception.cpp \ $$PWD/sqlstatementbuilderexception.cpp \
@@ -31,22 +27,17 @@ SOURCES += \
$$PWD/utf8stringvector.cpp \ $$PWD/utf8stringvector.cpp \
$$PWD/sqlitedatabase.cpp \ $$PWD/sqlitedatabase.cpp \
$$PWD/sqlitetable.cpp \ $$PWD/sqlitetable.cpp \
$$PWD/sqlitecolumn.cpp \ $$PWD/sqlitecolumn.cpp
$$PWD/tablewriteworker.cpp \
$$PWD/tablewriteworkerproxy.cpp
HEADERS += \ HEADERS += \
$$PWD/columndefinition.h \ $$PWD/columndefinition.h \
$$PWD/createtablesqlstatementbuilder.h \ $$PWD/createtablesqlstatementbuilder.h \
$$PWD/sqlitedatabasebackend.h \ $$PWD/sqlitedatabasebackend.h \
$$PWD/sqlitedatabaseconnection.h \
$$PWD/sqlitedatabaseconnectionproxy.h \
$$PWD/sqliteexception.h \ $$PWD/sqliteexception.h \
$$PWD/sqliteglobal.h \ $$PWD/sqliteglobal.h \
$$PWD/sqlitereadstatement.h \ $$PWD/sqlitereadstatement.h \
$$PWD/sqlitereadwritestatement.h \ $$PWD/sqlitereadwritestatement.h \
$$PWD/sqlitestatement.h \ $$PWD/sqlitestatement.h \
$$PWD/sqlitetransaction.h \ $$PWD/sqlitetransaction.h \
$$PWD/sqliteworkerthread.h \
$$PWD/sqlitewritestatement.h \ $$PWD/sqlitewritestatement.h \
$$PWD/sqlstatementbuilder.h \ $$PWD/sqlstatementbuilder.h \
$$PWD/sqlstatementbuilderexception.h \ $$PWD/sqlstatementbuilderexception.h \
@@ -54,10 +45,7 @@ HEADERS += \
$$PWD/utf8stringvector.h \ $$PWD/utf8stringvector.h \
$$PWD/sqlitedatabase.h \ $$PWD/sqlitedatabase.h \
$$PWD/sqlitetable.h \ $$PWD/sqlitetable.h \
$$PWD/sqlitecolumn.h \ $$PWD/sqlitecolumn.h
$$PWD/tablewriteworker.h \
$$PWD/tablewriteworkerproxy.h \
$$PWD/createtablecommand.h
DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA

View File

@@ -25,57 +25,7 @@
#include "sqlitecolumn.h" #include "sqlitecolumn.h"
SqliteColumn::SqliteColumn() namespace Sqlite {
: type_(ColumnType::Numeric),
isPrimaryKey_(false)
{
}
void SqliteColumn::clear() } // namespace Sqlite
{
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;
}

View File

@@ -30,27 +30,70 @@
#include <QObject> #include <QObject>
class SQLITE_EXPORT SqliteColumn : public QObject namespace Sqlite {
class SqliteColumn
{ {
Q_OBJECT
public: public:
SqliteColumn(); SqliteColumn()
: m_type(ColumnType::Numeric),
m_isPrimaryKey(false)
{
void clear(); }
void setName(const Utf8String &newName); void clear()
const Utf8String &name() const; {
m_name.clear();
m_type = ColumnType::Numeric;
m_isPrimaryKey = false;
}
void setType(ColumnType newType); void setName(const Utf8String &newName)
ColumnType type() const; {
m_name = newName;
}
void setIsPrimaryKey(bool isPrimaryKey); const Utf8String &name() const
bool isPrimaryKey() 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: private:
Utf8String name_; Utf8String m_name;
ColumnType type_; ColumnType m_type;
bool isPrimaryKey_; bool m_isPrimaryKey;
}; };
} // namespace Sqlite

View File

@@ -27,103 +27,66 @@
#include "sqlitetable.h" #include "sqlitetable.h"
namespace Sqlite {
SqliteDatabase::SqliteDatabase() SqliteDatabase::SqliteDatabase()
: readDatabaseConnection(QStringLiteral("ReadWorker")), : m_journalMode(JournalMode::Wal)
writeDatabaseConnection(QStringLiteral("WriterWorker")),
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() SqliteDatabase::~SqliteDatabase()
{ {
qDeleteAll(sqliteTables); qDeleteAll(m_sqliteTables);
} }
void SqliteDatabase::open() void SqliteDatabase::open()
{ {
writeDatabaseConnection.setDatabaseFilePath(databaseFilePath()); m_sqliteDatabaseBackEnd.open(m_databaseFilePath);
writeDatabaseConnection.setJournalMode(journalMode()); m_sqliteDatabaseBackEnd.setJournalMode(journalMode());
initializeTables();
m_isOpen = true;
} }
void SqliteDatabase::close() void SqliteDatabase::close()
{ {
writeDatabaseConnection.close(); m_isOpen = false;
m_sqliteDatabaseBackEnd.close();
} }
bool SqliteDatabase::isOpen() const bool SqliteDatabase::isOpen() const
{ {
return readDatabaseConnection.isOpen() && writeDatabaseConnection.isOpen(); return m_isOpen;
} }
void SqliteDatabase::addTable(SqliteTable *newSqliteTable) void SqliteDatabase::addTable(SqliteTable *newSqliteTable)
{ {
newSqliteTable->setSqliteDatabase(this); newSqliteTable->setSqliteDatabase(this);
sqliteTables.append(newSqliteTable); m_sqliteTables.append(newSqliteTable);
} }
const QVector<SqliteTable *> &SqliteDatabase::tables() const const QVector<SqliteTable *> &SqliteDatabase::tables() const
{ {
return sqliteTables; return m_sqliteTables;
} }
void SqliteDatabase::setDatabaseFilePath(const QString &databaseFilePath) void SqliteDatabase::setDatabaseFilePath(const QString &databaseFilePath)
{ {
databaseFilePath_ = databaseFilePath; m_databaseFilePath = databaseFilePath;
} }
const QString &SqliteDatabase::databaseFilePath() const const QString &SqliteDatabase::databaseFilePath() const
{ {
return databaseFilePath_; return m_databaseFilePath;
} }
void SqliteDatabase::setJournalMode(JournalMode journalMode) void SqliteDatabase::setJournalMode(JournalMode journalMode)
{ {
journalMode_ = journalMode; m_journalMode = journalMode;
} }
JournalMode SqliteDatabase::journalMode() const JournalMode SqliteDatabase::journalMode() const
{ {
return journalMode_; return m_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();
} }
void SqliteDatabase::initializeTables() void SqliteDatabase::initializeTables()
@@ -132,10 +95,4 @@ void SqliteDatabase::initializeTables()
table->initialize(); table->initialize();
} }
void SqliteDatabase::shutdownTables() } // namespace Sqlite
{
for (SqliteTable *table: tables())
table->shutdown();
}

View File

@@ -25,18 +25,18 @@
#pragma once #pragma once
#include "sqlitedatabaseconnectionproxy.h" #include "sqlitedatabasebackend.h"
#include "sqliteglobal.h" #include "sqliteglobal.h"
#include <QString> #include <QString>
#include <QVector> #include <QVector>
namespace Sqlite {
class SqliteTable; class SqliteTable;
class SQLITE_EXPORT SqliteDatabase : public QObject class SQLITE_EXPORT SqliteDatabase
{ {
Q_OBJECT
public: public:
SqliteDatabase(); SqliteDatabase();
~SqliteDatabase(); ~SqliteDatabase();
@@ -55,25 +55,16 @@ public:
void setJournalMode(JournalMode journalMode); void setJournalMode(JournalMode journalMode);
JournalMode journalMode() const; JournalMode journalMode() const;
QThread *writeWorkerThread() const;
QThread *readWorkerThread() const;
signals:
void databaseIsOpened();
void databaseIsClosed();
private: private:
void handleReadDatabaseConnectionIsOpened();
void handleWriteDatabaseConnectionIsOpened();
void handleReadDatabaseConnectionIsClosed();
void handleWriteDatabaseConnectionIsClosed();
void initializeTables(); void initializeTables();
void shutdownTables();
private: private:
SqliteDatabaseConnectionProxy readDatabaseConnection; SqliteDatabaseBackend m_sqliteDatabaseBackEnd;
SqliteDatabaseConnectionProxy writeDatabaseConnection; QVector<SqliteTable*> m_sqliteTables;
QVector<SqliteTable*> sqliteTables; QString m_databaseFilePath;
QString databaseFilePath_; JournalMode m_journalMode;
JournalMode journalMode_; bool m_isOpen = false;
}; };
} // namespace Sqlite

View File

@@ -46,11 +46,13 @@
#define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray) #define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray)
namespace Sqlite {
QTC_THREAD_LOCAL SqliteDatabaseBackend *sqliteDatabaseBackend = nullptr; QTC_THREAD_LOCAL SqliteDatabaseBackend *sqliteDatabaseBackend = nullptr;
SqliteDatabaseBackend::SqliteDatabaseBackend() SqliteDatabaseBackend::SqliteDatabaseBackend()
: databaseHandle(nullptr), : m_databaseHandle(nullptr),
cachedTextEncoding(Utf8) m_cachedTextEncoding(Utf8)
{ {
sqliteDatabaseBackend = this; sqliteDatabaseBackend = this;
} }
@@ -108,7 +110,7 @@ void SqliteDatabaseBackend::open(const QString &databaseFilePath)
QByteArray databaseUtf8Path = databaseFilePath.toUtf8(); QByteArray databaseUtf8Path = databaseFilePath.toUtf8();
int resultCode = sqlite3_open_v2(databaseUtf8Path.data(), int resultCode = sqlite3_open_v2(databaseUtf8Path.data(),
&databaseHandle, &m_databaseHandle,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
NULL); NULL);
@@ -123,7 +125,7 @@ sqlite3 *SqliteDatabaseBackend::sqliteDatabaseHandle()
{ {
checkDatabaseBackendIsNotNull(); checkDatabaseBackendIsNotNull();
checkDatabaseHandleIsNotNull(); checkDatabaseHandleIsNotNull();
return threadLocalInstance()->databaseHandle; return threadLocalInstance()->m_databaseHandle;
} }
void SqliteDatabaseBackend::setPragmaValue(const Utf8String &pragmaKey, const Utf8String &newPragmaValue) void SqliteDatabaseBackend::setPragmaValue(const Utf8String &pragmaKey, const Utf8String &newPragmaValue)
@@ -157,7 +159,7 @@ void SqliteDatabaseBackend::setTextEncoding(TextEncoding textEncoding)
TextEncoding SqliteDatabaseBackend::textEncoding() TextEncoding SqliteDatabaseBackend::textEncoding()
{ {
return cachedTextEncoding; return m_cachedTextEncoding;
} }
@@ -181,11 +183,11 @@ void SqliteDatabaseBackend::close()
{ {
checkForOpenDatabaseWhichCanBeClosed(); checkForOpenDatabaseWhichCanBeClosed();
int resultCode = sqlite3_close(databaseHandle); int resultCode = sqlite3_close(m_databaseHandle);
checkDatabaseClosing(resultCode); checkDatabaseClosing(resultCode);
databaseHandle = nullptr; m_databaseHandle = nullptr;
} }
@@ -197,14 +199,14 @@ SqliteDatabaseBackend *SqliteDatabaseBackend::threadLocalInstance()
bool SqliteDatabaseBackend::databaseIsOpen() const bool SqliteDatabaseBackend::databaseIsOpen() const
{ {
return databaseHandle != nullptr; return m_databaseHandle != nullptr;
} }
void SqliteDatabaseBackend::closeWithoutException() void SqliteDatabaseBackend::closeWithoutException()
{ {
if (databaseHandle) { if (m_databaseHandle) {
int resultCode = sqlite3_close_v2(databaseHandle); int resultCode = sqlite3_close_v2(m_databaseHandle);
databaseHandle = nullptr; m_databaseHandle = nullptr;
if (resultCode != SQLITE_OK) if (resultCode != SQLITE_OK)
qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!"; qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!";
} }
@@ -235,12 +237,12 @@ int SqliteDatabaseBackend::busyHandlerCallback(void *, int counter)
void SqliteDatabaseBackend::cacheTextEncoding() void SqliteDatabaseBackend::cacheTextEncoding()
{ {
cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding"))); m_cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding")));
} }
void SqliteDatabaseBackend::checkForOpenDatabaseWhichCanBeClosed() void SqliteDatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
{ {
if (databaseHandle == nullptr) if (m_databaseHandle == nullptr)
throwException("SqliteDatabaseBackend::close: database is not open so it can not be closed."); 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() void SqliteDatabaseBackend::checkDatabaseHandleIsNotNull()
{ {
if (sqliteDatabaseBackend->databaseHandle == nullptr) if (sqliteDatabaseBackend->m_databaseHandle == nullptr)
throwException("SqliteDatabaseBackend: database is not open!"); throwException("SqliteDatabaseBackend: database is not open!");
} }
@@ -383,8 +385,10 @@ TextEncoding SqliteDatabaseBackend::pragmaToTextEncoding(const Utf8String &pragm
void SqliteDatabaseBackend::throwException(const char *whatHasHappens) void SqliteDatabaseBackend::throwException(const char *whatHasHappens)
{ {
if (sqliteDatabaseBackend && sqliteDatabaseBackend->databaseHandle) if (sqliteDatabaseBackend && sqliteDatabaseBackend->m_databaseHandle)
throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->databaseHandle)); throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->m_databaseHandle));
else else
throw SqliteException(whatHasHappens); throw SqliteException(whatHasHappens);
} }
} // namespace Sqlite

View File

@@ -33,6 +33,8 @@
struct sqlite3; struct sqlite3;
namespace Sqlite {
class SQLITE_EXPORT SqliteDatabaseBackend class SQLITE_EXPORT SqliteDatabaseBackend
{ {
public: public:
@@ -102,7 +104,9 @@ protected:
Q_NORETURN static void throwException(const char *whatHasHappens); Q_NORETURN static void throwException(const char *whatHasHappens);
private: private:
sqlite3 *databaseHandle; sqlite3 *m_databaseHandle;
TextEncoding cachedTextEncoding; TextEncoding m_cachedTextEncoding;
}; };
} // namespace Sqlite

View File

@@ -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
}

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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;
};

View File

@@ -27,17 +27,20 @@
#include <QDebug> #include <QDebug>
namespace Sqlite {
SqliteException::SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage) SqliteException::SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage)
: whatErrorHasHappen(whatErrorHasHappen), : m_whatErrorHasHappen(whatErrorHasHappen),
sqliteErrorMessage_(sqliteErrorMessage) m_sqliteErrorMessage(sqliteErrorMessage)
{ {
} }
void SqliteException::printWarning() const void SqliteException::printWarning() const
{ {
if (!sqliteErrorMessage_.isEmpty()) if (!m_sqliteErrorMessage.isEmpty())
qWarning() << whatErrorHasHappen << sqliteErrorMessage_; qWarning() << m_whatErrorHasHappen << m_sqliteErrorMessage;
else else
qWarning() << whatErrorHasHappen; qWarning() << m_whatErrorHasHappen;
} }
} // namespace Sqlite

View File

@@ -29,14 +29,18 @@
#include <QByteArray> #include <QByteArray>
namespace Sqlite {
class SQLITE_EXPORT SqliteException class SQLITE_EXPORT SqliteException
{ {
public: public:
SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage = 0); SqliteException(const char *m_whatErrorHasHappen, const char *sqliteErrorMessage = 0);
void printWarning() const; void printWarning() const;
private: private:
const char *whatErrorHasHappen; const char *m_whatErrorHasHappen;
QByteArray sqliteErrorMessage_; QByteArray m_sqliteErrorMessage;
}; };
} // namespace Sqlite

View File

@@ -25,15 +25,8 @@
#include "sqliteglobal.h" #include "sqliteglobal.h"
#include "createtablecommand.h"
namespace Sqlite { namespace Sqlite {
void registerTypes()
{
Internal::CreateTableCommand::registerType();
qRegisterMetaType<JournalMode>("JournalMode");
}
} }

View File

@@ -27,6 +27,8 @@
#include "sqlite3.h" #include "sqlite3.h"
namespace Sqlite {
SqliteReadStatement::SqliteReadStatement(const Utf8String &sqlStatementUtf8) SqliteReadStatement::SqliteReadStatement(const Utf8String &sqlStatementUtf8)
: SqliteStatement(sqlStatementUtf8) : SqliteStatement(sqlStatementUtf8)
{ {
@@ -38,3 +40,5 @@ void SqliteReadStatement::checkIsReadOnlyStatement()
if (!isReadOnlyStatement()) if (!isReadOnlyStatement())
throwException("SqliteStatement::SqliteReadStatement: is not read only statement!"); throwException("SqliteStatement::SqliteReadStatement: is not read only statement!");
} }
} // namespace Sqlite

View File

@@ -27,6 +27,8 @@
#include "sqlitestatement.h" #include "sqlitestatement.h"
namespace Sqlite {
class SQLITE_EXPORT SqliteReadStatement final : private SqliteStatement class SQLITE_EXPORT SqliteReadStatement final : private SqliteStatement
{ {
public: public:
@@ -49,3 +51,5 @@ public:
protected: protected:
void checkIsReadOnlyStatement(); void checkIsReadOnlyStatement();
}; };
} // namespace Sqlite

View File

@@ -25,8 +25,11 @@
#include "sqlitereadwritestatement.h" #include "sqlitereadwritestatement.h"
namespace Sqlite {
SqliteReadWriteStatement::SqliteReadWriteStatement(const Utf8String &sqlStatementUft8) SqliteReadWriteStatement::SqliteReadWriteStatement(const Utf8String &sqlStatementUft8)
: SqliteStatement(sqlStatementUft8) : SqliteStatement(sqlStatementUft8)
{ {
} }
} // namespace Sqlite

View File

@@ -27,6 +27,8 @@
#include "sqlitestatement.h" #include "sqlitestatement.h"
namespace Sqlite {
class SQLITE_EXPORT SqliteReadWriteStatement final : private SqliteStatement class SQLITE_EXPORT SqliteReadWriteStatement final : private SqliteStatement
{ {
public: public:
@@ -48,3 +50,5 @@ public:
using SqliteStatement::toValue; using SqliteStatement::toValue;
using SqliteStatement::execute; using SqliteStatement::execute;
}; };
} // namespace Sqlite

View File

@@ -39,11 +39,13 @@
# pragma GCC diagnostic ignored "-Wignored-qualifiers" # pragma GCC diagnostic ignored "-Wignored-qualifiers"
#endif #endif
namespace Sqlite {
SqliteStatement::SqliteStatement(const Utf8String &sqlStatementUtf8) SqliteStatement::SqliteStatement(const Utf8String &sqlStatementUtf8)
: compiledStatement(nullptr, deleteCompiledStatement), : m_compiledStatement(nullptr, deleteCompiledStatement),
bindingParameterCount(0), m_bindingParameterCount(0),
columnCount_(0), m_columnCount(0),
isReadyToFetchValues(false) m_isReadyToFetchValues(false)
{ {
prepare(sqlStatementUtf8); prepare(sqlStatementUtf8);
setBindingParameterCount(); setBindingParameterCount();
@@ -108,11 +110,11 @@ void SqliteStatement::waitForUnlockNotify() const
void SqliteStatement::reset() const void SqliteStatement::reset() const
{ {
int resultCode = sqlite3_reset(compiledStatement.get()); int resultCode = sqlite3_reset(m_compiledStatement.get());
if (resultCode != SQLITE_OK) if (resultCode != SQLITE_OK)
throwException("SqliteStatement::reset: can't reset statement!"); throwException("SqliteStatement::reset: can't reset statement!");
isReadyToFetchValues = false; m_isReadyToFetchValues = false;
} }
bool SqliteStatement::next() const bool SqliteStatement::next() const
@@ -120,10 +122,10 @@ bool SqliteStatement::next() const
int resultCode; int resultCode;
do { do {
resultCode = sqlite3_step(compiledStatement.get()); resultCode = sqlite3_step(m_compiledStatement.get());
if (resultCode == SQLITE_LOCKED) { if (resultCode == SQLITE_LOCKED) {
waitForUnlockNotify(); waitForUnlockNotify();
sqlite3_reset(compiledStatement.get()); sqlite3_reset(m_compiledStatement.get());
} }
} while (resultCode == SQLITE_LOCKED); } while (resultCode == SQLITE_LOCKED);
@@ -154,7 +156,7 @@ void SqliteStatement::writeUnchecked(const RowDictionary &rowDictionary)
int SqliteStatement::columnCount() const int SqliteStatement::columnCount() const
{ {
return columnCount_; return m_columnCount;
} }
Utf8StringVector SqliteStatement::columnNames() const Utf8StringVector SqliteStatement::columnNames() const
@@ -163,28 +165,28 @@ Utf8StringVector SqliteStatement::columnNames() const
int columnCount = SqliteStatement::columnCount(); int columnCount = SqliteStatement::columnCount();
columnNames.reserve(columnCount); columnNames.reserve(columnCount);
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) 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; return columnNames;
} }
void SqliteStatement::bind(int index, int value) 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) if (resultCode != SQLITE_OK)
throwException("SqliteStatement::bind: cant' bind 32 bit integer!"); throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
} }
void SqliteStatement::bind(int index, qint64 value) 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) if (resultCode != SQLITE_OK)
throwException("SqliteStatement::bind: cant' bind 64 bit integer!"); throwException("SqliteStatement::bind: cant' bind 64 bit integer!");
} }
void SqliteStatement::bind(int index, double value) 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) if (resultCode != SQLITE_OK)
throwException("SqliteStatement::bind: cant' bind double!"); throwException("SqliteStatement::bind: cant' bind double!");
} }
@@ -194,9 +196,9 @@ void SqliteStatement::bind(int index, const QString &text)
int resultCode; int resultCode;
if (databaseTextEncoding() == Utf8) { if (databaseTextEncoding() == Utf8) {
QByteArray textUtf8 = text.toUtf8(); 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 { } 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) if (resultCode != SQLITE_OK)
@@ -205,7 +207,7 @@ void SqliteStatement::bind(int index, const QString &text)
void SqliteStatement::bind(int index, const QByteArray &blob) 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) void SqliteStatement::bind(int index, const QVariant &value)
@@ -232,7 +234,7 @@ void SqliteStatement::bind(int index, const QVariant &value)
bind(index, value.toByteArray()); bind(index, value.toByteArray());
break; break;
default: 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) 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) void SqliteStatement::bind(const RowDictionary &rowDictionary)
@@ -261,7 +263,7 @@ void SqliteStatement::bind(const RowDictionary &rowDictionary)
checkBindingValueMapIsEmpty(rowDictionary); checkBindingValueMapIsEmpty(rowDictionary);
int columnIndex = 1; int columnIndex = 1;
foreach (const Utf8String &columnName, bindingColumnNames_) { foreach (const Utf8String &columnName, m_bindingColumnNames) {
checkParameterCanBeBound(rowDictionary, columnName); checkParameterCanBeBound(rowDictionary, columnName);
QVariant value = rowDictionary.value(columnName); QVariant value = rowDictionary.value(columnName);
bind(columnIndex, value); bind(columnIndex, value);
@@ -274,7 +276,7 @@ void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
checkBindingValueMapIsEmpty(rowDictionary); checkBindingValueMapIsEmpty(rowDictionary);
int columnIndex = 1; int columnIndex = 1;
foreach (const Utf8String &columnName, bindingColumnNames_) { foreach (const Utf8String &columnName, m_bindingColumnNames) {
if (rowDictionary.contains(columnName)) { if (rowDictionary.contains(columnName)) {
QVariant value = rowDictionary.value(columnName); QVariant value = rowDictionary.value(columnName);
bind(columnIndex, value); bind(columnIndex, value);
@@ -285,12 +287,12 @@ void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
void SqliteStatement::setBindingColumnNames(const Utf8StringVector &bindingColumnNames) void SqliteStatement::setBindingColumnNames(const Utf8StringVector &bindingColumnNames)
{ {
bindingColumnNames_ = bindingColumnNames; m_bindingColumnNames = bindingColumnNames;
} }
const Utf8StringVector &SqliteStatement::bindingColumnNames() const const Utf8StringVector &SqliteStatement::bindingColumnNames() const
{ {
return bindingColumnNames_; return m_bindingColumnNames;
} }
void SqliteStatement::execute(const Utf8String &sqlStatementUtf8) void SqliteStatement::execute(const Utf8String &sqlStatementUtf8)
@@ -306,7 +308,7 @@ void SqliteStatement::prepare(const Utf8String &sqlStatementUtf8)
do { do {
sqlite3_stmt *sqliteStatement = nullptr; sqlite3_stmt *sqliteStatement = nullptr;
resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(), sqlStatementUtf8.constData(), sqlStatementUtf8.byteSize(), &sqliteStatement, nullptr); resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(), sqlStatementUtf8.constData(), sqlStatementUtf8.byteSize(), &sqliteStatement, nullptr);
compiledStatement.reset(sqliteStatement); m_compiledStatement.reset(sqliteStatement);
if (resultCode == SQLITE_LOCKED) if (resultCode == SQLITE_LOCKED)
waitForUnlockNotify(); waitForUnlockNotify();
@@ -362,41 +364,41 @@ void SqliteStatement::checkForPrepareError(int resultCode) const
void SqliteStatement::setIfIsReadyToFetchValues(int resultCode) const void SqliteStatement::setIfIsReadyToFetchValues(int resultCode) const
{ {
if (resultCode == SQLITE_ROW) if (resultCode == SQLITE_ROW)
isReadyToFetchValues = true; m_isReadyToFetchValues = true;
else else
isReadyToFetchValues = false; m_isReadyToFetchValues = false;
} }
void SqliteStatement::checkIfIsReadyToFetchValues() const void SqliteStatement::checkIfIsReadyToFetchValues() const
{ {
if (!isReadyToFetchValues) if (!m_isReadyToFetchValues)
throwException("SqliteStatement::value: there are no values to fetch!"); throwException("SqliteStatement::value: there are no values to fetch!");
} }
void SqliteStatement::checkColumnsAreValid(const QVector<int> &columns) const void SqliteStatement::checkColumnsAreValid(const QVector<int> &columns) const
{ {
foreach (int column, columns) { foreach (int column, columns) {
if (column < 0 || column >= columnCount_) if (column < 0 || column >= m_columnCount)
throwException("SqliteStatement::values: column index out of bound!"); throwException("SqliteStatement::values: column index out of bound!");
} }
} }
void SqliteStatement::checkColumnIsValid(int column) const 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!"); throwException("SqliteStatement::values: column index out of bound!");
} }
void SqliteStatement::checkBindingIndex(int index) const 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!"); throwException("SqliteStatement::bind: binding index is out of bound!");
} }
void SqliteStatement::checkBindingName(int index) const 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!"); throwException("SqliteStatement::bind: binding name are not exists in this statement!");
} }
@@ -408,7 +410,7 @@ void SqliteStatement::checkParameterCanBeBound(const RowDictionary &rowDictionar
void SqliteStatement::setBindingParameterCount() void SqliteStatement::setBindingParameterCount()
{ {
bindingParameterCount = sqlite3_bind_parameter_count(compiledStatement.get()); m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get());
} }
Utf8String chopFirstLetter(const char *rawBindingName) Utf8String chopFirstLetter(const char *rawBindingName)
@@ -421,15 +423,15 @@ Utf8String chopFirstLetter(const char *rawBindingName)
void SqliteStatement::setBindingColumnNamesFromStatement() void SqliteStatement::setBindingColumnNamesFromStatement()
{ {
for (int index = 1; index <= bindingParameterCount; index++) { for (int index = 1; index <= m_bindingParameterCount; index++) {
Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(compiledStatement.get(), index)); Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(m_compiledStatement.get(), index));
bindingColumnNames_.append(bindingName); m_bindingColumnNames.append(bindingName);
} }
} }
void SqliteStatement::setColumnCount() void SqliteStatement::setColumnCount()
{ {
columnCount_ = sqlite3_column_count(compiledStatement.get()); m_columnCount = sqlite3_column_count(m_compiledStatement.get());
} }
void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const
@@ -440,7 +442,7 @@ void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictio
bool SqliteStatement::isReadOnlyStatement() const bool SqliteStatement::isReadOnlyStatement() const
{ {
return sqlite3_stmt_readonly(compiledStatement.get()); return sqlite3_stmt_readonly(m_compiledStatement.get());
} }
void SqliteStatement::throwException(const char *whatHasHappened) void SqliteStatement::throwException(const char *whatHasHappened)
@@ -450,7 +452,7 @@ void SqliteStatement::throwException(const char *whatHasHappened)
QString SqliteStatement::columnName(int column) const 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) static bool columnIsBlob(sqlite3_stmt *sqlStatment, int column)
@@ -521,7 +523,7 @@ int SqliteStatement::value<int>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return sqlite3_column_int(compiledStatement.get(), column); return sqlite3_column_int(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -529,7 +531,7 @@ qint64 SqliteStatement::value<qint64>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return sqlite3_column_int64(compiledStatement.get(), column); return sqlite3_column_int64(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -537,7 +539,7 @@ double SqliteStatement::value<double>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return sqlite3_column_double(compiledStatement.get(), column); return sqlite3_column_double(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -545,7 +547,7 @@ QByteArray SqliteStatement::value<QByteArray>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return byteArrayForColumn(compiledStatement.get(), column); return byteArrayForColumn(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -553,7 +555,7 @@ Utf8String SqliteStatement::value<Utf8String>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return convertedToUtf8StringForColumn(compiledStatement.get(), column); return convertedToUtf8StringForColumn(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -561,7 +563,7 @@ QString SqliteStatement::value<QString>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return textForColumn(compiledStatement.get(), column); return textForColumn(m_compiledStatement.get(), column);
} }
template<> template<>
@@ -569,7 +571,7 @@ QVariant SqliteStatement::value<QVariant>(int column) const
{ {
checkIfIsReadyToFetchValues(); checkIfIsReadyToFetchValues();
checkColumnIsValid(column); checkColumnIsValid(column);
return variantForColumn(compiledStatement.get(), column); return variantForColumn(m_compiledStatement.get(), column);
} }
template <typename ContainerType> template <typename ContainerType>
@@ -592,7 +594,7 @@ QMap<QString, QVariant> SqliteStatement::rowColumnValueMap() const
if (next()) { if (next()) {
for (int column = 0; column < columnCount(); column++) 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; return values;
@@ -605,7 +607,7 @@ QMap<QString, QVariant> SqliteStatement::twoColumnValueMap() const
reset(); reset();
while (next()) 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; 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 Utf8String SqliteStatement::toValue<Utf8String>(const Utf8String &sqlStatementUtf8);
template SQLITE_EXPORT QVariant SqliteStatement::toValue<QVariant>(const Utf8String &sqlStatementUtf8); template SQLITE_EXPORT QVariant SqliteStatement::toValue<QVariant>(const Utf8String &sqlStatementUtf8);
} // namespace Sqlite

View File

@@ -40,12 +40,14 @@
struct sqlite3_stmt; struct sqlite3_stmt;
struct sqlite3; struct sqlite3;
namespace Sqlite {
class SQLITE_EXPORT SqliteStatement class SQLITE_EXPORT SqliteStatement
{ {
protected: protected:
explicit SqliteStatement(const Utf8String &sqlStatementUtf8); explicit SqliteStatement(const Utf8String &sqlStatementUtf8);
static void deleteCompiledStatement(sqlite3_stmt *compiledStatement); static void deleteCompiledStatement(sqlite3_stmt *m_compiledStatement);
bool next() const; bool next() const;
void step() const; void step() const;
@@ -120,9 +122,11 @@ protected:
QString columnName(int column) const; QString columnName(int column) const;
private: private:
std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> compiledStatement; std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement;
Utf8StringVector bindingColumnNames_; Utf8StringVector m_bindingColumnNames;
int bindingParameterCount; int m_bindingParameterCount;
int columnCount_; int m_columnCount;
mutable bool isReadyToFetchValues; mutable bool m_isReadyToFetchValues;
}; };
} // namespace Sqlite

View File

@@ -27,88 +27,91 @@
#include "sqlitecolumn.h" #include "sqlitecolumn.h"
#include "sqlitedatabase.h" #include "sqlitedatabase.h"
#include "createtablesqlstatementbuilder.h"
#include "sqlitewritestatement.h"
#include "sqlitetransaction.h"
namespace Sqlite {
SqliteTable::SqliteTable() SqliteTable::SqliteTable()
: withoutRowId(false) : m_withoutRowId(false)
{ {
} }
SqliteTable::~SqliteTable() SqliteTable::~SqliteTable()
{ {
qDeleteAll(sqliteColumns); qDeleteAll(m_sqliteColumns);
} }
void SqliteTable::setName(const Utf8String &name) void SqliteTable::setName(const Utf8String &name)
{ {
tableName = name; m_tableName = name;
} }
const Utf8String &SqliteTable::name() const const Utf8String &SqliteTable::name() const
{ {
return tableName; return m_tableName;
} }
void SqliteTable::setUseWithoutRowId(bool useWithoutWorId) void SqliteTable::setUseWithoutRowId(bool useWithoutWorId)
{ {
withoutRowId = useWithoutWorId; m_withoutRowId = useWithoutWorId;
} }
bool SqliteTable::useWithoutRowId() const bool SqliteTable::useWithoutRowId() const
{ {
return withoutRowId; return m_withoutRowId;
} }
void SqliteTable::addColumn(SqliteColumn *newColumn) void SqliteTable::addColumn(SqliteColumn *newColumn)
{ {
sqliteColumns.append(newColumn); m_sqliteColumns.append(newColumn);
} }
const QVector<SqliteColumn *> &SqliteTable::columns() const const QVector<SqliteColumn *> &SqliteTable::columns() const
{ {
return sqliteColumns; return m_sqliteColumns;
} }
void SqliteTable::setSqliteDatabase(SqliteDatabase *database) void SqliteTable::setSqliteDatabase(SqliteDatabase *database)
{ {
sqliteDatabase = database; m_sqliteDatabase = database;
writeWorker.moveWorkerToThread(sqliteDatabase->writeWorkerThread());
} }
void SqliteTable::initialize() 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 for (SqliteColumn *sqliteColumn : m_sqliteColumns)
{
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)
columnDefintions.append(sqliteColumn->columnDefintion()); columnDefintions.append(sqliteColumn->columnDefintion());
return columnDefintions; return columnDefintions;
} }
} // namespace Sqlite

View File

@@ -26,21 +26,19 @@
#pragma once #pragma once
#include "sqliteglobal.h" #include "sqliteglobal.h"
#include "tablewriteworkerproxy.h" #include "columndefinition.h"
#include "utf8string.h" #include "utf8string.h"
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
namespace Sqlite {
class SqliteColumn; class SqliteColumn;
class SqliteDatabase; class SqliteDatabase;
class SQLITE_EXPORT SqliteTable : public QObject class SQLITE_EXPORT SqliteTable
{ {
Q_OBJECT
friend class Internal::TableWriteWorkerProxy;
public: public:
SqliteTable(); SqliteTable();
~SqliteTable(); ~SqliteTable();
@@ -57,20 +55,19 @@ public:
void setSqliteDatabase(SqliteDatabase *database); void setSqliteDatabase(SqliteDatabase *database);
void initialize(); void initialize();
void shutdown();
signals: bool isReady() const;
void tableIsReady();
private: private:
void handleTableCreated(); QVector<ColumnDefinition> createColumnDefintions() const;
Internal::CreateTableCommand createTableCommand() const;
QVector<Internal::ColumnDefinition> createColumnDefintions() const;
private: private:
Internal::TableWriteWorkerProxy writeWorker; QVector<SqliteColumn*> m_sqliteColumns;
QVector<SqliteColumn*> sqliteColumns; Utf8String m_tableName;
Utf8String tableName; SqliteDatabase *m_sqliteDatabase;
SqliteDatabase *sqliteDatabase; bool m_withoutRowId;
bool withoutRowId;
bool m_isReady = false;
}; };
} // namespace Sqlite

View File

@@ -27,16 +27,18 @@
#include "sqlitewritestatement.h" #include "sqlitewritestatement.h"
namespace Sqlite {
SqliteAbstractTransaction::~SqliteAbstractTransaction() SqliteAbstractTransaction::~SqliteAbstractTransaction()
{ {
if (!isAlreadyCommited) if (!m_isAlreadyCommited)
SqliteWriteStatement::execute(Utf8StringLiteral("ROLLBACK")); SqliteWriteStatement::execute(Utf8StringLiteral("ROLLBACK"));
} }
void SqliteAbstractTransaction::commit() void SqliteAbstractTransaction::commit()
{ {
SqliteWriteStatement::execute(Utf8StringLiteral("COMMIT")); SqliteWriteStatement::execute(Utf8StringLiteral("COMMIT"));
isAlreadyCommited = true; m_isAlreadyCommited = true;
} }
SqliteTransaction::SqliteTransaction() SqliteTransaction::SqliteTransaction()
@@ -53,3 +55,5 @@ SqliteExclusiveTransaction::SqliteExclusiveTransaction()
{ {
SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN EXCLUSIVE")); SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN EXCLUSIVE"));
} }
} // namespace Sqlite

View File

@@ -27,6 +27,8 @@
#include "sqliteglobal.h" #include "sqliteglobal.h"
namespace Sqlite {
class SQLITE_EXPORT SqliteAbstractTransaction class SQLITE_EXPORT SqliteAbstractTransaction
{ {
public: public:
@@ -35,7 +37,7 @@ public:
void commit(); void commit();
private: private:
bool isAlreadyCommited = false; bool m_isAlreadyCommited = false;
}; };
@@ -59,3 +61,5 @@ public:
SqliteExclusiveTransaction(); SqliteExclusiveTransaction();
}; };
} // namespace Sqlite

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -25,6 +25,8 @@
#include "sqlitewritestatement.h" #include "sqlitewritestatement.h"
namespace Sqlite {
SqliteWriteStatement::SqliteWriteStatement(const Utf8String &sqlStatementUtf8) SqliteWriteStatement::SqliteWriteStatement(const Utf8String &sqlStatementUtf8)
: SqliteStatement(sqlStatementUtf8) : SqliteStatement(sqlStatementUtf8)
{ {
@@ -36,3 +38,5 @@ void SqliteWriteStatement::checkIsWritableStatement()
if (isReadOnlyStatement()) if (isReadOnlyStatement())
throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!"); throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
} }
} // namespace Sqlite

View File

@@ -27,6 +27,8 @@
#include "sqlitestatement.h" #include "sqlitestatement.h"
namespace Sqlite {
class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement
{ {
public: public:
@@ -46,3 +48,5 @@ public:
protected: protected:
void checkIsWritableStatement(); void checkIsWritableStatement();
}; };
} // namespace Sqlite

View File

@@ -30,8 +30,10 @@
#include <algorithm> #include <algorithm>
namespace Sqlite {
SqlStatementBuilder::SqlStatementBuilder(const Utf8String &sqlTemplate) SqlStatementBuilder::SqlStatementBuilder(const Utf8String &sqlTemplate)
: sqlTemplate(sqlTemplate) : m_sqlTemplate(sqlTemplate)
{ {
} }
@@ -99,8 +101,8 @@ void SqlStatementBuilder::bindWithUpdateTemplateNames(const Utf8String &name, co
void SqlStatementBuilder::clear() void SqlStatementBuilder::clear()
{ {
bindings.clear(); m_bindings.clear();
sqlStatement_.clear(); m_sqlStatement_.clear();
} }
const Utf8String SqlStatementBuilder::insertTemplateParameters(const Utf8StringVector &columns) const Utf8String SqlStatementBuilder::insertTemplateParameters(const Utf8StringVector &columns)
@@ -130,7 +132,7 @@ const Utf8String SqlStatementBuilder::updateTemplateNames(const Utf8StringVector
void SqlStatementBuilder::sortBindings() const 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(); 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()) if (!isBuild())
generateSqlStatement(); generateSqlStatement();
return sqlStatement_; return m_sqlStatement_;
} }
bool SqlStatementBuilder::isBuild() const bool SqlStatementBuilder::isBuild() const
{ {
return sqlStatement_.hasContent(); return m_sqlStatement_.hasContent();
} }
Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType) Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
@@ -164,15 +166,15 @@ Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
void SqlStatementBuilder::generateSqlStatement() const void SqlStatementBuilder::generateSqlStatement() const
{ {
sqlStatement_ = sqlTemplate; m_sqlStatement_ = m_sqlTemplate;
sortBindings(); sortBindings();
auto bindingIterator = bindings.cbegin(); auto bindingIterator = m_bindings.cbegin();
while (bindingIterator != bindings.cend()) { while (bindingIterator != m_bindings.cend()) {
const Utf8String &placeHolderToken = bindingIterator->first; const Utf8String &placeHolderToken = bindingIterator->first;
const Utf8String &replacementToken = bindingIterator->second; const Utf8String &replacementToken = bindingIterator->second;
sqlStatement_.replace(placeHolderToken, replacementToken); m_sqlStatement_.replace(placeHolderToken, replacementToken);
++bindingIterator; ++bindingIterator;
} }
@@ -182,52 +184,54 @@ void SqlStatementBuilder::generateSqlStatement() const
void SqlStatementBuilder::changeBinding(const Utf8String &name, const Utf8String &text) 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; return binding.first == name;
}); });
if (findBindingIterator == bindings.end()) if (findBindingIterator == m_bindings.end())
bindings.push_back(std::make_pair(name, text)); m_bindings.push_back(std::make_pair(name, text));
else else
findBindingIterator->second = text; findBindingIterator->second = text;
} }
void SqlStatementBuilder::clearSqlStatement() void SqlStatementBuilder::clearSqlStatement()
{ {
sqlStatement_.clear(); m_sqlStatement_.clear();
} }
void SqlStatementBuilder::checkIfPlaceHolderExists(const Utf8String &name) const 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()); throwException("SqlStatementBuilder::bind: placeholder name does not exists!", name.constData());
} }
void SqlStatementBuilder::checkIfNoPlaceHoldersAynmoreExists() const void SqlStatementBuilder::checkIfNoPlaceHoldersAynmoreExists() const
{ {
if (sqlStatement_.contains('$')) if (m_sqlStatement_.contains('$'))
throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", sqlTemplate.constData()); throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", m_sqlTemplate.constData());
} }
void SqlStatementBuilder::checkBindingTextIsNotEmpty(const Utf8String &text) const void SqlStatementBuilder::checkBindingTextIsNotEmpty(const Utf8String &text) const
{ {
if (text.isEmpty()) 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 void SqlStatementBuilder::checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const
{ {
if (textVector.isEmpty()) 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 void SqlStatementBuilder::checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const
{ {
if (integerVector.isEmpty()) 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) void SqlStatementBuilder::throwException(const char *whatHasHappened, const char *errorMessage)
{ {
throw SqlStatementBuilderException(whatHasHappened, errorMessage); throw SqlStatementBuilderException(whatHasHappened, errorMessage);
} }
} // namespace Sqlite

View File

@@ -30,11 +30,13 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace Sqlite {
class SQLITE_EXPORT SqlStatementBuilder class SQLITE_EXPORT SqlStatementBuilder
{ {
using BindingPair = std::pair<Utf8String, Utf8String>; using BindingPair = std::pair<Utf8String, Utf8String>;
public: public:
SqlStatementBuilder(const Utf8String &sqlTemplate); SqlStatementBuilder(const Utf8String &m_sqlTemplate);
void bindEmptyText(const Utf8String &name); void bindEmptyText(const Utf8String &name);
void bind(const Utf8String &name, const Utf8String &text); void bind(const Utf8String &name, const Utf8String &text);
@@ -72,7 +74,9 @@ protected:
Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage); Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage);
private: private:
Utf8String sqlTemplate; Utf8String m_sqlTemplate;
mutable Utf8String sqlStatement_; mutable Utf8String m_sqlStatement_;
mutable std::vector<BindingPair> bindings; mutable std::vector<BindingPair> m_bindings;
}; };
} // namespace Sqlite

View File

@@ -25,7 +25,11 @@
#include "sqlstatementbuilderexception.h" #include "sqlstatementbuilderexception.h"
namespace Sqlite {
SqlStatementBuilderException::SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage) SqlStatementBuilderException::SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage)
: SqliteException(whatErrorHasHappen, errorMessage) : SqliteException(whatErrorHasHappen, errorMessage)
{ {
} }
} // namespace Sqlite

View File

@@ -27,8 +27,12 @@
#include "sqliteexception.h" #include "sqliteexception.h"
namespace Sqlite {
class SQLITE_EXPORT SqlStatementBuilderException : public SqliteException class SQLITE_EXPORT SqlStatementBuilderException : public SqliteException
{ {
public: public:
SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage = 0); SqlStatementBuilderException(const char *m_whatErrorHasHappen, const char *errorMessage = 0);
}; };
} // namespace Sqlite

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -32,18 +32,21 @@
#include <utf8stringvector.h> #include <utf8stringvector.h>
namespace {
using Sqlite::ColumnDefinition;
using Sqlite::SqlStatementBuilderException;
class CreateTableSqlStatementBuilder : public ::testing::Test class CreateTableSqlStatementBuilder : public ::testing::Test
{ {
protected: protected:
void SetUp() override;
void bindValues(); void bindValues();
static const QVector<Internal::ColumnDefinition> createColumnDefintions(); static const QVector<ColumnDefinition> createColumnDefintions();
static const Internal::ColumnDefinition createColumnDefintion(const Utf8String &name, static const ColumnDefinition createColumnDefintion(const Utf8String &name,
ColumnType type, ColumnType type,
bool isPrimaryKey = false); bool isPrimaryKey = false);
protected:
Internal::CreateTableSqlStatementBuilder builder; Sqlite::CreateTableSqlStatementBuilder builder;
}; };
TEST_F(CreateTableSqlStatementBuilder, IsNotValidAfterCreation) 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)")); Utf8StringLiteral("CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)"));
} }
void CreateTableSqlStatementBuilder::SetUp()
{
builder = Internal::CreateTableSqlStatementBuilder();
}
void CreateTableSqlStatementBuilder::bindValues() void CreateTableSqlStatementBuilder::bindValues()
{ {
builder.clear(); builder.clear();
@@ -160,9 +158,9 @@ void CreateTableSqlStatementBuilder::bindValues()
builder.addColumnDefinition(Utf8StringLiteral("number"),ColumnType:: Numeric); 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("id"), ColumnType::Integer, true));
columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("name"), ColumnType::Text)); columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("name"), ColumnType::Text));
columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("number"), ColumnType::Numeric)); columnDefinitions.append(createColumnDefintion(Utf8StringLiteral("number"), ColumnType::Numeric));
@@ -170,9 +168,9 @@ const QVector<Internal::ColumnDefinition> CreateTableSqlStatementBuilder::create
return columnDefinitions; 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.setName(name);
columnDefinition.setType(type); columnDefinition.setType(type);
@@ -180,3 +178,5 @@ const Internal::ColumnDefinition CreateTableSqlStatementBuilder::createColumnDef
return columnDefinition; return columnDefinition;
} }
}

View File

@@ -29,12 +29,14 @@
namespace { namespace {
using Sqlite::ColumnDefinition;
class SqliteColumn : public ::testing::Test class SqliteColumn : public ::testing::Test
{ {
protected: protected:
void SetUp() override; void SetUp() override;
::SqliteColumn column; Sqlite::SqliteColumn column;
}; };
TEST_F(SqliteColumn, ChangeName) TEST_F(SqliteColumn, ChangeName)
@@ -72,7 +74,7 @@ TEST_F(SqliteColumn, GetColumnDefinition)
{ {
column.setName(Utf8StringLiteral("Claudia")); column.setName(Utf8StringLiteral("Claudia"));
Internal::ColumnDefinition columnDefintion = column.columnDefintion(); ColumnDefinition columnDefintion = column.columnDefintion();
ASSERT_THAT(columnDefintion.name(), Utf8StringLiteral("Claudia")); ASSERT_THAT(columnDefintion.name(), Utf8StringLiteral("Claudia"));
ASSERT_THAT(columnDefintion.type(), ColumnType::Numeric); ASSERT_THAT(columnDefintion.type(), ColumnType::Numeric);

View File

@@ -36,6 +36,10 @@
namespace { namespace {
using testing::Contains;
using Sqlite::SqliteTable;
class SqliteDatabase : public ::testing::Test class SqliteDatabase : public ::testing::Test
{ {
protected: protected:
@@ -44,7 +48,7 @@ protected:
SpyDummy spyDummy; SpyDummy spyDummy;
QString databaseFilePath = QStringLiteral(":memory:"); QString databaseFilePath = QStringLiteral(":memory:");
::SqliteDatabase database; Sqlite::SqliteDatabase database;
}; };
TEST_F(SqliteDatabase, SetDatabaseFilePath) TEST_F(SqliteDatabase, SetDatabaseFilePath)
@@ -62,20 +66,16 @@ TEST_F(SqliteDatabase, SetJournalMode)
TEST_F(SqliteDatabase, OpenDatabase) TEST_F(SqliteDatabase, OpenDatabase)
{ {
database.close(); database.close();
QSignalSpy signalSpy(&spyDummy, &SpyDummy::databaseIsOpened);
database.open(); database.open();
ASSERT_TRUE(signalSpy.wait(100000));
ASSERT_TRUE(database.isOpen()); ASSERT_TRUE(database.isOpen());
} }
TEST_F(SqliteDatabase, CloseDatabase) TEST_F(SqliteDatabase, CloseDatabase)
{ {
QSignalSpy signalSpy(&spyDummy, &SpyDummy::databaseIsClosed);
database.close(); database.close();
ASSERT_TRUE(signalSpy.wait(100000));
ASSERT_FALSE(database.isOpen()); ASSERT_FALSE(database.isOpen());
} }
@@ -85,20 +85,19 @@ TEST_F(SqliteDatabase, AddTable)
database.addTable(sqliteTable); database.addTable(sqliteTable);
ASSERT_THAT(database.tables().first(), sqliteTable); ASSERT_THAT(database.tables(), Contains(sqliteTable));
} }
void SqliteDatabase::SetUp() void SqliteDatabase::SetUp()
{ {
QObject::connect(&database, &::SqliteDatabase::databaseIsOpened, &spyDummy, &SpyDummy::databaseIsOpened);
QObject::connect(&database, &::SqliteDatabase::databaseIsClosed, &spyDummy, &SpyDummy::databaseIsClosed);
database.setJournalMode(JournalMode::Memory); database.setJournalMode(JournalMode::Memory);
database.setDatabaseFilePath(databaseFilePath); database.setDatabaseFilePath(databaseFilePath);
database.open();
} }
void SqliteDatabase::TearDown() void SqliteDatabase::TearDown()
{ {
database.close(); if (database.isOpen())
database.close();
} }
} }

View File

@@ -33,6 +33,9 @@
namespace { namespace {
using Sqlite::SqliteException;
using Sqlite::SqliteWriteStatement;
class SqliteDatabaseBackend : public ::testing::Test class SqliteDatabaseBackend : public ::testing::Test
{ {
protected: protected:
@@ -40,7 +43,7 @@ protected:
void TearDown() override; void TearDown() override;
QString databaseFilePath = QDir::tempPath() + QStringLiteral("/SqliteDatabaseBackendTest.db"); QString databaseFilePath = QDir::tempPath() + QStringLiteral("/SqliteDatabaseBackendTest.db");
::SqliteDatabaseBackend databaseBackend; Sqlite::SqliteDatabaseBackend databaseBackend;
}; };
using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend; using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend;
@@ -53,6 +56,7 @@ TEST_F(SqliteDatabaseBackend, OpenAlreadyOpenDatabase)
TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase) TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase)
{ {
databaseBackend.close(); databaseBackend.close();
ASSERT_THROW(databaseBackend.close(), SqliteException); ASSERT_THROW(databaseBackend.close(), SqliteException);
} }

View File

@@ -39,6 +39,13 @@
#include <QVariant> #include <QVariant>
namespace { namespace {
using Sqlite::SqliteException;
using Sqlite::SqliteDatabaseBackend;
using Sqlite::SqliteReadStatement;
using Sqlite::SqliteReadWriteStatement;
using Sqlite::SqliteWriteStatement;
class SqliteStatement : public ::testing::Test class SqliteStatement : public ::testing::Test
{ {
protected: protected:

View File

@@ -36,6 +36,9 @@
namespace { namespace {
using Sqlite::SqliteColumn;
using Sqlite::SqliteDatabase;
class SqliteTable : public ::testing::Test class SqliteTable : public ::testing::Test
{ {
protected: protected:
@@ -45,8 +48,8 @@ protected:
SqliteColumn *addColumn(const Utf8String &columnName); SqliteColumn *addColumn(const Utf8String &columnName);
SpyDummy spyDummy; SpyDummy spyDummy;
SqliteDatabase *database = nullptr; SqliteDatabase database;
::SqliteTable *table = nullptr; Sqlite::SqliteTable *table = new Sqlite::SqliteTable;
Utf8String tableName = Utf8StringLiteral("testTable"); Utf8String tableName = Utf8StringLiteral("testTable");
}; };
@@ -74,31 +77,25 @@ TEST_F(SqliteTable, SetUseWithoutRowid)
TEST_F(SqliteTable, TableIsReadyAfterOpenDatabase) TEST_F(SqliteTable, TableIsReadyAfterOpenDatabase)
{ {
QSignalSpy signalSpy(&spyDummy, &SpyDummy::tableIsReady);
table->setName(tableName); table->setName(tableName);
addColumn(Utf8StringLiteral("name")); addColumn(Utf8StringLiteral("name"));
database->open(); database.open();
ASSERT_TRUE(signalSpy.wait(100000)); ASSERT_TRUE(table->isReady());
} }
void SqliteTable::SetUp() void SqliteTable::SetUp()
{ {
table = new ::SqliteTable; database.setJournalMode(JournalMode::Memory);
QObject::connect(table, &::SqliteTable::tableIsReady, &spyDummy, &SpyDummy::tableIsReady); database.setDatabaseFilePath( QStringLiteral(":memory:"));
database.addTable(table);
database = new SqliteDatabase;
database->setJournalMode(JournalMode::Memory);
database->setDatabaseFilePath( QStringLiteral(":memory:"));
database->addTable(table);
} }
void SqliteTable::TearDown() void SqliteTable::TearDown()
{ {
database->close(); if (database.isOpen())
delete database; database.close();
database = nullptr;
table = nullptr; table = nullptr;
} }

View File

@@ -33,6 +33,9 @@
using namespace ::testing; using namespace ::testing;
using Sqlite::SqlStatementBuilder;
using Sqlite::SqlStatementBuilderException;
TEST(SqlStatementBuilder, Bind) TEST(SqlStatementBuilder, Bind)
{ {
SqlStatementBuilder sqlStatementBuilder(Utf8StringLiteral("SELECT $columns FROM $table WHERE $column = 'foo' AND rowid=$row AND rowid IN ($rows)")); SqlStatementBuilder sqlStatementBuilder(Utf8StringLiteral("SELECT $columns FROM $table WHERE $column = 'foo' AND rowid=$row AND rowid IN ($rows)"));

View File

@@ -44,8 +44,6 @@ int main(int argc, char *argv[])
qputenv("TMPDIR", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8()); qputenv("TMPDIR", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8());
qputenv("TEMP", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8()); qputenv("TEMP", Utils::TemporaryDirectory::masterDirectoryPath().toUtf8());
Sqlite::registerTypes();
QCoreApplication application(argc, argv); QCoreApplication application(argc, argv);
QLoggingCategory::setFilterRules(QStringLiteral("*.info=false\n*.debug=false\n*.warning=true")); QLoggingCategory::setFilterRules(QStringLiteral("*.info=false\n*.debug=false\n*.warning=true"));