aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/sqlite
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/sqlite')
-rw-r--r--src/libs/sqlite/columndefinition.cpp78
-rw-r--r--src/libs/sqlite/columndefinition.h60
-rw-r--r--src/libs/sqlite/createtablecommand.cpp41
-rw-r--r--src/libs/sqlite/createtablecommand.h57
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.cpp131
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.h72
-rw-r--r--src/libs/sqlite/sqlite-lib.pri64
-rw-r--r--src/libs/sqlite/sqlite-source.pri53
-rw-r--r--src/libs/sqlite/sqlite.pro5
-rw-r--r--src/libs/sqlite/sqlite.qbs42
-rw-r--r--src/libs/sqlite/sqlite_dependencies.pri3
-rw-r--r--src/libs/sqlite/sqlitecolumn.cpp86
-rw-r--r--src/libs/sqlite/sqlitecolumn.h64
-rw-r--r--src/libs/sqlite/sqlitedatabase.cpp146
-rw-r--r--src/libs/sqlite/sqlitedatabase.h87
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.cpp397
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.h116
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnection.cpp100
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnection.h65
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp97
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnectionproxy.h71
-rw-r--r--src/libs/sqlite/sqliteexception.cpp48
-rw-r--r--src/libs/sqlite/sqliteexception.h50
-rw-r--r--src/libs/sqlite/sqliteglobal.cpp44
-rw-r--r--src/libs/sqlite/sqliteglobal.h96
-rw-r--r--src/libs/sqlite/sqlitereadstatement.cpp45
-rw-r--r--src/libs/sqlite/sqlitereadstatement.h59
-rw-r--r--src/libs/sqlite/sqlitereadwritestatement.cpp38
-rw-r--r--src/libs/sqlite/sqlitereadwritestatement.h58
-rw-r--r--src/libs/sqlite/sqlitestatement.cpp676
-rw-r--r--src/libs/sqlite/sqlitestatement.h138
-rw-r--r--src/libs/sqlite/sqlitetable.cpp119
-rw-r--r--src/libs/sqlite/sqlitetable.h84
-rw-r--r--src/libs/sqlite/sqlitetransaction.cpp61
-rw-r--r--src/libs/sqlite/sqlitetransaction.h70
-rw-r--r--src/libs/sqlite/sqliteworkerthread.cpp64
-rw-r--r--src/libs/sqlite/sqliteworkerthread.h57
-rw-r--r--src/libs/sqlite/sqlitewritestatement.cpp43
-rw-r--r--src/libs/sqlite/sqlitewritestatement.h56
-rw-r--r--src/libs/sqlite/sqlstatementbuilder.cpp238
-rw-r--r--src/libs/sqlite/sqlstatementbuilder.h86
-rw-r--r--src/libs/sqlite/sqlstatementbuilderexception.cpp36
-rw-r--r--src/libs/sqlite/sqlstatementbuilderexception.h42
-rw-r--r--src/libs/sqlite/tablewriteworker.cpp71
-rw-r--r--src/libs/sqlite/tablewriteworker.h56
-rw-r--r--src/libs/sqlite/tablewriteworkerproxy.cpp68
-rw-r--r--src/libs/sqlite/tablewriteworkerproxy.h71
-rw-r--r--src/libs/sqlite/utf8string.cpp255
-rw-r--r--src/libs/sqlite/utf8string.h142
-rw-r--r--src/libs/sqlite/utf8stringvector.cpp123
-rw-r--r--src/libs/sqlite/utf8stringvector.h79
51 files changed, 4908 insertions, 0 deletions
diff --git a/src/libs/sqlite/columndefinition.cpp b/src/libs/sqlite/columndefinition.cpp
new file mode 100644
index 0000000000..0bacb27c56
--- /dev/null
+++ b/src/libs/sqlite/columndefinition.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "columndefinition.h"
+
+namespace Internal {
+
+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_;
+}
+
+}
diff --git a/src/libs/sqlite/columndefinition.h b/src/libs/sqlite/columndefinition.h
new file mode 100644
index 0000000000..ef63a709dd
--- /dev/null
+++ b/src/libs/sqlite/columndefinition.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef COLUMNDEFINITION_H
+#define COLUMNDEFINITION_H
+
+#include "sqliteglobal.h"
+#include "utf8string.h"
+
+namespace Internal {
+
+class ColumnDefinition
+{
+public:
+ void setName(const Utf8String &name);
+ const Utf8String &name() const;
+
+ void setType(ColumnType type);
+ ColumnType type() const;
+ Utf8String typeString() const;
+
+ void setIsPrimaryKey(bool isPrimaryKey);
+ bool isPrimaryKey() const;
+
+private:
+ Utf8String name_;
+ ColumnType type_;
+ bool isPrimaryKey_ = false;
+};
+
+}
+
+#endif // COLUMNDEFINITION_H
diff --git a/src/libs/sqlite/createtablecommand.cpp b/src/libs/sqlite/createtablecommand.cpp
new file mode 100644
index 0000000000..5d54323e46
--- /dev/null
+++ b/src/libs/sqlite/createtablecommand.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "createtablecommand.h"
+
+namespace Internal {
+
+void CreateTableCommand::registerType()
+{
+ qRegisterMetaType<CreateTableCommand>("CreateTableCommand");
+}
+
+} // namespace Internal
+
diff --git a/src/libs/sqlite/createtablecommand.h b/src/libs/sqlite/createtablecommand.h
new file mode 100644
index 0000000000..cd4bdd46db
--- /dev/null
+++ b/src/libs/sqlite/createtablecommand.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef INTERNAL_CREATETABLECOMMAND_H
+#define INTERNAL_CREATETABLECOMMAND_H
+
+#include <QMetaType>
+#include <QVector>
+
+#include "utf8string.h"
+#include "columndefinition.h"
+
+namespace Internal {
+
+class CreateTableCommand
+{
+public:
+ QVector<ColumnDefinition> definitions;
+ Utf8String tableName;
+ bool useWithoutRowId;
+
+ static void registerType();
+
+};
+
+} // namespace Internal
+
+Q_DECLARE_METATYPE(Internal::CreateTableCommand)
+
+#endif // INTERNAL_CREATETABLECOMMAND_H
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
new file mode 100644
index 0000000000..5122001c19
--- /dev/null
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "createtablesqlstatementbuilder.h"
+
+#include "utf8stringvector.h"
+
+namespace Internal {
+
+CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
+ : sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")),
+ useWithoutRowId(false)
+{
+}
+
+void CreateTableSqlStatementBuilder::setTable(const Utf8String &tableName)
+{
+ sqlStatementBuilder.clear();
+
+ this->tableName = tableName;
+}
+
+void CreateTableSqlStatementBuilder::addColumnDefinition(const Utf8String &columnName,
+ ColumnType columnType,
+ bool isPrimaryKey)
+{
+ sqlStatementBuilder.clear();
+
+ ColumnDefinition columnDefinition;
+ columnDefinition.setName(columnName);
+ columnDefinition.setType(columnType);
+ columnDefinition.setIsPrimaryKey(isPrimaryKey);
+
+ columnDefinitions.append(columnDefinition);
+}
+
+void CreateTableSqlStatementBuilder::setColumnDefinitions(const QVector<ColumnDefinition> &columnDefinitions)
+{
+ sqlStatementBuilder.clear();
+
+ this->columnDefinitions = columnDefinitions;
+}
+
+void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
+{
+ this->useWithoutRowId = useWithoutRowId;
+}
+
+void CreateTableSqlStatementBuilder::clear()
+{
+ sqlStatementBuilder.clear();
+ columnDefinitions.clear();
+ tableName.clear();
+ useWithoutRowId = false;
+}
+
+void CreateTableSqlStatementBuilder::clearColumns()
+{
+ sqlStatementBuilder.clear();
+ columnDefinitions.clear();
+}
+
+Utf8String CreateTableSqlStatementBuilder::sqlStatement() const
+{
+ if (!sqlStatementBuilder.isBuild())
+ bindAll();
+
+ return sqlStatementBuilder.sqlStatement();
+}
+
+bool CreateTableSqlStatementBuilder::isValid() const
+{
+ return tableName.hasContent() && !columnDefinitions.isEmpty();
+}
+
+void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
+{
+ Utf8StringVector columnDefinitionStrings;
+
+ foreach (const ColumnDefinition &columnDefinition, columnDefinitions) {
+ Utf8String columnDefinitionString = columnDefinition.name() + Utf8StringLiteral(" ") + columnDefinition.typeString();
+
+ if (columnDefinition.isPrimaryKey())
+ columnDefinitionString.append(Utf8StringLiteral(" PRIMARY KEY"));
+
+ columnDefinitionStrings.append(columnDefinitionString);
+ }
+
+ sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings);
+}
+
+void CreateTableSqlStatementBuilder::bindAll() const
+{
+ sqlStatementBuilder.bind(Utf8StringLiteral("$table"), tableName);
+
+ bindColumnDefinitions();
+
+ if (useWithoutRowId)
+ sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID"));
+ else
+ sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId"));
+}
+
+}
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h
new file mode 100644
index 0000000000..f70c972f39
--- /dev/null
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CREATETABLESQLSTATEMENTBUILDER_H
+#define CREATETABLESQLSTATEMENTBUILDER_H
+
+#include <QVector>
+
+#include "sqlstatementbuilder.h"
+
+#include "columndefinition.h"
+
+namespace Internal {
+
+class SQLITE_EXPORT CreateTableSqlStatementBuilder
+{
+public:
+ CreateTableSqlStatementBuilder();
+
+ void setTable(const Utf8String &tableName);
+ void addColumnDefinition(const Utf8String &columnName, ColumnType columnType, bool isPrimaryKey = false);
+ void setColumnDefinitions(const QVector<ColumnDefinition> & columnDefinitions);
+ void setUseWithoutRowId(bool useWithoutRowId);
+
+ void clear();
+ void clearColumns();
+
+ Utf8String sqlStatement() const;
+
+ bool isValid() const;
+
+protected:
+ void bindColumnDefinitions() const;
+ void bindAll() const;
+
+private:
+ mutable SqlStatementBuilder sqlStatementBuilder;
+ Utf8String tableName;
+ QVector<ColumnDefinition> columnDefinitions;
+ bool useWithoutRowId;
+};
+
+}
+
+#endif // CREATETABLESQLSTATEMENTBUILDER_H
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
new file mode 100644
index 0000000000..35a02f55a6
--- /dev/null
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -0,0 +1,64 @@
+contains(CONFIG, dll) {
+ DEFINES += BUILD_SQLITE_LIBRARY
+} else {
+ DEFINES += BUILD_SQLITE_STATIC_LIBRARY
+}
+
+INCLUDEPATH += $$PWD
+
+unix:LIBS += -ldl
+
+include(../3rdparty/sqlite/sqlite.pri)
+
+SOURCES += \
+ $$PWD/columndefinition.cpp \
+ $$PWD/createtablecommand.cpp \
+ $$PWD/createtablesqlstatementbuilder.cpp \
+ $$PWD/sqlitedatabasebackend.cpp \
+ $$PWD/sqlitedatabaseconnection.cpp \
+ $$PWD/sqlitedatabaseconnectionproxy.cpp \
+ $$PWD/sqliteexception.cpp \
+ $$PWD/sqliteglobal.cpp \
+ $$PWD/sqlitereadstatement.cpp \
+ $$PWD/sqlitereadwritestatement.cpp \
+ $$PWD/sqlitestatement.cpp \
+ $$PWD/sqlitetransaction.cpp \
+ $$PWD/sqliteworkerthread.cpp \
+ $$PWD/sqlitewritestatement.cpp \
+ $$PWD/sqlstatementbuilder.cpp \
+ $$PWD/sqlstatementbuilderexception.cpp \
+ $$PWD/utf8string.cpp \
+ $$PWD/utf8stringvector.cpp \
+ $$PWD/sqlitedatabase.cpp \
+ $$PWD/sqlitetable.cpp \
+ $$PWD/sqlitecolumn.cpp \
+ $$PWD/tablewriteworker.cpp \
+ $$PWD/tablewriteworkerproxy.cpp
+HEADERS += \
+ $$PWD/columndefinition.h \
+ $$PWD/createtablesqlstatementbuilder.h \
+ $$PWD/sqlitedatabasebackend.h \
+ $$PWD/sqlitedatabaseconnection.h \
+ $$PWD/sqlitedatabaseconnectionproxy.h \
+ $$PWD/sqliteexception.h \
+ $$PWD/sqliteglobal.h \
+ $$PWD/sqlitereadstatement.h \
+ $$PWD/sqlitereadwritestatement.h \
+ $$PWD/sqlitestatement.h \
+ $$PWD/sqlitetransaction.h \
+ $$PWD/sqliteworkerthread.h \
+ $$PWD/sqlitewritestatement.h \
+ $$PWD/sqlstatementbuilder.h \
+ $$PWD/sqlstatementbuilderexception.h \
+ $$PWD/utf8string.h \
+ $$PWD/utf8stringvector.h \
+ $$PWD/sqlitedatabase.h \
+ $$PWD/sqlitetable.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
+
+contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/sqlite/sqlite-source.pri b/src/libs/sqlite/sqlite-source.pri
new file mode 100644
index 0000000000..b297e31da2
--- /dev/null
+++ b/src/libs/sqlite/sqlite-source.pri
@@ -0,0 +1,53 @@
+INCLUDEPATH += $$PWD
+VPATH += $$PWD
+
+SOURCES += \
+ columndefinition.cpp \
+ createtablecommand.cpp \
+ createtablesqlstatementbuilder.cpp \
+ sqlitedatabasebackend.cpp \
+ sqlitedatabaseconnection.cpp \
+ sqlitedatabaseconnectionproxy.cpp \
+ sqliteexception.cpp \
+ sqliteglobal.cpp \
+ sqlitereadstatement.cpp \
+ sqlitereadwritestatement.cpp \
+ sqlitestatement.cpp \
+ sqlitetransaction.cpp \
+ sqliteworkerthread.cpp \
+ sqlitewritestatement.cpp \
+ sqlstatementbuilder.cpp \
+ sqlstatementbuilderexception.cpp \
+ utf8string.cpp \
+ utf8stringvector.cpp \
+ sqlitedatabase.cpp \
+ sqlitetable.cpp \
+ sqlitecolumn.cpp \
+ tablewriteworker.cpp \
+ tablewriteworkerproxy.cpp
+HEADERS += \
+ columndefinition.h \
+ createtablesqlstatementbuilder.h \
+ sqlitedatabasebackend.h \
+ sqlitedatabaseconnection.h \
+ sqlitedatabaseconnectionproxy.h \
+ sqliteexception.h \
+ sqliteglobal.h \
+ sqlitereadstatement.h \
+ sqlitereadwritestatement.h \
+ sqlitestatement.h \
+ sqlitetransaction.h \
+ sqliteworkerthread.h \
+ sqlitewritestatement.h \
+ sqlstatementbuilder.h \
+ sqlstatementbuilderexception.h \
+ utf8string.h \
+ utf8stringvector.h \
+ sqlitedatabase.h \
+ sqlitetable.h \
+ sqlitecolumn.h \
+ tablewriteworker.h \
+ tablewriteworkerproxy.h \
+ createtablecommand.h
+
+
diff --git a/src/libs/sqlite/sqlite.pro b/src/libs/sqlite/sqlite.pro
new file mode 100644
index 0000000000..741e6a6cbf
--- /dev/null
+++ b/src/libs/sqlite/sqlite.pro
@@ -0,0 +1,5 @@
+unix:QMAKE_CXXFLAGS_DEBUG += -O2
+win32:QMAKE_CXXFLAGS_DEBUG += -O2
+
+include(../../qtcreatorlibrary.pri)
+include(sqlite-lib.pri)
diff --git a/src/libs/sqlite/sqlite.qbs b/src/libs/sqlite/sqlite.qbs
new file mode 100644
index 0000000000..92ff6a6c51
--- /dev/null
+++ b/src/libs/sqlite/sqlite.qbs
@@ -0,0 +1,42 @@
+import qbs 1.0
+
+QtcLibrary {
+ name: "Sqlite"
+
+ cpp.includePaths: base.concat(["../3rdparty/sqlite", "."])
+ cpp.defines: base.concat([
+ "BUILD_SQLITE_LIBRARY",
+ "SQLITE_THREADSAFE=2",
+ "SQLITE_ENABLE_FTS4",
+ "SQLITE_ENABLE_FTS3_PARENTHESIS",
+ "SQLITE_ENABLE_UNLOCK_NOTIFY",
+ "SQLITE_ENABLE_COLUMN_METADATA"
+ ])
+ cpp.optimization: "fast"
+ cpp.dynamicLibraries: base.concat("dl")
+
+
+ Group {
+ name: "ThirdPartySqlite"
+ prefix: "../3rdparty/sqlite/"
+ files: [
+ "sqlite3.c",
+ "sqlite3.h",
+ "sqlite3ext.h",
+ ]
+ }
+
+ Group {
+ files: [
+ "*.h",
+ "*.cpp"
+ ]
+ }
+
+ Export {
+ cpp.includePaths: base.concat([
+ "../3rdparty/sqlite",
+ "."
+ ])
+ }
+}
diff --git a/src/libs/sqlite/sqlite_dependencies.pri b/src/libs/sqlite/sqlite_dependencies.pri
new file mode 100644
index 0000000000..cb383c8e63
--- /dev/null
+++ b/src/libs/sqlite/sqlite_dependencies.pri
@@ -0,0 +1,3 @@
+QTC_LIB_NAME = Sqlite
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/3rdparty/sqlite
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite
diff --git a/src/libs/sqlite/sqlitecolumn.cpp b/src/libs/sqlite/sqlitecolumn.cpp
new file mode 100644
index 0000000000..5005c50441
--- /dev/null
+++ b/src/libs/sqlite/sqlitecolumn.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitecolumn.h"
+
+SqliteColumn::SqliteColumn()
+ : type_(ColumnType::Numeric),
+ isPrimaryKey_(false)
+{
+
+}
+
+void SqliteColumn::clear()
+{
+ name_.clear();
+ type_ = ColumnType::Numeric;
+ isPrimaryKey_ = false;
+}
+
+void SqliteColumn::setName(const Utf8String &newName)
+{
+ name_ = newName;
+}
+
+const Utf8String &SqliteColumn::name() const
+{
+ return name_;
+}
+
+void SqliteColumn::setType(ColumnType newType)
+{
+ type_ = newType;
+}
+
+ColumnType SqliteColumn::type() const
+{
+ return type_;
+}
+
+void SqliteColumn::setIsPrimaryKey(bool isPrimaryKey)
+{
+ isPrimaryKey_ = isPrimaryKey;
+}
+
+bool SqliteColumn::isPrimaryKey() const
+{
+ return isPrimaryKey_;
+}
+
+Internal::ColumnDefinition SqliteColumn::columnDefintion() const
+{
+ Internal::ColumnDefinition columnDefinition;
+
+ columnDefinition.setName(name_);
+ columnDefinition.setType(type_);
+ columnDefinition.setIsPrimaryKey(isPrimaryKey_);
+
+ return columnDefinition;
+}
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
new file mode 100644
index 0000000000..a25fa1fa28
--- /dev/null
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITECOLUMN_H
+#define SQLITECOLUMN_H
+
+#include <QObject>
+
+#include "utf8string.h"
+#include "columndefinition.h"
+
+class SQLITE_EXPORT SqliteColumn : public QObject
+{
+ Q_OBJECT
+public:
+ SqliteColumn();
+
+ void clear();
+
+ void setName(const Utf8String &newName);
+ const Utf8String &name() const;
+
+ void setType(ColumnType newType);
+ ColumnType type() const;
+
+ void setIsPrimaryKey(bool isPrimaryKey);
+ bool isPrimaryKey() const;
+
+ Internal::ColumnDefinition columnDefintion() const;
+
+private:
+ Utf8String name_;
+ ColumnType type_;
+ bool isPrimaryKey_;
+};
+
+#endif // SQLITECOLUMN_H
diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp
new file mode 100644
index 0000000000..66ce669551
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabase.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitedatabase.h"
+
+#include "sqlitetable.h"
+
+SqliteDatabase::SqliteDatabase()
+ : readDatabaseConnection(QStringLiteral("ReadWorker")),
+ 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()
+{
+ qDeleteAll(sqliteTables);
+}
+
+void SqliteDatabase::open()
+{
+ writeDatabaseConnection.setDatabaseFilePath(databaseFilePath());
+ writeDatabaseConnection.setJournalMode(journalMode());
+}
+
+void SqliteDatabase::close()
+{
+ writeDatabaseConnection.close();
+}
+
+bool SqliteDatabase::isOpen() const
+{
+ return readDatabaseConnection.isOpen() && writeDatabaseConnection.isOpen();
+}
+
+void SqliteDatabase::addTable(SqliteTable *newSqliteTable)
+{
+ newSqliteTable->setSqliteDatabase(this);
+ sqliteTables.append(newSqliteTable);
+}
+
+const QVector<SqliteTable *> &SqliteDatabase::tables() const
+{
+ return sqliteTables;
+}
+
+void SqliteDatabase::setDatabaseFilePath(const QString &databaseFilePath)
+{
+ databaseFilePath_ = databaseFilePath;
+}
+
+const QString &SqliteDatabase::databaseFilePath() const
+{
+ return databaseFilePath_;
+}
+
+void SqliteDatabase::setJournalMode(JournalMode journalMode)
+{
+ journalMode_ = journalMode;
+}
+
+JournalMode SqliteDatabase::journalMode() const
+{
+ return journalMode_;
+}
+
+QThread *SqliteDatabase::writeWorkerThread() const
+{
+ return writeDatabaseConnection.connectionThread();
+}
+
+QThread *SqliteDatabase::readWorkerThread() const
+{
+ return readDatabaseConnection.connectionThread();
+}
+
+void SqliteDatabase::handleReadDatabaseConnectionIsOpened()
+{
+ if (writeDatabaseConnection.isOpen() && readDatabaseConnection.isOpen()) {
+ initializeTables();
+ emit databaseIsOpened();
+ }
+}
+
+void SqliteDatabase::handleWriteDatabaseConnectionIsOpened()
+{
+ readDatabaseConnection.setDatabaseFilePath(databaseFilePath());
+}
+
+void SqliteDatabase::handleReadDatabaseConnectionIsClosed()
+{
+ if (!writeDatabaseConnection.isOpen() && !readDatabaseConnection.isOpen()) {
+ shutdownTables();
+ emit databaseIsClosed();
+ }
+}
+
+void SqliteDatabase::handleWriteDatabaseConnectionIsClosed()
+{
+ readDatabaseConnection.close();
+}
+
+void SqliteDatabase::initializeTables()
+{
+ for (SqliteTable *table: tables())
+ table->initialize();
+}
+
+void SqliteDatabase::shutdownTables()
+{
+ for (SqliteTable *table: tables())
+ table->shutdown();
+}
+
+
diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h
new file mode 100644
index 0000000000..a7d367cf16
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabase.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEDATABASE_H
+#define SQLITEDATABASE_H
+
+#include <QString>
+#include <QVector>
+
+#include "sqliteglobal.h"
+#include "sqlitedatabaseconnectionproxy.h"
+
+class SqliteTable;
+
+class SQLITE_EXPORT SqliteDatabase : public QObject
+{
+ Q_OBJECT
+
+public:
+ SqliteDatabase();
+ ~SqliteDatabase();
+
+ void open();
+ void close();
+
+ bool isOpen() const;
+
+ void addTable(SqliteTable *newSqliteTable);
+ const QVector<SqliteTable *> &tables() const;
+
+ void setDatabaseFilePath(const QString &databaseFilePath);
+ const QString &databaseFilePath() const;
+
+ void setJournalMode(JournalMode journalMode);
+ JournalMode journalMode() const;
+
+ QThread *writeWorkerThread() const;
+ QThread *readWorkerThread() const;
+
+signals:
+ void databaseIsOpened();
+ void databaseIsClosed();
+
+private:
+ void handleReadDatabaseConnectionIsOpened();
+ void handleWriteDatabaseConnectionIsOpened();
+ void handleReadDatabaseConnectionIsClosed();
+ void handleWriteDatabaseConnectionIsClosed();
+ void initializeTables();
+ void shutdownTables();
+
+private:
+ SqliteDatabaseConnectionProxy readDatabaseConnection;
+ SqliteDatabaseConnectionProxy writeDatabaseConnection;
+ QVector<SqliteTable*> sqliteTables;
+ QString databaseFilePath_;
+ JournalMode journalMode_;
+};
+
+#endif // SQLITEDATABASE_H
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
new file mode 100644
index 0000000000..c17aab3f72
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitedatabasebackend.h"
+
+#include <QThread>
+#include <QtDebug>
+
+#include "sqlite3.h"
+
+#include "okapi_bm25.h"
+
+#include "sqliteexception.h"
+#include "sqlitestatement.h"
+#include "sqlitereadstatement.h"
+#include "sqlitewritestatement.h"
+#include "sqlitereadwritestatement.h"
+
+#if defined(Q_OS_UNIX)
+#define QTC_THREAD_LOCAL __thread
+#elif defined(Q_OS_WIN)
+#define QTC_THREAD_LOCAL __declspec(thread)
+#else
+#define static QTC_THREAD_LOCAL thread_local
+#endif
+
+#define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray)
+
+QTC_THREAD_LOCAL SqliteDatabaseBackend *sqliteDatabaseBackend = nullptr;
+
+SqliteDatabaseBackend::SqliteDatabaseBackend()
+ : databaseHandle(nullptr),
+ cachedTextEncoding(Utf8)
+{
+ sqliteDatabaseBackend = this;
+}
+
+SqliteDatabaseBackend::~SqliteDatabaseBackend()
+{
+ closeWithoutException();
+ sqliteDatabaseBackend = nullptr;
+}
+
+void SqliteDatabaseBackend::setMmapSize(qint64 defaultSize, qint64 maximumSize)
+{
+ int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize);
+ checkMmapSizeIsSet(resultCode);
+}
+
+void SqliteDatabaseBackend::activateMultiThreading()
+{
+ int resultCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
+ checkIfMultithreadingIsActivated(resultCode);
+}
+
+static void sqliteLog(void*,int errorCode,const char *errorMessage)
+{
+ qWarning() << sqlite3_errstr(errorCode) << errorMessage;
+}
+
+void SqliteDatabaseBackend::activateLogging()
+{
+ int resultCode = sqlite3_config(SQLITE_CONFIG_LOG, sqliteLog, nullptr);
+ checkIfLoogingIsActivated(resultCode);
+}
+
+void SqliteDatabaseBackend::initializeSqliteLibrary()
+{
+ int resultCode = sqlite3_initialize();
+ checkInitializeSqliteLibraryWasSuccesful(resultCode);
+}
+
+void SqliteDatabaseBackend::shutdownSqliteLibrary()
+{
+ int resultCode = sqlite3_shutdown();
+ checkShutdownSqliteLibraryWasSuccesful(resultCode);
+}
+
+void SqliteDatabaseBackend::checkpointFullWalLog()
+{
+ int resultCode = sqlite3_wal_checkpoint_v2(sqliteDatabaseHandle(), nullptr, SQLITE_CHECKPOINT_FULL, nullptr, nullptr);
+ checkIfLogCouldBeCheckpointed(resultCode);
+}
+
+void SqliteDatabaseBackend::open(const QString &databaseFilePath)
+{
+ checkCanOpenDatabase(databaseFilePath);
+
+ QByteArray databaseUtf8Path = databaseFilePath.toUtf8();
+ int resultCode = sqlite3_open_v2(databaseUtf8Path.data(),
+ &databaseHandle,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+ NULL);
+
+ checkDatabaseCouldBeOpened(resultCode);
+
+ registerBusyHandler();
+ registerRankingFunction();
+ cacheTextEncoding();
+}
+
+sqlite3 *SqliteDatabaseBackend::sqliteDatabaseHandle()
+{
+ checkDatabaseBackendIsNotNull();
+ checkDatabaseHandleIsNotNull();
+ return threadLocalInstance()->databaseHandle;
+}
+
+void SqliteDatabaseBackend::setPragmaValue(const Utf8String &pragmaKey, const Utf8String &newPragmaValue)
+{
+ SqliteReadWriteStatement::execute(Utf8StringLiteral("PRAGMA ") + pragmaKey + Utf8StringLiteral("='") + newPragmaValue + Utf8StringLiteral("'"));
+ Utf8String pragmeValueInDatabase = SqliteReadWriteStatement::toValue<Utf8String>(Utf8StringLiteral("PRAGMA ") + pragmaKey);
+
+ checkPragmaValue(pragmeValueInDatabase, newPragmaValue);
+}
+
+Utf8String SqliteDatabaseBackend::pragmaValue(const Utf8String &pragma) const
+{
+ return SqliteReadWriteStatement::toValue<Utf8String>(Utf8StringLiteral("PRAGMA ") + pragma);
+}
+
+void SqliteDatabaseBackend::setJournalMode(JournalMode journalMode)
+{
+ setPragmaValue(Utf8StringLiteral("journal_mode"), journalModeToPragma(journalMode));
+}
+
+JournalMode SqliteDatabaseBackend::journalMode() const
+{
+ return pragmaToJournalMode(pragmaValue(Utf8StringLiteral("journal_mode")));
+}
+
+void SqliteDatabaseBackend::setTextEncoding(TextEncoding textEncoding)
+{
+ setPragmaValue(Utf8StringLiteral("encoding"), textEncodingToPragma(textEncoding));
+ cacheTextEncoding();
+}
+
+TextEncoding SqliteDatabaseBackend::textEncoding()
+{
+ return cachedTextEncoding;
+}
+
+
+Utf8StringVector SqliteDatabaseBackend::columnNames(const Utf8String &tableName)
+{
+ SqliteReadStatement statement(Utf8StringLiteral("SELECT * FROM ") + tableName);
+ return statement.columnNames();
+}
+
+int SqliteDatabaseBackend::changesCount()
+{
+ return sqlite3_changes(sqliteDatabaseHandle());
+}
+
+int SqliteDatabaseBackend::totalChangesCount()
+{
+ return sqlite3_total_changes(sqliteDatabaseHandle());
+}
+
+void SqliteDatabaseBackend::close()
+{
+ checkForOpenDatabaseWhichCanBeClosed();
+
+ int resultCode = sqlite3_close(databaseHandle);
+
+ checkDatabaseClosing(resultCode);
+
+ databaseHandle = nullptr;
+
+}
+
+SqliteDatabaseBackend *SqliteDatabaseBackend::threadLocalInstance()
+{
+ checkDatabaseBackendIsNotNull();
+ return sqliteDatabaseBackend;
+}
+
+bool SqliteDatabaseBackend::databaseIsOpen() const
+{
+ return databaseHandle != nullptr;
+}
+
+void SqliteDatabaseBackend::closeWithoutException()
+{
+ if (databaseHandle) {
+ int resultCode = sqlite3_close_v2(databaseHandle);
+ databaseHandle = nullptr;
+ if (resultCode != SQLITE_OK)
+ qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!";
+ }
+}
+
+void SqliteDatabaseBackend::registerBusyHandler()
+{
+ sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, nullptr);
+}
+
+void SqliteDatabaseBackend::registerRankingFunction()
+{
+ sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25", -1, SQLITE_ANY, 0, okapi_bm25, 0, 0, 0);
+ sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25f", -1, SQLITE_UTF8, 0, okapi_bm25f, 0, 0, 0);
+ sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25f_kb", -1, SQLITE_UTF8, 0, okapi_bm25f_kb, 0, 0, 0);
+}
+
+int SqliteDatabaseBackend::busyHandlerCallback(void *, int counter)
+{
+ Q_UNUSED(counter);
+#ifdef QT_DEBUG
+ //qWarning() << "Busy handler invoked" << counter << "times!";
+#endif
+ QThread::msleep(10);
+
+ return true;
+}
+
+void SqliteDatabaseBackend::cacheTextEncoding()
+{
+ cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding")));
+}
+
+void SqliteDatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
+{
+ if (databaseHandle == nullptr)
+ throwException("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
+}
+
+void SqliteDatabaseBackend::checkDatabaseClosing(int resultCode)
+{
+ switch (resultCode) {
+ case SQLITE_OK: return;
+ default: throwException("SqliteDatabaseBackend::close: unknown error happens at closing!");
+ }
+}
+
+void SqliteDatabaseBackend::checkCanOpenDatabase(const QString &databaseFilePath)
+{
+ if (databaseFilePath.isEmpty())
+ throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database file path is empty!");
+
+ if (databaseIsOpen())
+ throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database is already open!");
+}
+
+void SqliteDatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
+{
+ switch (resultCode) {
+ case SQLITE_OK:
+ return;
+ default:
+ closeWithoutException();
+ throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", sqlite3_errmsg(sqliteDatabaseHandle()));
+ }
+}
+
+void SqliteDatabaseBackend::checkPragmaValue(const Utf8String &databaseValue, const Utf8String &expectedValue)
+{
+ if (databaseValue != expectedValue)
+ throwException("SqliteDatabaseBackend::setPragmaValue: pragma value is not set!");
+}
+
+void SqliteDatabaseBackend::checkDatabaseHandleIsNotNull()
+{
+ if (sqliteDatabaseBackend->databaseHandle == nullptr)
+ throwException("SqliteDatabaseBackend: database is not open!");
+}
+
+void SqliteDatabaseBackend::checkDatabaseBackendIsNotNull()
+{
+ if (sqliteDatabaseBackend == nullptr)
+ throwException("SqliteDatabaseBackend: database backend is not initialized!");
+}
+
+void SqliteDatabaseBackend::checkIfMultithreadingIsActivated(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::activateMultiThreading: multithreading can't be activated!");
+}
+
+void SqliteDatabaseBackend::checkIfLoogingIsActivated(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::activateLogging: logging can't be activated!");
+}
+
+void SqliteDatabaseBackend::checkMmapSizeIsSet(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::checkMmapSizeIsSet: mmap size can't be changed!");
+}
+
+void SqliteDatabaseBackend::checkInitializeSqliteLibraryWasSuccesful(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::initializeSqliteLibrary: SqliteLibrary cannot initialized!");
+}
+
+void SqliteDatabaseBackend::checkShutdownSqliteLibraryWasSuccesful(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::shutdownSqliteLibrary: SqliteLibrary cannot be shutdowned!");
+}
+
+void SqliteDatabaseBackend::checkIfLogCouldBeCheckpointed(int resultCode)
+{
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteDatabaseBackend::checkpointFullWalLog: WAL log could not be checkpointed!");
+}
+
+int SqliteDatabaseBackend::indexOfPragma(const Utf8String pragma, const Utf8String pragmas[], size_t pragmaCount)
+{
+ for (unsigned int index = 0; index < pragmaCount; index++) {
+ if (pragma == pragmas[index])
+ return int(index);
+ }
+
+ return -1;
+
+}
+
+static const Utf8String journalModeStrings[] = {
+ Utf8StringLiteral("delete"),
+ Utf8StringLiteral("truncate"),
+ Utf8StringLiteral("persist"),
+ Utf8StringLiteral("memory"),
+ Utf8StringLiteral("wal")
+};
+
+const Utf8String &SqliteDatabaseBackend::journalModeToPragma(JournalMode journalMode)
+{
+ return journalModeStrings[int(journalMode)];
+}
+
+JournalMode SqliteDatabaseBackend::pragmaToJournalMode(const Utf8String &pragma)
+{
+ int index = indexOfPragma(pragma, journalModeStrings, SIZE_OF_BYTEARRAY_ARRAY(journalModeStrings));
+
+ if (index < 0)
+ throwException("SqliteDatabaseBackend::pragmaToJournalMode: pragma can't be transformed in a journal mode enumeration!");
+
+ return static_cast<JournalMode>(index);
+}
+
+static const Utf8String textEncodingStrings[] = {
+ Utf8StringLiteral("UTF-8"),
+ Utf8StringLiteral("UTF-16le"),
+ Utf8StringLiteral("UTF-16be")
+};
+
+const Utf8String &SqliteDatabaseBackend::textEncodingToPragma(TextEncoding textEncoding)
+{
+ return textEncodingStrings[textEncoding];
+}
+
+TextEncoding SqliteDatabaseBackend::pragmaToTextEncoding(const Utf8String &pragma)
+{
+ int index = indexOfPragma(pragma, textEncodingStrings, SIZE_OF_BYTEARRAY_ARRAY(textEncodingStrings));
+
+ if (index < 0)
+ throwException("SqliteDatabaseBackend::pragmaToTextEncoding: pragma can't be transformed in a text encoding enumeration!");
+
+ return static_cast<TextEncoding>(index);
+}
+
+void SqliteDatabaseBackend::throwException(const char *whatHasHappens)
+{
+ if (sqliteDatabaseBackend && sqliteDatabaseBackend->databaseHandle)
+ throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->databaseHandle));
+ else
+ throw SqliteException(whatHasHappens);
+}
diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h
new file mode 100644
index 0000000000..5b1b21788c
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabasebackend.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEDATABASEBACKEND_H
+#define SQLITEDATABASEBACKEND_H
+
+#include <QStringList>
+
+#include "sqliteglobal.h"
+
+#include "utf8stringvector.h"
+
+struct sqlite3;
+
+class SQLITE_EXPORT SqliteDatabaseBackend
+{
+public:
+
+ SqliteDatabaseBackend();
+ ~SqliteDatabaseBackend();
+
+ static void setMmapSize(qint64 defaultSize, qint64 maximumSize);
+ static void activateMultiThreading();
+ static void activateLogging();
+ static void initializeSqliteLibrary();
+ static void shutdownSqliteLibrary();
+ static void checkpointFullWalLog();
+
+ void open(const QString &databaseFilePath);
+ void close();
+ void closeWithoutException();
+
+ static SqliteDatabaseBackend *threadLocalInstance();
+ static sqlite3* sqliteDatabaseHandle();
+
+ void setJournalMode(JournalMode journalMode);
+ JournalMode journalMode() const;
+
+ void setTextEncoding(TextEncoding textEncoding);
+ TextEncoding textEncoding();
+
+
+
+ static Utf8StringVector columnNames(const Utf8String &tableName);
+
+ static int changesCount();
+ static int totalChangesCount();
+
+protected:
+ bool databaseIsOpen() const;
+
+ void setPragmaValue(const Utf8String &pragma, const Utf8String &value);
+ Utf8String pragmaValue(const Utf8String &pragma) const;
+
+ void registerBusyHandler();
+ void registerRankingFunction();
+ static int busyHandlerCallback(void*, int counter);
+
+ void cacheTextEncoding();
+
+ void checkForOpenDatabaseWhichCanBeClosed();
+ void checkDatabaseClosing(int resultCode);
+ void checkCanOpenDatabase(const QString &databaseFilePath);
+ void checkDatabaseCouldBeOpened(int resultCode);
+ void checkPragmaValue(const Utf8String &databaseValue, const Utf8String &expectedValue);
+ static void checkDatabaseHandleIsNotNull();
+ static void checkDatabaseBackendIsNotNull();
+ static void checkIfMultithreadingIsActivated(int resultCode);
+ static void checkIfLoogingIsActivated(int resultCode);
+ static void checkMmapSizeIsSet(int resultCode);
+ static void checkInitializeSqliteLibraryWasSuccesful(int resultCode);
+ static void checkShutdownSqliteLibraryWasSuccesful(int resultCode);
+ static void checkIfLogCouldBeCheckpointed(int resultCode);
+
+ static int indexOfPragma(const Utf8String pragma, const Utf8String pragmas[], size_t pragmaCount);
+ static const Utf8String &journalModeToPragma(JournalMode journalMode);
+ static JournalMode pragmaToJournalMode(const Utf8String &pragma);
+ static const Utf8String &textEncodingToPragma(TextEncoding textEncoding);
+ static TextEncoding pragmaToTextEncoding(const Utf8String &pragma);
+
+ Q_NORETURN static void throwException(const char *whatHasHappens);
+
+private:
+ sqlite3 *databaseHandle;
+ TextEncoding cachedTextEncoding;
+
+};
+
+#endif // SQLITEDATABASEBACKEND_H
diff --git a/src/libs/sqlite/sqlitedatabaseconnection.cpp b/src/libs/sqlite/sqlitedatabaseconnection.cpp
new file mode 100644
index 0000000000..29e1d19fec
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabaseconnection.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitedatabaseconnection.h"
+
+#include <sqlite3.h>
+
+#include <QtDebug>
+
+#ifdef Q_OS_LINUX
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#endif
+
+#include "sqliteexception.h"
+#include "sqliteglobal.h"
+
+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
+}
diff --git a/src/libs/sqlite/sqlitedatabaseconnection.h b/src/libs/sqlite/sqlitedatabaseconnection.h
new file mode 100644
index 0000000000..548bcb32ce
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabaseconnection.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEDATABASECONNECTIONCONTROLLER_H
+#define SQLITEDATABASECONNECTIONCONTROLLER_H
+
+#include <QObject>
+
+#include "sqlitedatabasebackend.h"
+
+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;
+};
+
+#endif // SQLITEDATABASECONNECTIONCONTROLLER_H
diff --git a/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp b/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp
new file mode 100644
index 0000000000..994b5e028d
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#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();
+}
diff --git a/src/libs/sqlite/sqlitedatabaseconnectionproxy.h b/src/libs/sqlite/sqlitedatabaseconnectionproxy.h
new file mode 100644
index 0000000000..21885645e5
--- /dev/null
+++ b/src/libs/sqlite/sqlitedatabaseconnectionproxy.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEDATABASECONNECTION_H
+#define SQLITEDATABASECONNECTION_H
+
+#include <QObject>
+#include <QPointer>
+
+#include <sqliteglobal.h>
+
+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;
+};
+
+#endif // SQLITEDATABASECONNECTION_H
diff --git a/src/libs/sqlite/sqliteexception.cpp b/src/libs/sqlite/sqliteexception.cpp
new file mode 100644
index 0000000000..fde46941b6
--- /dev/null
+++ b/src/libs/sqlite/sqliteexception.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqliteexception.h"
+
+#include <QtDebug>
+
+SqliteException::SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage)
+ : whatErrorHasHappen(whatErrorHasHappen),
+ sqliteErrorMessage_(sqliteErrorMessage)
+{
+}
+
+void SqliteException::printWarning() const
+{
+ if (!sqliteErrorMessage_.isEmpty())
+ qWarning() << whatErrorHasHappen << sqliteErrorMessage_;
+ else
+ qWarning() << whatErrorHasHappen;
+}
+
diff --git a/src/libs/sqlite/sqliteexception.h b/src/libs/sqlite/sqliteexception.h
new file mode 100644
index 0000000000..beab962c6e
--- /dev/null
+++ b/src/libs/sqlite/sqliteexception.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEEXCEPTION_H
+#define SQLITEEXCEPTION_H
+
+#include <QByteArray>
+
+#include "sqliteglobal.h"
+
+class SQLITE_EXPORT SqliteException
+{
+public:
+ SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage = 0);
+
+ void printWarning() const;
+
+private:
+ const char *whatErrorHasHappen;
+ QByteArray sqliteErrorMessage_;
+};
+
+#endif // SQLITEEXCEPTION_H
diff --git a/src/libs/sqlite/sqliteglobal.cpp b/src/libs/sqlite/sqliteglobal.cpp
new file mode 100644
index 0000000000..74e76aab5a
--- /dev/null
+++ b/src/libs/sqlite/sqliteglobal.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqliteglobal.h"
+
+#include "createtablecommand.h"
+
+namespace Sqlite {
+
+void registerTypes()
+{
+ Internal::CreateTableCommand::registerType();
+
+ qRegisterMetaType<JournalMode>("JournalMode");
+}
+
+}
diff --git a/src/libs/sqlite/sqliteglobal.h b/src/libs/sqlite/sqliteglobal.h
new file mode 100644
index 0000000000..0b14b21a4b
--- /dev/null
+++ b/src/libs/sqlite/sqliteglobal.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEGLOBAL_H
+#define SQLITEGLOBAL_H
+
+#include <QtGlobal>
+
+#if defined(BUILD_SQLITE_LIBRARY)
+# define SQLITE_EXPORT Q_DECL_EXPORT
+#elif defined(BUILD_SQLITE_STATIC_LIBRARY)
+# define SQLITE_EXPORT
+#else
+# define SQLITE_EXPORT Q_DECL_IMPORT
+#endif
+
+
+namespace Sqlite {
+SQLITE_EXPORT void registerTypes();
+}
+
+enum class ColumnType {
+ Numeric,
+ Integer,
+ Real,
+ Text,
+ None
+};
+
+enum class ColumnConstraint {
+ PrimaryKey
+};
+
+enum class JournalMode {
+ Delete,
+ Truncate,
+ Persist,
+ Memory,
+ Wal
+};
+
+enum TextEncoding {
+ Utf8,
+ Utf16le,
+ Utf16be,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ Utf16 = Utf16le
+#else
+ Utf16 = Utf16be
+#endif
+
+};
+
+QT_BEGIN_NAMESPACE
+template <typename T> class QVector;
+template <typename T> class QSet;
+template <class Key, class T> class QHash;
+template <class Key, class T> class QMap;
+class QVariant;
+QT_END_NAMESPACE
+
+class Utf8String;
+class Utf8StringVector;
+
+typedef QMap<Utf8String, QVariant> RowDictionary;
+typedef QVector<RowDictionary> RowDictionaries;
+
+
+#endif // SQLITEGLOBAL_H
diff --git a/src/libs/sqlite/sqlitereadstatement.cpp b/src/libs/sqlite/sqlitereadstatement.cpp
new file mode 100644
index 0000000000..e04b577d39
--- /dev/null
+++ b/src/libs/sqlite/sqlitereadstatement.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitereadstatement.h"
+
+#include "sqlite3.h"
+
+SqliteReadStatement::SqliteReadStatement(const Utf8String &sqlStatementUtf8)
+ : SqliteStatement(sqlStatementUtf8)
+{
+ checkIsReadOnlyStatement();
+}
+
+void SqliteReadStatement::checkIsReadOnlyStatement()
+{
+ if (!isReadOnlyStatement())
+ throwException("SqliteStatement::SqliteReadStatement: is not read only statement!");
+}
diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h
new file mode 100644
index 0000000000..abc1ea80dc
--- /dev/null
+++ b/src/libs/sqlite/sqlitereadstatement.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEREADSTATEMENT_H
+#define SQLITEREADSTATEMENT_H
+
+#include "sqlitestatement.h"
+
+class SQLITE_EXPORT SqliteReadStatement final : private SqliteStatement
+{
+public:
+ explicit SqliteReadStatement(const Utf8String &sqlStatementUtf8);
+
+ using SqliteStatement::next;
+ using SqliteStatement::reset;
+ using SqliteStatement::value;
+ using SqliteStatement::values;
+ using SqliteStatement::rowColumnValueMap;
+ using SqliteStatement::twoColumnValueMap;
+ using SqliteStatement::columnCount;
+ using SqliteStatement::columnNames;
+ using SqliteStatement::bind;
+ using SqliteStatement::bindingIndexForName;
+ using SqliteStatement::setBindingColumnNames;
+ using SqliteStatement::bindingColumnNames;
+ using SqliteStatement::toValue;
+
+protected:
+ void checkIsReadOnlyStatement();
+};
+
+#endif // SQLITEREADSTATEMENT_H
diff --git a/src/libs/sqlite/sqlitereadwritestatement.cpp b/src/libs/sqlite/sqlitereadwritestatement.cpp
new file mode 100644
index 0000000000..1427a83a0d
--- /dev/null
+++ b/src/libs/sqlite/sqlitereadwritestatement.cpp
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitereadwritestatement.h"
+
+
+SqliteReadWriteStatement::SqliteReadWriteStatement(const Utf8String &sqlStatementUft8)
+ : SqliteStatement(sqlStatementUft8)
+{
+}
+
diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h
new file mode 100644
index 0000000000..02825fc295
--- /dev/null
+++ b/src/libs/sqlite/sqlitereadwritestatement.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEREADWRITESTATEMENT_H
+#define SQLITEREADWRITESTATEMENT_H
+
+#include "sqlitestatement.h"
+
+class SQLITE_EXPORT SqliteReadWriteStatement final : private SqliteStatement
+{
+public:
+ explicit SqliteReadWriteStatement(const Utf8String &sqlStatementUft8);
+
+ using SqliteStatement::next;
+ using SqliteStatement::step;
+ using SqliteStatement::reset;
+ using SqliteStatement::bind;
+ using SqliteStatement::bindingIndexForName;
+ using SqliteStatement::setBindingColumnNames;
+ using SqliteStatement::bindingColumnNames;
+ using SqliteStatement::write;
+ using SqliteStatement::value;
+ using SqliteStatement::values;
+ using SqliteStatement::rowColumnValueMap;
+ using SqliteStatement::columnCount;
+ using SqliteStatement::columnNames;
+ using SqliteStatement::toValue;
+ using SqliteStatement::execute;
+};
+
+#endif // SQLITEREADWRITESTATEMENT_H
diff --git a/src/libs/sqlite/sqlitestatement.cpp b/src/libs/sqlite/sqlitestatement.cpp
new file mode 100644
index 0000000000..4b8e3338a4
--- /dev/null
+++ b/src/libs/sqlite/sqlitestatement.cpp
@@ -0,0 +1,676 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitestatement.h"
+
+#include <QMutex>
+#include <QWaitCondition>
+#include <QVariant>
+#include <QtGlobal>
+
+#include "sqlite3.h"
+
+#include "sqlitedatabasebackend.h"
+#include "sqliteexception.h"
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#endif
+
+SqliteStatement::SqliteStatement(const Utf8String &sqlStatementUtf8)
+ : compiledStatement(nullptr, deleteCompiledStatement),
+ bindingParameterCount(0),
+ columnCount_(0),
+ isReadyToFetchValues(false)
+{
+ prepare(sqlStatementUtf8);
+ setBindingParameterCount();
+ setBindingColumnNamesFromStatement();
+ setColumnCount();
+}
+
+void SqliteStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
+{
+ if (compiledStatement)
+ sqlite3_finalize(compiledStatement);
+}
+
+class UnlockNotification {
+
+public:
+ UnlockNotification() : fired(false) {};
+
+ static void unlockNotifyCallBack(void **arguments, int argumentCount)
+ {
+ for (int index = 0; index < argumentCount; index++) {
+ UnlockNotification *unlockNotification = static_cast<UnlockNotification *>(arguments[index]);
+ unlockNotification->wakeupWaitCondition();
+ }
+ }
+
+ void wakeupWaitCondition()
+ {
+ mutex.lock();
+ fired = 1;
+ waitCondition.wakeAll();
+ mutex.unlock();
+ }
+
+ void wait()
+ {
+ mutex.lock();
+
+ if (!fired) {
+ waitCondition.wait(&mutex);
+ }
+
+ mutex.unlock();
+ }
+
+private:
+ bool fired;
+ QWaitCondition waitCondition;
+ QMutex mutex;
+};
+
+void SqliteStatement::waitForUnlockNotify() const
+{
+ UnlockNotification unlockNotification;
+ int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(), UnlockNotification::unlockNotifyCallBack, &unlockNotification);
+
+ if (resultCode == SQLITE_OK)
+ unlockNotification.wait();
+ else
+ throwException("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
+}
+
+void SqliteStatement::reset() const
+{
+ int resultCode = sqlite3_reset(compiledStatement.get());
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteStatement::reset: can't reset statement!");
+
+ isReadyToFetchValues = false;
+}
+
+bool SqliteStatement::next() const
+{
+ int resultCode;
+
+ do {
+ resultCode = sqlite3_step(compiledStatement.get());
+ if (resultCode == SQLITE_LOCKED) {
+ waitForUnlockNotify();
+ sqlite3_reset(compiledStatement.get());
+ }
+
+ } while (resultCode == SQLITE_LOCKED);
+
+ setIfIsReadyToFetchValues(resultCode);
+
+ return checkForStepError(resultCode);
+}
+
+void SqliteStatement::step() const
+{
+ next();
+}
+
+void SqliteStatement::write(const RowDictionary &rowDictionary)
+{
+ bind(rowDictionary);
+ step();
+ reset();
+}
+
+void SqliteStatement::writeUnchecked(const RowDictionary &rowDictionary)
+{
+ bindUnchecked(rowDictionary);
+ step();
+ reset();
+}
+
+int SqliteStatement::columnCount() const
+{
+ return columnCount_;
+}
+
+Utf8StringVector SqliteStatement::columnNames() const
+{
+ Utf8StringVector columnNames;
+ int columnCount = SqliteStatement::columnCount();
+ columnNames.reserve(columnCount);
+ for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
+ columnNames.append(Utf8String(sqlite3_column_origin_name(compiledStatement.get(), columnIndex), -1));
+
+ return columnNames;
+}
+
+void SqliteStatement::bind(int index, int value)
+{
+ int resultCode = sqlite3_bind_int(compiledStatement.get(), index, value);
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
+}
+
+void SqliteStatement::bind(int index, qint64 value)
+{
+ int resultCode = sqlite3_bind_int64(compiledStatement.get(), index, value);
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteStatement::bind: cant' bind 64 bit integer!");
+}
+
+void SqliteStatement::bind(int index, double value)
+{
+ int resultCode = sqlite3_bind_double(compiledStatement.get(), index, value);
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteStatement::bind: cant' bind double!");
+}
+
+void SqliteStatement::bind(int index, const QString &text)
+{
+ int resultCode;
+ if (databaseTextEncoding() == Utf8) {
+ QByteArray textUtf8 = text.toUtf8();
+ resultCode = sqlite3_bind_text(compiledStatement.get(), index, textUtf8.constData(), textUtf8.size(), SQLITE_TRANSIENT);
+ } else {
+ resultCode = sqlite3_bind_text16(compiledStatement.get(), index, text.constData(), text.size() * 2, SQLITE_TRANSIENT);
+ }
+
+ if (resultCode != SQLITE_OK)
+ throwException("SqliteStatement::bind: cant' not bind text!");
+}
+
+void SqliteStatement::bind(int index, const QByteArray &blob)
+{
+ sqlite3_bind_blob(compiledStatement.get(), index, blob.constData(), blob.size(), SQLITE_TRANSIENT);
+}
+
+void SqliteStatement::bind(int index, const QVariant &value)
+{
+ checkBindingIndex(index);
+
+ switch (value.type()) {
+ case QVariant::Bool:
+ case QVariant::Int:
+ bind(index, value.toInt());
+ break;
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ bind(index, value.toLongLong());
+ break;
+ case QVariant::Double:
+ bind(index, value.toDouble());
+ break;
+ case QVariant::String:
+ bind(index, value.toString());
+ break;
+ case QVariant::ByteArray:
+ bind(index, value.toByteArray());
+ break;
+ default:
+ sqlite3_bind_null(compiledStatement.get(), index);
+ }
+}
+
+template <typename Type>
+void SqliteStatement::bind(const Utf8String &name, const Type &value)
+{
+ int index = bindingIndexForName(name);
+ checkBindingName(index);
+ bind(index, value);
+}
+
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const int &value);
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const qint64 &value);
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const double &value);
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QString &text);
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QByteArray &blob);
+template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QVariant &value);
+
+int SqliteStatement::bindingIndexForName(const Utf8String &name)
+{
+ return sqlite3_bind_parameter_index(compiledStatement.get(), name.constData());
+}
+
+void SqliteStatement::bind(const RowDictionary &rowDictionary)
+{
+ checkBindingValueMapIsEmpty(rowDictionary);
+
+ int columnIndex = 1;
+ foreach (const Utf8String &columnName, bindingColumnNames_) {
+ checkParameterCanBeBound(rowDictionary, columnName);
+ QVariant value = rowDictionary.value(columnName);
+ bind(columnIndex, value);
+ columnIndex += 1;
+ }
+}
+
+void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
+{
+ checkBindingValueMapIsEmpty(rowDictionary);
+
+ int columnIndex = 1;
+ foreach (const Utf8String &columnName, bindingColumnNames_) {
+ if (rowDictionary.contains(columnName)) {
+ QVariant value = rowDictionary.value(columnName);
+ bind(columnIndex, value);
+ }
+ columnIndex += 1;
+ }
+}
+
+void SqliteStatement::setBindingColumnNames(const Utf8StringVector &bindingColumnNames)
+{
+ bindingColumnNames_ = bindingColumnNames;
+}
+
+const Utf8StringVector &SqliteStatement::bindingColumnNames() const
+{
+ return bindingColumnNames_;
+}
+
+void SqliteStatement::execute(const Utf8String &sqlStatementUtf8)
+{
+ SqliteStatement statement(sqlStatementUtf8);
+ statement.step();
+}
+
+void SqliteStatement::prepare(const Utf8String &sqlStatementUtf8)
+{
+ int resultCode;
+
+ do {
+ sqlite3_stmt *sqliteStatement = nullptr;
+ resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(), sqlStatementUtf8.constData(), sqlStatementUtf8.byteSize(), &sqliteStatement, nullptr);
+ compiledStatement.reset(sqliteStatement);
+
+ if (resultCode == SQLITE_LOCKED)
+ waitForUnlockNotify();
+
+ } while (resultCode == SQLITE_LOCKED);
+
+ checkForPrepareError(resultCode);
+}
+
+sqlite3 *SqliteStatement::sqliteDatabaseHandle()
+{
+return SqliteDatabaseBackend::sqliteDatabaseHandle();
+}
+
+TextEncoding SqliteStatement::databaseTextEncoding()
+{
+ if (SqliteDatabaseBackend::threadLocalInstance())
+ return SqliteDatabaseBackend::threadLocalInstance()->textEncoding();
+
+ throwException("SqliteStatement::databaseTextEncoding: database backend instance is null!");
+
+ Q_UNREACHABLE();
+}
+
+bool SqliteStatement::checkForStepError(int resultCode) const
+{
+ switch (resultCode) {
+ case SQLITE_ROW: return true;
+ case SQLITE_DONE: return false;
+ case SQLITE_BUSY: throwException("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
+ case SQLITE_ERROR : throwException("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
+ case SQLITE_MISUSE: throwException("SqliteStatement::stepStatement: was called inappropriately!");
+ case SQLITE_CONSTRAINT: throwException("SqliteStatement::stepStatement: contraint prevent insert or update!");
+ }
+
+ throwException("SqliteStatement::stepStatement: unknown error has happen!");
+
+ Q_UNREACHABLE();
+}
+
+void SqliteStatement::checkForPrepareError(int resultCode) const
+{
+ switch (resultCode) {
+ case SQLITE_OK: return;
+ case SQLITE_BUSY: throwException("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
+ case SQLITE_ERROR : throwException("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
+ case SQLITE_MISUSE: throwException("SqliteStatement::prepareStatement: was called inappropriately!");
+ }
+
+ throwException("SqliteStatement::prepareStatement: unknown error has happen!");
+}
+
+void SqliteStatement::setIfIsReadyToFetchValues(int resultCode) const
+{
+ if (resultCode == SQLITE_ROW)
+ isReadyToFetchValues = true;
+ else
+ isReadyToFetchValues = false;
+
+}
+
+void SqliteStatement::checkIfIsReadyToFetchValues() const
+{
+ if (!isReadyToFetchValues)
+ throwException("SqliteStatement::value: there are no values to fetch!");
+}
+
+void SqliteStatement::checkColumnsAreValid(const QVector<int> &columns) const
+{
+ foreach (int column, columns) {
+ if (column < 0 || column >= columnCount_)
+ throwException("SqliteStatement::values: column index out of bound!");
+ }
+}
+
+void SqliteStatement::checkColumnIsValid(int column) const
+{
+ if (column < 0 || column >= columnCount_)
+ throwException("SqliteStatement::values: column index out of bound!");
+}
+
+void SqliteStatement::checkBindingIndex(int index) const
+{
+ if (index <= 0 || index > bindingParameterCount)
+ throwException("SqliteStatement::bind: binding index is out of bound!");
+}
+
+void SqliteStatement::checkBindingName(int index) const
+{
+ if (index <= 0 || index > bindingParameterCount)
+ throwException("SqliteStatement::bind: binding name are not exists in this statement!");
+}
+
+void SqliteStatement::checkParameterCanBeBound(const RowDictionary &rowDictionary, const Utf8String &columnName)
+{
+ if (!rowDictionary.contains(columnName))
+ throwException("SqliteStatement::bind: Not all parameters are bound!");
+}
+
+void SqliteStatement::setBindingParameterCount()
+{
+ bindingParameterCount = sqlite3_bind_parameter_count(compiledStatement.get());
+}
+
+Utf8String chopFirstLetter(const char *rawBindingName)
+{
+ QByteArray bindingName(rawBindingName);
+ bindingName = bindingName.mid(1);
+
+ return Utf8String::fromByteArray(bindingName);
+}
+
+void SqliteStatement::setBindingColumnNamesFromStatement()
+{
+ for (int index = 1; index <= bindingParameterCount; index++) {
+ Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(compiledStatement.get(), index));
+ bindingColumnNames_.append(bindingName);
+ }
+}
+
+void SqliteStatement::setColumnCount()
+{
+ columnCount_ = sqlite3_column_count(compiledStatement.get());
+}
+
+void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const
+{
+ if (rowDictionary.isEmpty())
+ throwException("SqliteStatement::bind: can't bind empty row!");
+}
+
+bool SqliteStatement::isReadOnlyStatement() const
+{
+ return sqlite3_stmt_readonly(compiledStatement.get());
+}
+
+void SqliteStatement::throwException(const char *whatHasHappened)
+{
+ throw SqliteException(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
+}
+
+QString SqliteStatement::columnName(int column) const
+{
+ return QString::fromUtf8(sqlite3_column_name(compiledStatement.get(), column));
+}
+
+static bool columnIsBlob(sqlite3_stmt *sqlStatment, int column)
+{
+ return sqlite3_column_type(sqlStatment, column) == SQLITE_BLOB;
+}
+
+static QByteArray byteArrayForColumn(sqlite3_stmt *sqlStatment, int column)
+{
+ if (columnIsBlob(sqlStatment, column)) {
+ const char *blob = static_cast<const char*>(sqlite3_column_blob(sqlStatment, column));
+ int size = sqlite3_column_bytes(sqlStatment, column);
+
+ return QByteArray(blob, size);
+ }
+
+ return QByteArray();
+}
+
+static QString textForColumn(sqlite3_stmt *sqlStatment, int column)
+{
+ const QChar *text = static_cast<const QChar*>(sqlite3_column_text16(sqlStatment, column));
+ int size = sqlite3_column_bytes16(sqlStatment, column) / 2;
+
+ return QString(text, size);
+}
+
+static Utf8String utf8TextForColumn(sqlite3_stmt *sqlStatment, int column)
+{
+ const char *text = reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
+ int size = sqlite3_column_bytes(sqlStatment, column);
+
+ return Utf8String(text, size);
+}
+
+
+static Utf8String convertedToUtf8StringForColumn(sqlite3_stmt *sqlStatment, int column)
+{
+ int dataType = sqlite3_column_type(sqlStatment, column);
+ switch (dataType) {
+ case SQLITE_INTEGER: return Utf8String::fromByteArray(QByteArray::number(sqlite3_column_int64(sqlStatment, column)));
+ case SQLITE_FLOAT: return Utf8String::fromByteArray(QByteArray::number(sqlite3_column_double(sqlStatment, column)));
+ case SQLITE_BLOB: return Utf8String();
+ case SQLITE3_TEXT: return utf8TextForColumn(sqlStatment, column);
+ case SQLITE_NULL: return Utf8String();
+ }
+
+ Q_UNREACHABLE();
+}
+
+
+static QVariant variantForColumn(sqlite3_stmt *sqlStatment, int column)
+{
+ int dataType = sqlite3_column_type(sqlStatment, column);
+ switch (dataType) {
+ case SQLITE_INTEGER: return QVariant::fromValue(sqlite3_column_int64(sqlStatment, column));
+ case SQLITE_FLOAT: return QVariant::fromValue(sqlite3_column_double(sqlStatment, column));
+ case SQLITE_BLOB: return QVariant::fromValue(byteArrayForColumn(sqlStatment, column));
+ case SQLITE3_TEXT: return QVariant::fromValue(textForColumn(sqlStatment, column));
+ case SQLITE_NULL: return QVariant();
+ }
+
+ Q_UNREACHABLE();
+}
+
+template<>
+int SqliteStatement::value<int>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return sqlite3_column_int(compiledStatement.get(), column);
+}
+
+template<>
+qint64 SqliteStatement::value<qint64>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return sqlite3_column_int64(compiledStatement.get(), column);
+}
+
+template<>
+double SqliteStatement::value<double>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return sqlite3_column_double(compiledStatement.get(), column);
+}
+
+template<>
+QByteArray SqliteStatement::value<QByteArray>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return byteArrayForColumn(compiledStatement.get(), column);
+}
+
+template<>
+Utf8String SqliteStatement::value<Utf8String>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return convertedToUtf8StringForColumn(compiledStatement.get(), column);
+}
+
+template<>
+QString SqliteStatement::value<QString>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return textForColumn(compiledStatement.get(), column);
+}
+
+template<>
+QVariant SqliteStatement::value<QVariant>(int column) const
+{
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return variantForColumn(compiledStatement.get(), column);
+}
+
+template <typename ContainerType>
+ ContainerType SqliteStatement::columnValues(const QVector<int> &columnIndices) const
+{
+ typedef typename ContainerType::value_type ElementType;
+ ContainerType valueContainer;
+ valueContainer.reserve(columnIndices.count());
+ for (int columnIndex : columnIndices)
+ valueContainer += value<ElementType>(columnIndex);
+
+ return valueContainer;
+}
+
+QMap<QString, QVariant> SqliteStatement::rowColumnValueMap() const
+{
+ QMap<QString, QVariant> values;
+
+ reset();
+
+ if (next()) {
+ for (int column = 0; column < columnCount(); column++)
+ values.insert(columnName(column), variantForColumn(compiledStatement.get(), column));
+ }
+
+ return values;
+}
+
+QMap<QString, QVariant> SqliteStatement::twoColumnValueMap() const
+{
+ QMap<QString, QVariant> values;
+
+ reset();
+
+ while (next())
+ values.insert(textForColumn(compiledStatement.get(), 0), variantForColumn(compiledStatement.get(), 1));
+
+ return values;
+}
+
+template <typename ContainerType>
+ContainerType SqliteStatement::values(const QVector<int> &columns, int size) const
+{
+ checkColumnsAreValid(columns);
+
+ ContainerType resultValues;
+ resultValues.reserve(size);
+
+ reset();
+
+ while (next()) {
+ resultValues += columnValues<ContainerType>(columns);
+ }
+
+ return resultValues;
+}
+
+template SQLITE_EXPORT QVector<QVariant> SqliteStatement::values<QVector<QVariant>>(const QVector<int> &columnIndices, int size) const;
+template SQLITE_EXPORT QVector<Utf8String> SqliteStatement::values<QVector<Utf8String>>(const QVector<int> &columnIndices, int size) const;
+
+template <typename ContainerType>
+ContainerType SqliteStatement::values(int column) const
+{
+ typedef typename ContainerType::value_type ElementType;
+ ContainerType resultValues;
+
+ reset();
+
+ while (next()) {
+ resultValues += value<ElementType>(column);
+ }
+
+ return resultValues;
+}
+
+template SQLITE_EXPORT QVector<qint64> SqliteStatement::values<QVector<qint64>>(int column) const;
+template SQLITE_EXPORT QVector<double> SqliteStatement::values<QVector<double>>(int column) const;
+template SQLITE_EXPORT QVector<QByteArray> SqliteStatement::values<QVector<QByteArray>>(int column) const;
+template SQLITE_EXPORT Utf8StringVector SqliteStatement::values<Utf8StringVector>(int column) const;
+template SQLITE_EXPORT QVector<QString> SqliteStatement::values<QVector<QString>>(int column) const;
+
+template <typename Type>
+Type SqliteStatement::toValue(const Utf8String &sqlStatementUtf8)
+{
+ SqliteStatement statement(sqlStatementUtf8);
+
+ statement.next();
+
+ return statement.value<Type>(0);
+}
+
+template SQLITE_EXPORT int SqliteStatement::toValue<int>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT qint64 SqliteStatement::toValue<qint64>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT double SqliteStatement::toValue<double>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT QString SqliteStatement::toValue<QString>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT QByteArray SqliteStatement::toValue<QByteArray>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT Utf8String SqliteStatement::toValue<Utf8String>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT QVariant SqliteStatement::toValue<QVariant>(const Utf8String &sqlStatementUtf8);
+
diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitestatement.h
new file mode 100644
index 0000000000..7c19af335a
--- /dev/null
+++ b/src/libs/sqlite/sqlitestatement.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITESTATEMENT_H
+#define SQLITESTATEMENT_H
+
+#include <type_traits>
+#include <memory>
+
+#include <QString>
+#include <QVariant>
+#include <QVector>
+
+#include "sqliteglobal.h"
+
+struct sqlite3_stmt;
+struct sqlite3;
+
+#include "sqliteexception.h"
+#include "utf8stringvector.h"
+
+
+
+class SQLITE_EXPORT SqliteStatement
+{
+protected:
+ explicit SqliteStatement(const Utf8String &sqlStatementUtf8);
+
+ static void deleteCompiledStatement(sqlite3_stmt *compiledStatement);
+
+ bool next() const;
+ void step() const;
+ void reset() const;
+
+ template<typename Type>
+ Type value(int column) const;
+ int columnCount() const;
+ Utf8StringVector columnNames() const;
+
+ void bind(int index, int value);
+ void bind(int index, qint64 value);
+ void bind(int index, double value);
+ void bind(int index, const QString &text);
+ void bind(int index, const QByteArray &blob);
+ void bind(int index, const QVariant &value);
+
+ template <typename Type>
+ void bind(const Utf8String &name, const Type &value);
+
+ int bindingIndexForName(const Utf8String &name);
+
+ void bind(const RowDictionary &rowDictionary);
+ void bindUnchecked(const RowDictionary &rowDictionary);
+
+ void setBindingColumnNames(const Utf8StringVector &bindingColumnNames);
+ const Utf8StringVector &bindingColumnNames() const;
+
+ template <typename ContainerType>
+ ContainerType values(const QVector<int> &columns, int size = 0) const;
+
+ template <typename ContainerType>
+ ContainerType values(int column = 0) const;
+
+ QMap<QString, QVariant> rowColumnValueMap() const;
+ QMap<QString, QVariant> twoColumnValueMap() const;
+
+ static void execute(const Utf8String &sqlStatementUtf8);
+
+ template <typename Type>
+ static Type toValue(const Utf8String &sqlStatementUtf8);
+
+ void prepare(const Utf8String &sqlStatementUtf8);
+ void waitForUnlockNotify() const;
+
+ void write(const RowDictionary &rowDictionary);
+ void writeUnchecked(const RowDictionary &rowDictionary);
+
+ static sqlite3 *sqliteDatabaseHandle();
+ static TextEncoding databaseTextEncoding();
+
+
+ bool checkForStepError(int resultCode) const;
+ void checkForPrepareError(int resultCode) const;
+ void setIfIsReadyToFetchValues(int resultCode) const;
+ void checkIfIsReadyToFetchValues() const;
+ void checkColumnsAreValid(const QVector<int> &columns) const;
+ void checkColumnIsValid(int column) const;
+ void checkBindingIndex(int index) const;
+ void checkBindingName(int index) const;
+ void checkParameterCanBeBound(const RowDictionary &rowDictionary, const Utf8String &columnName);
+ void setBindingParameterCount();
+ void setBindingColumnNamesFromStatement();
+ void setColumnCount();
+ void checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const;
+ bool isReadOnlyStatement() const;
+ Q_NORETURN static void throwException(const char *whatHasHappened);
+
+ template <typename ContainerType>
+ ContainerType columnValues(const QVector<int> &columnIndices) const;
+
+ QString columnName(int column) const;
+
+private:
+ std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> compiledStatement;
+ Utf8StringVector bindingColumnNames_;
+ int bindingParameterCount;
+ int columnCount_;
+ mutable bool isReadyToFetchValues;
+};
+
+#endif // SQLITESTATEMENT_H
diff --git a/src/libs/sqlite/sqlitetable.cpp b/src/libs/sqlite/sqlitetable.cpp
new file mode 100644
index 0000000000..8135dfde83
--- /dev/null
+++ b/src/libs/sqlite/sqlitetable.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitetable.h"
+
+#include "sqlitecolumn.h"
+#include "sqlitedatabase.h"
+
+SqliteTable::SqliteTable()
+ : withoutRowId(false)
+{
+
+}
+
+SqliteTable::~SqliteTable()
+{
+ qDeleteAll(sqliteColumns);
+}
+
+void SqliteTable::setName(const Utf8String &name)
+{
+ tableName = name;
+}
+
+const Utf8String &SqliteTable::name() const
+{
+ return tableName;
+}
+
+void SqliteTable::setUseWithoutRowId(bool useWithoutWorId)
+{
+ withoutRowId = useWithoutWorId;
+}
+
+bool SqliteTable::useWithoutRowId() const
+{
+ return withoutRowId;
+}
+
+void SqliteTable::addColumn(SqliteColumn *newColumn)
+{
+ sqliteColumns.append(newColumn);
+}
+
+const QVector<SqliteColumn *> &SqliteTable::columns() const
+{
+ return sqliteColumns;
+}
+
+void SqliteTable::setSqliteDatabase(SqliteDatabase *database)
+{
+ sqliteDatabase = database;
+ writeWorker.moveWorkerToThread(sqliteDatabase->writeWorkerThread());
+}
+
+void SqliteTable::initialize()
+{
+ writeWorker.connectWithWorker(this);
+
+ writeWorker.createTable(createTableCommand());
+}
+
+void SqliteTable::shutdown()
+{
+ writeWorker.disconnectWithWorker(this);
+}
+
+void SqliteTable::handleTableCreated()
+{
+ emit tableIsReady();
+}
+
+Internal::CreateTableCommand SqliteTable::createTableCommand() const
+{
+ Internal::CreateTableCommand createTableCommand;
+
+ createTableCommand.tableName = tableName;
+ createTableCommand.useWithoutRowId = withoutRowId;
+ createTableCommand.definitions = createColumnDefintions();
+
+ return createTableCommand;
+}
+
+QVector<Internal::ColumnDefinition> SqliteTable::createColumnDefintions() const
+{
+ QVector<Internal::ColumnDefinition> columnDefintions;
+
+ for (SqliteColumn *sqliteColumn: sqliteColumns)
+ columnDefintions.append(sqliteColumn->columnDefintion());
+
+ return columnDefintions;
+}
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
new file mode 100644
index 0000000000..ed4be02462
--- /dev/null
+++ b/src/libs/sqlite/sqlitetable.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITETABLE_H
+#define SQLITETABLE_H
+
+#include <QObject>
+#include <QVector>
+#include "utf8string.h"
+
+#include "sqliteglobal.h"
+#include "tablewriteworkerproxy.h"
+
+class SqliteColumn;
+class SqliteDatabase;
+
+class SQLITE_EXPORT SqliteTable : public QObject
+{
+ Q_OBJECT
+
+ friend class Internal::TableWriteWorkerProxy;
+
+public:
+ SqliteTable();
+ ~SqliteTable();
+
+ void setName(const Utf8String &name);
+ const Utf8String &name() const;
+
+ void setUseWithoutRowId(bool useWithoutWorId);
+ bool useWithoutRowId() const;
+
+ void addColumn(SqliteColumn *newColumn);
+ const QVector<SqliteColumn *> &columns() const;
+
+ void setSqliteDatabase(SqliteDatabase *database);
+
+ void initialize();
+ void shutdown();
+
+signals:
+ void tableIsReady();
+
+private:
+ void handleTableCreated();
+ Internal::CreateTableCommand createTableCommand() const;
+ QVector<Internal::ColumnDefinition> createColumnDefintions() const;
+
+private:
+ Internal::TableWriteWorkerProxy writeWorker;
+ QVector<SqliteColumn*> sqliteColumns;
+ Utf8String tableName;
+ SqliteDatabase *sqliteDatabase;
+ bool withoutRowId;
+};
+
+#endif // SQLITETABLE_H
diff --git a/src/libs/sqlite/sqlitetransaction.cpp b/src/libs/sqlite/sqlitetransaction.cpp
new file mode 100644
index 0000000000..6e2b757569
--- /dev/null
+++ b/src/libs/sqlite/sqlitetransaction.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitetransaction.h"
+
+#include "sqlitewritestatement.h"
+
+
+SqliteAbstractTransaction::~SqliteAbstractTransaction()
+{
+ if (!isAlreadyCommited)
+ SqliteWriteStatement::execute(Utf8StringLiteral("ROLLBACK"));
+}
+
+void SqliteAbstractTransaction::commit()
+{
+ SqliteWriteStatement::execute(Utf8StringLiteral("COMMIT"));
+ isAlreadyCommited = true;
+}
+
+SqliteTransaction::SqliteTransaction()
+{
+ SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN"));
+}
+
+SqliteImmediateTransaction::SqliteImmediateTransaction()
+{
+ SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN IMMEDIATE"));
+}
+
+SqliteExclusiveTransaction::SqliteExclusiveTransaction()
+{
+ SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN EXCLUSIVE"));
+}
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h
new file mode 100644
index 0000000000..5c994b5614
--- /dev/null
+++ b/src/libs/sqlite/sqlitetransaction.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITETRANSACTION_H
+#define SQLITETRANSACTION_H
+
+#include "sqliteglobal.h"
+
+class SQLITE_EXPORT SqliteAbstractTransaction
+{
+public:
+ virtual ~SqliteAbstractTransaction();
+
+ void commit();
+
+private:
+ bool isAlreadyCommited = false;
+};
+
+
+class SQLITE_EXPORT SqliteTransaction final : public SqliteAbstractTransaction
+{
+public:
+ SqliteTransaction();
+
+};
+
+class SQLITE_EXPORT SqliteImmediateTransaction final : public SqliteAbstractTransaction
+{
+public:
+ SqliteImmediateTransaction();
+
+};
+
+class SQLITE_EXPORT SqliteExclusiveTransaction final : public SqliteAbstractTransaction
+{
+public:
+ SqliteExclusiveTransaction();
+
+};
+
+
+#endif // SQLITETRANSACTION_H
diff --git a/src/libs/sqlite/sqliteworkerthread.cpp b/src/libs/sqlite/sqliteworkerthread.cpp
new file mode 100644
index 0000000000..8789a6e7d5
--- /dev/null
+++ b/src/libs/sqlite/sqliteworkerthread.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#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;
+}
diff --git a/src/libs/sqlite/sqliteworkerthread.h b/src/libs/sqlite/sqliteworkerthread.h
new file mode 100644
index 0000000000..5a504a69aa
--- /dev/null
+++ b/src/libs/sqlite/sqliteworkerthread.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEWORKERTHREAD_H
+#define SQLITEWORKERTHREAD_H
+
+#include <QThread>
+#include <QPointer>
+#include <QMutex>
+#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;
+};
+
+#endif // SQLITEWORKERTHREAD_H
diff --git a/src/libs/sqlite/sqlitewritestatement.cpp b/src/libs/sqlite/sqlitewritestatement.cpp
new file mode 100644
index 0000000000..7effb9618b
--- /dev/null
+++ b/src/libs/sqlite/sqlitewritestatement.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlitewritestatement.h"
+
+SqliteWriteStatement::SqliteWriteStatement(const Utf8String &sqlStatementUtf8)
+ : SqliteStatement(sqlStatementUtf8)
+{
+ checkIsWritableStatement();
+}
+
+void SqliteWriteStatement::checkIsWritableStatement()
+{
+ if (isReadOnlyStatement())
+ throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
+}
diff --git a/src/libs/sqlite/sqlitewritestatement.h b/src/libs/sqlite/sqlitewritestatement.h
new file mode 100644
index 0000000000..c8d9b31845
--- /dev/null
+++ b/src/libs/sqlite/sqlitewritestatement.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLITEWRITESTATEMENT_H
+#define SQLITEWRITESTATEMENT_H
+
+#include "sqlitestatement.h"
+
+class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement
+{
+public:
+ explicit SqliteWriteStatement(const Utf8String &sqlStatementUtf8);
+
+ using SqliteStatement::step;
+ using SqliteStatement::reset;
+ using SqliteStatement::bind;
+ using SqliteStatement::bindUnchecked;
+ using SqliteStatement::bindingIndexForName;
+ using SqliteStatement::setBindingColumnNames;
+ using SqliteStatement::bindingColumnNames;
+ using SqliteStatement::write;
+ using SqliteStatement::writeUnchecked;
+ using SqliteStatement::execute;
+
+protected:
+ void checkIsWritableStatement();
+};
+
+#endif // SQLITEWRITESTATEMENT_H
diff --git a/src/libs/sqlite/sqlstatementbuilder.cpp b/src/libs/sqlite/sqlstatementbuilder.cpp
new file mode 100644
index 0000000000..9f73907b2e
--- /dev/null
+++ b/src/libs/sqlite/sqlstatementbuilder.cpp
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlstatementbuilder.h"
+
+#include "sqlstatementbuilderexception.h"
+#include "utf8stringvector.h"
+
+#include <algorithm>
+
+SqlStatementBuilder::SqlStatementBuilder(const Utf8String &sqlTemplate)
+ : sqlTemplate(sqlTemplate)
+{
+}
+
+void SqlStatementBuilder::bindEmptyText(const Utf8String &name)
+{
+ clearSqlStatement();
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, Utf8String());
+}
+
+void SqlStatementBuilder::bind(const Utf8String &name, const Utf8String &text)
+{
+ clearSqlStatement();
+ checkBindingTextIsNotEmpty(text);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, text);
+}
+
+void SqlStatementBuilder::bind(const Utf8String &name, const Utf8StringVector &textVector)
+{
+ clearSqlStatement();
+ checkBindingTextVectorIsNotEmpty(textVector);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, textVector.join(Utf8StringLiteral(", ")));
+}
+
+void SqlStatementBuilder::bind(const Utf8String &name, int value)
+{
+ clearSqlStatement();
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, Utf8String::number(value));
+}
+
+void SqlStatementBuilder::bind(const Utf8String &name, const QVector<int> &integerVector)
+{
+ clearSqlStatement();
+ checkBindingIntegerVectorIsNotEmpty(integerVector);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, Utf8StringVector::fromIntegerVector(integerVector).join(Utf8StringLiteral(", ")));
+}
+
+void SqlStatementBuilder::bindWithInsertTemplateParameters(const Utf8String &name, const Utf8StringVector &columns)
+{
+ clearSqlStatement();
+ checkBindingTextVectorIsNotEmpty(columns);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, insertTemplateParameters(columns));
+}
+
+void SqlStatementBuilder::bindWithUpdateTemplateParameters(const Utf8String &name, const Utf8StringVector &columns)
+{
+ clearSqlStatement();
+ checkBindingTextVectorIsNotEmpty(columns);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, updateTemplateParameters(columns));
+}
+
+void SqlStatementBuilder::bindWithUpdateTemplateNames(const Utf8String &name, const Utf8StringVector &columns)
+{
+ clearSqlStatement();
+ checkBindingTextVectorIsNotEmpty(columns);
+ checkIfPlaceHolderExists(name);
+ changeBinding(name, updateTemplateNames(columns));
+}
+
+void SqlStatementBuilder::clear()
+{
+ bindings.clear();
+ sqlStatement_.clear();
+}
+
+const Utf8String SqlStatementBuilder::insertTemplateParameters(const Utf8StringVector &columns)
+{
+ const Utf8StringVector templateParamters(columns.count(), Utf8StringLiteral("?"));
+
+ return templateParamters.join(Utf8StringLiteral(", "));
+}
+
+const Utf8String SqlStatementBuilder::updateTemplateParameters(const Utf8StringVector &columns)
+{
+ Utf8String templateParamters = columns.join(Utf8StringLiteral("=?, "));
+ templateParamters.append(Utf8StringLiteral("=?"));
+
+ return templateParamters;
+}
+
+const Utf8String SqlStatementBuilder::updateTemplateNames(const Utf8StringVector &columns)
+{
+ Utf8StringVector templateNames;
+
+ foreach (const Utf8String &columnName, columns)
+ templateNames.append(columnName+Utf8StringLiteral("=@")+columnName);
+
+ return templateNames.join(Utf8StringLiteral(", "));
+}
+
+void SqlStatementBuilder::sortBindings() const
+{
+ std::sort(bindings.begin(), 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();
+ });
+}
+
+Utf8String SqlStatementBuilder::sqlStatement() const
+{
+ if (!isBuild())
+ generateSqlStatement();
+
+ return sqlStatement_;
+}
+
+bool SqlStatementBuilder::isBuild() const
+{
+ return sqlStatement_.hasContent();
+}
+
+Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
+{
+ switch (columnType) {
+ case ColumnType::Numeric: return Utf8StringLiteral("NUMERIC");
+ case ColumnType::Integer: return Utf8StringLiteral("INTEGER");
+ case ColumnType::Real: return Utf8StringLiteral("REAL");
+ case ColumnType::Text: return Utf8StringLiteral("TEXT");
+ case ColumnType::None: return Utf8String();
+ }
+
+ Q_UNREACHABLE();
+}
+
+void SqlStatementBuilder::generateSqlStatement() const
+{
+ sqlStatement_ = sqlTemplate;
+
+ sortBindings();
+
+ auto bindingIterator = bindings.cbegin();
+ while (bindingIterator != bindings.cend()) {
+ const Utf8String &placeHolderToken = bindingIterator->first;
+ const Utf8String &replacementToken = bindingIterator->second;
+ sqlStatement_.replace(placeHolderToken, replacementToken);
+ ++bindingIterator;
+ }
+
+ checkIfNoPlaceHoldersAynmoreExists();
+}
+
+void SqlStatementBuilder::changeBinding(const Utf8String &name, const Utf8String &text)
+{
+
+ auto findBindingIterator = std::find_if(bindings.begin(), bindings.end(), [name] (const BindingPair &binding) {
+ return binding.first == name;
+ });
+
+ if (findBindingIterator == bindings.end())
+ bindings.push_back(std::make_pair(name, text));
+ else
+ findBindingIterator->second = text;
+}
+
+void SqlStatementBuilder::clearSqlStatement()
+{
+ sqlStatement_.clear();
+}
+
+void SqlStatementBuilder::checkIfPlaceHolderExists(const Utf8String &name) const
+{
+ if (name.byteSize() < 2 || !name.startsWith('$') || !sqlTemplate.contains(name))
+ throwException("SqlStatementBuilder::bind: placeholder name does not exists!", name.constData());
+}
+
+void SqlStatementBuilder::checkIfNoPlaceHoldersAynmoreExists() const
+{
+ if (sqlStatement_.contains('$'))
+ throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", sqlTemplate.constData());
+}
+
+void SqlStatementBuilder::checkBindingTextIsNotEmpty(const Utf8String &text) const
+{
+ if (text.isEmpty())
+ throwException("SqlStatementBuilder::bind: binding text it empty!", sqlTemplate.constData());
+}
+
+void SqlStatementBuilder::checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const
+{
+ if (textVector.isEmpty())
+ throwException("SqlStatementBuilder::bind: binding text vector it empty!", sqlTemplate.constData());
+}
+
+void SqlStatementBuilder::checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const
+{
+ if (integerVector.isEmpty())
+ throwException("SqlStatementBuilder::bind: binding integer vector it empty!", sqlTemplate.constData());
+}
+
+void SqlStatementBuilder::throwException(const char *whatHasHappened, const char *errorMessage)
+{
+ throw SqlStatementBuilderException(whatHasHappened, errorMessage);
+}
diff --git a/src/libs/sqlite/sqlstatementbuilder.h b/src/libs/sqlite/sqlstatementbuilder.h
new file mode 100644
index 0000000000..5fcd3d51f0
--- /dev/null
+++ b/src/libs/sqlite/sqlstatementbuilder.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLSTATEMENTBUILDER_H
+#define SQLSTATEMENTBUILDER_H
+
+#include <vector>
+#include <utility>
+
+#include "utf8string.h"
+
+class SQLITE_EXPORT SqlStatementBuilder
+{
+ using BindingPair = std::pair<Utf8String, Utf8String>;
+public:
+ SqlStatementBuilder(const Utf8String &sqlTemplate);
+
+ void bindEmptyText(const Utf8String &name);
+ void bind(const Utf8String &name, const Utf8String &text);
+ void bind(const Utf8String &name, const Utf8StringVector &textVector);
+ void bind(const Utf8String &name, int value);
+ void bind(const Utf8String &name, const QVector<int> &integerVector);
+ void bindWithInsertTemplateParameters(const Utf8String &name, const Utf8StringVector &columns);
+ void bindWithUpdateTemplateParameters(const Utf8String &name, const Utf8StringVector &columns);
+ void bindWithUpdateTemplateNames(const Utf8String &name, const Utf8StringVector &columns);
+ void clear();
+
+ Utf8String sqlStatement() const;
+
+ bool isBuild() const;
+
+ static Utf8String columnTypeToString(ColumnType columnType);
+
+protected:
+ static const Utf8String insertTemplateParameters(const Utf8StringVector &columns);
+ static const Utf8String updateTemplateParameters(const Utf8StringVector &columns);
+ static const Utf8String updateTemplateNames(const Utf8StringVector &columns);
+
+ void sortBindings() const;
+ void generateSqlStatement() const;
+
+ void changeBinding(const Utf8String &name, const Utf8String &text);
+
+ void clearSqlStatement();
+ void checkIfPlaceHolderExists(const Utf8String &name) const;
+ void checkIfNoPlaceHoldersAynmoreExists() const;
+ void checkBindingTextIsNotEmpty(const Utf8String &text) const;
+ void checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const;
+ void checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const;
+
+ Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage);
+
+private:
+ Utf8String sqlTemplate;
+ mutable Utf8String sqlStatement_;
+ mutable std::vector<BindingPair> bindings;
+};
+
+#endif // SQLSTATEMENTBUILDER_H
diff --git a/src/libs/sqlite/sqlstatementbuilderexception.cpp b/src/libs/sqlite/sqlstatementbuilderexception.cpp
new file mode 100644
index 0000000000..65addc681f
--- /dev/null
+++ b/src/libs/sqlite/sqlstatementbuilderexception.cpp
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sqlstatementbuilderexception.h"
+
+SqlStatementBuilderException::SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage)
+ : SqliteException(whatErrorHasHappen, errorMessage)
+{
+}
diff --git a/src/libs/sqlite/sqlstatementbuilderexception.h b/src/libs/sqlite/sqlstatementbuilderexception.h
new file mode 100644
index 0000000000..ef3943ba7f
--- /dev/null
+++ b/src/libs/sqlite/sqlstatementbuilderexception.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SQLSTATEMENTBUILDEREXCEPTION_H
+#define SQLSTATEMENTBUILDEREXCEPTION_H
+
+#include "sqliteexception.h"
+
+class SQLITE_EXPORT SqlStatementBuilderException : public SqliteException
+{
+public:
+ SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage = 0);
+};
+
+#endif // SQLSTATEMENTBUILDEREXCEPTION_H
diff --git a/src/libs/sqlite/tablewriteworker.cpp b/src/libs/sqlite/tablewriteworker.cpp
new file mode 100644
index 0000000000..6a84909e0d
--- /dev/null
+++ b/src/libs/sqlite/tablewriteworker.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "tablewriteworker.h"
+
+#include "createtablesqlstatementbuilder.h"
+
+#include "sqlitewritestatement.h"
+#include "sqlitetransaction.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
+
diff --git a/src/libs/sqlite/tablewriteworker.h b/src/libs/sqlite/tablewriteworker.h
new file mode 100644
index 0000000000..b2a369add5
--- /dev/null
+++ b/src/libs/sqlite/tablewriteworker.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef INTERNAL_TABLEWRITEWORKER_H
+#define INTERNAL_TABLEWRITEWORKER_H
+
+#include <QObject>
+
+#include "createtablecommand.h"
+
+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
+
+#endif // INTERNAL_TABLEWRITEWORKER_H
diff --git a/src/libs/sqlite/tablewriteworkerproxy.cpp b/src/libs/sqlite/tablewriteworkerproxy.cpp
new file mode 100644
index 0000000000..b6df81bae4
--- /dev/null
+++ b/src/libs/sqlite/tablewriteworkerproxy.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "tablewriteworkerproxy.h"
+
+#include "tablewriteworker.h"
+#include "sqlitetable.h"
+
+#include "createtablecommand.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
+
diff --git a/src/libs/sqlite/tablewriteworkerproxy.h b/src/libs/sqlite/tablewriteworkerproxy.h
new file mode 100644
index 0000000000..4a1d4e0333
--- /dev/null
+++ b/src/libs/sqlite/tablewriteworkerproxy.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef INTERNAL_TABLEWRITEWORKERPROXY_H
+#define INTERNAL_TABLEWRITEWORKERPROXY_H
+
+#include <QObject>
+
+#include <memory>
+
+#include "createtablecommand.h"
+
+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
+
+#endif // INTERNAL_TABLEWRITEWORKERPROXY_H
diff --git a/src/libs/sqlite/utf8string.cpp b/src/libs/sqlite/utf8string.cpp
new file mode 100644
index 0000000000..2ad6d8491b
--- /dev/null
+++ b/src/libs/sqlite/utf8string.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "utf8string.h"
+
+#include "utf8stringvector.h"
+
+#include <QString>
+#include <QDebug>
+
+#ifdef QT_TESTLIB_LIB
+#include <QTest>
+#endif
+
+#include <QDataStream>
+
+#include <ostream>
+
+Utf8String::Utf8String(const char *utf8Text, int size)
+ : byteArray(utf8Text, size)
+{
+}
+
+Utf8String::Utf8String(const QString &text)
+ : byteArray(text.toUtf8())
+{
+}
+
+const char *Utf8String::constData() const
+{
+ return byteArray.constData();
+}
+
+int Utf8String::byteSize() const
+{
+ return byteArray.size();
+}
+
+Utf8String Utf8String::fromUtf8(const char *utf8Text)
+{
+ return Utf8String(utf8Text, -1);
+}
+
+Utf8String::Utf8String(const QByteArray &utf8ByteArray)
+ : byteArray(utf8ByteArray)
+{
+}
+
+Utf8String Utf8String::fromByteArray(const QByteArray &utf8ByteArray)
+{
+ return Utf8String(utf8ByteArray);
+}
+
+const QByteArray &Utf8String::toByteArray() const
+{
+ return byteArray;
+}
+
+Utf8String Utf8String::fromString(const QString &text)
+{
+ return Utf8String::fromByteArray(text.toUtf8());
+}
+
+QString Utf8String::toString() const
+{
+ return QString::fromUtf8(byteArray, byteArray.size());
+}
+
+Utf8String Utf8String::mid(int position, int length) const
+{
+ return Utf8String(byteArray.mid(position, length));
+}
+
+void Utf8String::replace(const Utf8String &before, const Utf8String &after)
+{
+ byteArray.replace(before.byteArray, after.byteArray);
+}
+
+Utf8StringVector Utf8String::split(char separator) const
+{
+ Utf8StringVector utf8Vector;
+
+ foreach (const QByteArray &byteArray, byteArray.split(separator))
+ utf8Vector.append(Utf8String::fromByteArray(byteArray));
+
+ return utf8Vector;
+}
+
+void Utf8String::clear()
+{
+ byteArray.clear();
+}
+
+void Utf8String::append(const Utf8String &textToAppend)
+{
+ byteArray.append(textToAppend.byteArray);
+}
+
+bool Utf8String::contains(const Utf8String &text) const
+{
+ return byteArray.contains(text.byteArray);
+}
+
+bool Utf8String::contains(const char *text) const
+{
+ return byteArray.contains(text);
+}
+
+bool Utf8String::contains(char character) const
+{
+ return byteArray.contains(character);
+}
+
+bool Utf8String::startsWith(const Utf8String &text) const
+{
+ return byteArray.startsWith(text.byteArray);
+}
+
+bool Utf8String::startsWith(const char *text) const
+{
+ return byteArray.startsWith(text);
+}
+
+bool Utf8String::startsWith(char character) const
+{
+ return byteArray.startsWith(character);
+}
+
+bool Utf8String::isEmpty() const
+{
+ return byteArray.isEmpty();
+}
+
+bool Utf8String::hasContent() const
+{
+ return !isEmpty();
+}
+
+void Utf8String::reserve(int reserveSize)
+{
+ byteArray.reserve(reserveSize);
+}
+
+Utf8String Utf8String::number(int number, int base)
+{
+ return Utf8String::fromByteArray(QByteArray::number(number, base));
+}
+
+const Utf8String &Utf8String::operator+=(const Utf8String &text)
+{
+ byteArray += text.byteArray;
+
+ return *this;
+}
+
+void Utf8String::registerType()
+{
+ qRegisterMetaType<Utf8String>("Utf8String");
+}
+
+Utf8String::operator const QByteArray &() const
+{
+ return byteArray;
+}
+
+Utf8String::operator QString() const
+{
+ return toString();
+}
+
+const Utf8String operator +(const Utf8String &first, const Utf8String &second)
+{
+ return Utf8String(first.byteArray + second.byteArray);
+}
+
+
+bool operator !=(const Utf8String &first, const Utf8String &second)
+{
+ return first.byteArray != second.byteArray;
+}
+
+
+bool operator ==(const Utf8String &first, const Utf8String &second)
+{
+ return first.byteArray == second.byteArray;
+}
+
+bool operator ==(const Utf8String &first, const char *second)
+{
+ return first.byteArray == second;
+}
+
+bool operator <(const Utf8String &first, const Utf8String &second)
+{
+ if (first.byteSize() == second.byteSize())
+ return first.byteArray < second.byteArray;
+
+ return first.byteSize() < second.byteSize();
+}
+
+
+QDataStream &operator<<(QDataStream &datastream, const Utf8String &text)
+{
+ datastream << text.byteArray;
+
+ return datastream;
+}
+
+
+QDataStream &operator>>(QDataStream &datastream, Utf8String &text)
+{
+ datastream >> text.byteArray;
+
+ return datastream;
+}
+
+
+QDebug operator<<(QDebug debug, const Utf8String &text)
+{
+ debug << text.constData();
+
+ return debug;
+}
+
+void PrintTo(const Utf8String &text, ::std::ostream* os)
+{
+ *os << "\"" << text.toByteArray().data() << "\"";
+}
diff --git a/src/libs/sqlite/utf8string.h b/src/libs/sqlite/utf8string.h
new file mode 100644
index 0000000000..7461535a2a
--- /dev/null
+++ b/src/libs/sqlite/utf8string.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef UTF8STRING_H
+#define UTF8STRING_H
+
+#include <QByteArray>
+#include <QMetaType>
+
+#include "sqliteglobal.h"
+
+class Utf8StringVector;
+class Utf8String;
+
+class SQLITE_EXPORT Utf8String
+{
+ friend class Utf8StringVector;
+
+ friend SQLITE_EXPORT const Utf8String operator +(const Utf8String &first, const Utf8String &second);
+
+ friend SQLITE_EXPORT bool operator !=(const Utf8String &first, const Utf8String &second);
+ friend SQLITE_EXPORT bool operator ==(const Utf8String &first, const Utf8String &second);
+ friend SQLITE_EXPORT bool operator ==(const Utf8String &first, const char *second);
+ friend SQLITE_EXPORT bool operator <(const Utf8String &first, const Utf8String &second);
+
+ friend SQLITE_EXPORT QDataStream &operator<<(QDataStream &datastream, const Utf8String &text);
+ friend SQLITE_EXPORT QDataStream &operator>>(QDataStream &datastream, Utf8String &text);
+
+public:
+ Utf8String() = default;
+ explicit Utf8String(const char *utf8Text, int size);
+ Utf8String(const QString &text);
+
+ const char *constData() const;
+
+ int byteSize() const;
+
+ static Utf8String fromUtf8(const char *utf8Text);
+ static Utf8String fromByteArray(const QByteArray &utf8ByteArray);
+ const QByteArray &toByteArray() const;
+
+ static Utf8String fromString(const QString &text);
+ QString toString() const;
+
+ Utf8String mid(int position, int length = -1) const;
+ void replace(const Utf8String &before, const Utf8String &after);
+ Utf8StringVector split(char separator) const;
+
+ void clear();
+
+ void append(const Utf8String &textToAppend);
+ bool contains(const Utf8String &text) const;
+ bool contains(const char *text) const;
+ bool contains(char character) const;
+ bool startsWith(const Utf8String &text) const;
+ bool startsWith(const char *text) const;
+ bool startsWith(char character) const;
+ bool isEmpty() const;
+ bool hasContent() const;
+
+ void reserve(int reserveSize);
+
+ static Utf8String number(int number, int base=10);
+
+ const Utf8String &operator+=(const Utf8String &text);
+
+ static void registerType();
+
+ operator QString () const;
+ operator const QByteArray & () const;
+
+protected:
+ explicit Utf8String(const QByteArray &utf8ByteArray);
+
+private:
+ QByteArray byteArray;
+};
+
+SQLITE_EXPORT const Utf8String operator +(const Utf8String &first, const Utf8String &second);
+
+SQLITE_EXPORT bool operator !=(const Utf8String &first, const Utf8String &second);
+SQLITE_EXPORT bool operator ==(const Utf8String &first, const Utf8String &second);
+SQLITE_EXPORT bool operator ==(const Utf8String &first, const char *second);
+SQLITE_EXPORT bool operator <(const Utf8String &first, const Utf8String &second);
+
+SQLITE_EXPORT QDataStream &operator<<(QDataStream &datastream, const Utf8String &text);
+SQLITE_EXPORT QDataStream &operator>>(QDataStream &datastream, Utf8String &text);
+SQLITE_EXPORT QDebug operator<<(QDebug debug, const Utf8String &text);
+SQLITE_EXPORT void PrintTo(const Utf8String &text, ::std::ostream* os);
+
+#if defined(Q_COMPILER_LAMBDA)
+
+# define Utf8StringLiteral(str) \
+ ([]() -> Utf8String { \
+ enum { Size = sizeof(str) - 1 }; \
+ static const QStaticByteArrayData<Size> qbytearray_literal = { \
+ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
+ str }; \
+ QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
+ const QByteArray byteArray(holder); \
+ return Utf8String::fromByteArray(byteArray); \
+ }()) \
+ /**/
+
+#endif
+
+#ifndef Utf8StringLiteral
+// no lambdas, not GCC, just return a temporary QByteArray
+
+# define Utf8StringLiteral(str) Utf8String(str, sizeof(str) - 1)
+#endif
+
+Q_DECLARE_METATYPE(Utf8String)
+
+#endif // UTF8STRING_H
diff --git a/src/libs/sqlite/utf8stringvector.cpp b/src/libs/sqlite/utf8stringvector.cpp
new file mode 100644
index 0000000000..0c60551e96
--- /dev/null
+++ b/src/libs/sqlite/utf8stringvector.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "utf8stringvector.h"
+
+#include <QStringList>
+#include <QDebug>
+
+#include <ostream>
+
+Utf8StringVector::Utf8StringVector()
+{
+}
+
+Utf8StringVector::Utf8StringVector(std::initializer_list<Utf8String> initializerList)
+ : QVector<Utf8String>(initializerList)
+{
+
+}
+
+Utf8StringVector::Utf8StringVector(const Utf8String &utf8String)
+{
+ append(utf8String);
+}
+
+Utf8StringVector::Utf8StringVector(const QVector<Utf8String> &vector)
+ : QVector<Utf8String>(vector)
+{
+
+}
+
+Utf8StringVector::Utf8StringVector(const QStringList &stringList)
+{
+ reserve(stringList.count());
+
+ foreach (const QString &string, stringList)
+ append(Utf8String(string));
+}
+
+Utf8StringVector::Utf8StringVector(int size, const Utf8String &text)
+ : QVector<Utf8String>(size, text)
+{
+}
+
+Utf8String Utf8StringVector::join(const Utf8String &separator) const
+{
+ Utf8String joindedString;
+
+ joindedString.reserve(totalByteSize() + separator.byteSize() * count());
+
+ for (auto position = begin(); position != end(); ++position) {
+ joindedString.append(*position);
+ if (std::next(position) != end())
+ joindedString.append(separator);
+ }
+
+ return joindedString;
+}
+
+Utf8StringVector Utf8StringVector::fromIntegerVector(const QVector<int> &integerVector)
+{
+ Utf8StringVector utf8StringVector;
+ utf8StringVector.reserve(integerVector.count());
+
+ foreach (int integer, integerVector)
+ utf8StringVector.append(Utf8String::number(integer));
+
+ return utf8StringVector;
+}
+
+void Utf8StringVector::registerType()
+{
+ qRegisterMetaType<Utf8StringVector>("Utf8StringVector");
+}
+
+int Utf8StringVector::totalByteSize() const
+{
+ int totalSize = 0;
+
+ for (const Utf8String &utf8String : *this)
+ totalSize += utf8String.byteSize();
+
+ return totalSize;
+}
+
+QDebug operator<<(QDebug debug, const Utf8StringVector &textVector)
+{
+ debug << "Utf8StringVector(" << textVector.join(Utf8StringLiteral(", ")).constData() << ")";
+
+ return debug;
+}
+
+void PrintTo(const Utf8StringVector &textVector, ::std::ostream* os)
+{
+ *os << "Utf8StringVector(" << textVector.join(Utf8StringLiteral(", ")).constData() << ")";
+}
diff --git a/src/libs/sqlite/utf8stringvector.h b/src/libs/sqlite/utf8stringvector.h
new file mode 100644
index 0000000000..f8ee679e8d
--- /dev/null
+++ b/src/libs/sqlite/utf8stringvector.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef UTF8STRINGVECTOR_H
+#define UTF8STRINGVECTOR_H
+
+#include "utf8string.h"
+
+#include <QVector>
+
+#include "sqliteglobal.h"
+
+class SQLITE_EXPORT Utf8StringVector : public QVector<Utf8String>
+{
+public:
+ Utf8StringVector();
+ Utf8StringVector(std::initializer_list<Utf8String> initializerList);
+ explicit Utf8StringVector(const Utf8String &utf8String);
+ Utf8StringVector(const QVector<Utf8String> &vector);
+ explicit Utf8StringVector(const QStringList &stringList);
+ explicit Utf8StringVector(int size, const Utf8String &text);
+
+ Utf8String join(const Utf8String &separator) const;
+
+ static Utf8StringVector fromIntegerVector(const QVector<int> &integerVector);
+
+ static void registerType();
+
+ inline bool removeFast(const Utf8String &valueToBeRemoved);
+
+protected:
+ int totalByteSize() const;
+};
+
+bool Utf8StringVector::removeFast(const Utf8String &valueToBeRemoved)
+{
+ auto position = std::remove(begin(), end(), valueToBeRemoved);
+
+ bool hasEntry = position != end();
+
+ erase(position, end());
+
+ return hasEntry;
+}
+
+
+SQLITE_EXPORT QDebug operator<<(QDebug debug, const Utf8StringVector &textVector);
+SQLITE_EXPORT void PrintTo(const Utf8StringVector &textVector, ::std::ostream* os);
+
+Q_DECLARE_METATYPE(Utf8StringVector)
+
+#endif // UTF8STRINGVECTOR_H