diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
index c543d28de396e2963e5c4229c0d08df2ed80d8d8..dfdc779faaddb868b70f504e3e3bc2755efcf549 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.cpp
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
@@ -28,12 +28,11 @@
 namespace Sqlite {
 
 CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
-    : m_sqlStatementBuilder("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId"),
-      m_useWithoutRowId(false)
+    : m_sqlStatementBuilder("CREATE $temporaryTABLE $ifNotExits$table($columnDefinitions)$withoutRowId")
 {
 }
 
-void CreateTableSqlStatementBuilder::setTable(Utils::SmallString &&tableName)
+void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName)
 {
     m_sqlStatementBuilder.clear();
 
@@ -42,11 +41,11 @@ void CreateTableSqlStatementBuilder::setTable(Utils::SmallString &&tableName)
 
 void CreateTableSqlStatementBuilder::addColumn(Utils::SmallString &&columnName,
                                                ColumnType columnType,
-                                               IsPrimaryKey isPrimaryKey)
+                                               Contraint constraint)
 {
     m_sqlStatementBuilder.clear();
 
-    m_columns.emplace_back(std::move(columnName), columnType, isPrimaryKey);
+    m_columns.emplace_back(std::move(columnName), columnType, constraint);
 }
 
 void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
@@ -61,6 +60,16 @@ void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
     m_useWithoutRowId = useWithoutRowId;
 }
 
+void CreateTableSqlStatementBuilder::setUseIfNotExists(bool useIfNotExists)
+{
+    m_useIfNotExits = useIfNotExists;
+}
+
+void CreateTableSqlStatementBuilder::setUseTemporaryTable(bool useTemporaryTable)
+{
+    m_useTemporaryTable = useTemporaryTable;
+}
+
 void CreateTableSqlStatementBuilder::clear()
 {
     m_sqlStatementBuilder.clear();
@@ -95,8 +104,11 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
     for (const SqliteColumn &columns : m_columns) {
         Utils::SmallString columnDefinitionString = {columns.name(), " ", columns.typeString()};
 
-        if (columns.isPrimaryKey())
-            columnDefinitionString.append(" PRIMARY KEY");
+        switch (columns.constraint()) {
+            case Contraint::PrimaryKey: columnDefinitionString.append(" PRIMARY KEY"); break;
+            case Contraint::Unique: columnDefinitionString.append(" UNIQUE"); break;
+            case Contraint::NoConstraint: break;
+        }
 
         columnDefinitionStrings.push_back(columnDefinitionString);
     }
@@ -108,12 +120,34 @@ void CreateTableSqlStatementBuilder::bindAll() const
 {
     m_sqlStatementBuilder.bind("$table", m_tableName.clone());
 
+    bindTemporary();
+    bindIfNotExists();
     bindColumnDefinitions();
+    bindWithoutRowId();
+}
 
+void CreateTableSqlStatementBuilder::bindWithoutRowId() const
+{
     if (m_useWithoutRowId)
         m_sqlStatementBuilder.bind("$withoutRowId", " WITHOUT ROWID");
     else
         m_sqlStatementBuilder.bindEmptyText("$withoutRowId");
 }
 
+void CreateTableSqlStatementBuilder::bindIfNotExists() const
+{
+    if (m_useIfNotExits)
+        m_sqlStatementBuilder.bind("$ifNotExits", "IF NOT EXISTS ");
+    else
+        m_sqlStatementBuilder.bindEmptyText("$ifNotExits");
+}
+
+void CreateTableSqlStatementBuilder::bindTemporary() const
+{
+    if (m_useTemporaryTable)
+        m_sqlStatementBuilder.bind("$temporary", "TEMPORARY ");
+    else
+        m_sqlStatementBuilder.bindEmptyText("$temporary");
+}
+
 } // namespace Sqlite
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h
index f33a8920a23454a384cb2232c78d29f03ee586e9..00c9ebd45a145423ed8a0a4ea99e899ada463c9b 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.h
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.h
@@ -35,12 +35,14 @@ class SQLITE_EXPORT CreateTableSqlStatementBuilder
 public:
     CreateTableSqlStatementBuilder();
 
-    void setTable(Utils::SmallString &&tableName);
+    void setTableName(Utils::SmallString &&tableName);
     void addColumn(Utils::SmallString &&columnName,
                    ColumnType columnType,
-                   IsPrimaryKey isPrimaryKey = IsPrimaryKey::No);
+                   Contraint constraint = Contraint::NoConstraint);
     void setColumns(const SqliteColumns &columns);
     void setUseWithoutRowId(bool useWithoutRowId);
+    void setUseIfNotExists(bool useIfNotExists);
+    void setUseTemporaryTable(bool useTemporaryTable);
 
     void clear();
     void clearColumns();
@@ -52,12 +54,17 @@ public:
 protected:
     void bindColumnDefinitions() const;
     void bindAll() const;
+    void bindWithoutRowId() const;
+    void bindIfNotExists() const;
+    void bindTemporary() const;
 
 private:
     mutable SqlStatementBuilder m_sqlStatementBuilder;
     Utils::SmallString m_tableName;
     SqliteColumns m_columns;
-    bool m_useWithoutRowId;
+    bool m_useWithoutRowId = false;
+    bool m_useIfNotExits = false;
+    bool m_useTemporaryTable = false;
 };
 
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
index c16333ce2317f9f20119e546df0beeb1b6177c90..e25ee68b2d7d4e9996e80c793d121415063df537 100644
--- a/src/libs/sqlite/sqlitecolumn.h
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -38,17 +38,17 @@ public:
 
     SqliteColumn(Utils::SmallString &&name,
                  ColumnType type = ColumnType::Numeric,
-                 IsPrimaryKey isPrimaryKey = IsPrimaryKey::No)
+                 Contraint constraint = Contraint::NoConstraint)
         : m_name(std::move(name)),
           m_type(type),
-          m_isPrimaryKey(isPrimaryKey)
+          m_constraint(constraint)
     {}
 
     void clear()
     {
         m_name.clear();
         m_type = ColumnType::Numeric;
-        m_isPrimaryKey = IsPrimaryKey::No;
+        m_constraint = Contraint::NoConstraint;
     }
 
     void setName(Utils::SmallString &&newName)
@@ -71,14 +71,14 @@ public:
         return m_type;
     }
 
-    void setIsPrimaryKey(IsPrimaryKey isPrimaryKey)
+    void setContraint(Contraint constraint)
     {
-        m_isPrimaryKey = isPrimaryKey;
+        m_constraint = constraint;
     }
 
-    bool isPrimaryKey() const
+    Contraint constraint() const
     {
-        return m_isPrimaryKey == IsPrimaryKey::Yes;
+        return m_constraint;
     }
 
     Utils::SmallString typeString() const
@@ -98,13 +98,13 @@ public:
     {
         return first.m_name == second.m_name
             && first.m_type == second.m_type
-            && first.m_isPrimaryKey == second.m_isPrimaryKey;
+            && first.m_constraint == second.m_constraint;
     }
 
 private:
     Utils::SmallString m_name;
     ColumnType m_type = ColumnType::Numeric;
-    IsPrimaryKey m_isPrimaryKey = IsPrimaryKey::No;
+    Contraint m_constraint = Contraint::NoConstraint;
 };
 
 using SqliteColumns = std::vector<SqliteColumn>;
diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp
index ec2379c61c1ef371d4b26c3e4cfc0afb74bc12b2..4d53eecb35a4477c0c23b9c28b527171eb93cfef 100644
--- a/src/libs/sqlite/sqlitedatabase.cpp
+++ b/src/libs/sqlite/sqlitedatabase.cpp
@@ -26,6 +26,7 @@
 #include "sqlitedatabase.h"
 
 #include "sqlitetable.h"
+#include "sqlitetransaction.h"
 
 namespace Sqlite {
 
@@ -34,6 +35,12 @@ SqliteDatabase::SqliteDatabase()
 {
 }
 
+SqliteDatabase::SqliteDatabase(Utils::PathString &&databaseFilePath)
+    : m_databaseBackend(*this)
+{
+    open(std::move(databaseFilePath));
+}
+
 void SqliteDatabase::open()
 {
     m_databaseBackend.open(m_databaseFilePath, m_openMode);
@@ -61,7 +68,7 @@ bool SqliteDatabase::isOpen() const
 
 SqliteTable &SqliteDatabase::addTable()
 {
-    m_sqliteTables.emplace_back(*this);
+    m_sqliteTables.emplace_back();
 
     return m_sqliteTables.back();
 }
@@ -118,8 +125,12 @@ void SqliteDatabase::execute(Utils::SmallStringView sqlStatement)
 
 void SqliteDatabase::initializeTables()
 {
+    SqliteImmediateTransaction<SqliteDatabase> transaction(*this);
+
     for (SqliteTable &table : m_sqliteTables)
-        table.initialize();
+        table.initialize(*this);
+
+    transaction.commit();
 }
 
 SqliteDatabaseBackend &SqliteDatabase::backend()
diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h
index 2e178a0190cb3b209f7069b987b96a4b206f0861..0ac340bb12946e49f987d59eaed24edd76277c63 100644
--- a/src/libs/sqlite/sqlitedatabase.h
+++ b/src/libs/sqlite/sqlitedatabase.h
@@ -37,12 +37,14 @@ namespace Sqlite {
 
 class SQLITE_EXPORT SqliteDatabase
 {
+    template <typename Database>
     friend class SqliteAbstractTransaction;
     friend class SqliteStatement;
     friend class SqliteBackend;
 
 public:
     SqliteDatabase();
+    SqliteDatabase(Utils::PathString &&databaseFilePath);
 
     SqliteDatabase(const SqliteDatabase &) = delete;
     bool operator=(const SqliteDatabase &) = delete;
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
index 79eed32eab4d99175e621e1a01cc34c4c5bf5555..6ea70f30ada216b8bc1a34fbb651969426749a45 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.cpp
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -38,14 +38,6 @@
 
 #include "sqlite3.h"
 
-#if defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
-#define QTC_THREAD_LOCAL __thread
-#else
-#define QTC_THREAD_LOCAL thread_local
-#endif
-
-#define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray)
-
 namespace Sqlite {
 
 SqliteDatabaseBackend::SqliteDatabaseBackend(SqliteDatabase &database)
diff --git a/src/libs/sqlite/sqliteglobal.h b/src/libs/sqlite/sqliteglobal.h
index cb5208df5ff24ef822547dea19d4ca676f0eb6c0..af9d9ac36c0aaff2c9060a3687c0e3a76bd62b5d 100644
--- a/src/libs/sqlite/sqliteglobal.h
+++ b/src/libs/sqlite/sqliteglobal.h
@@ -37,6 +37,8 @@
 #  define SQLITE_EXPORT Q_DECL_IMPORT
 #endif
 
+namespace Sqlite {
+
 enum class ColumnType : char
 {
     Numeric,
@@ -46,10 +48,11 @@ enum class ColumnType : char
     None
 };
 
-enum class IsPrimaryKey : char
+enum class Contraint : char
 {
-    No,
-    Yes
+    NoConstraint,
+    PrimaryKey,
+    Unique
 };
 
 enum class ColumnConstraint : char
@@ -84,3 +87,5 @@ enum TextEncoding : char
 #endif
 
 };
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h
index 55bd5c15fbb991668963cbb38aa8b0eea4e70305..d0c8860281124b0fd3d1e194e94a18b3a120a5dd 100644
--- a/src/libs/sqlite/sqlitereadstatement.h
+++ b/src/libs/sqlite/sqlitereadstatement.h
@@ -37,6 +37,8 @@ public:
     using SqliteStatement::next;
     using SqliteStatement::reset;
     using SqliteStatement::value;
+    using SqliteStatement::structValues;
+    using SqliteStatement::tupleValues;
     using SqliteStatement::text;
     using SqliteStatement::values;
     using SqliteStatement::columnCount;
diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h
index 8f93ff85bed073f991eb10d4576c89c3c1573873..d53614bcc02721cce9cbe1be2b3b748f850cd830 100644
--- a/src/libs/sqlite/sqlitereadwritestatement.h
+++ b/src/libs/sqlite/sqlitereadwritestatement.h
@@ -48,6 +48,8 @@ public:
     using SqliteStatement::value;
     using SqliteStatement::text;
     using SqliteStatement::values;
+    using SqliteStatement::structValues;
+    using SqliteStatement::tupleValues;
     using SqliteStatement::columnCount;
     using SqliteStatement::columnNames;
     using SqliteStatement::toValue;
diff --git a/src/libs/sqlite/sqlitestatement.cpp b/src/libs/sqlite/sqlitestatement.cpp
index fee0130acc7d1fbdbba56b2aeba7c934ef0afa6e..4c4a458a968aaba7ae37b583440845457d9d9460 100644
--- a/src/libs/sqlite/sqlitestatement.cpp
+++ b/src/libs/sqlite/sqlitestatement.cpp
@@ -29,13 +29,11 @@
 #include "sqlitedatabasebackend.h"
 #include "sqliteexception.h"
 
-#include <QMutex>
-#include <QtGlobal>
-#include <QVariant>
-#include <QWaitCondition>
-
 #include "sqlite3.h"
 
+#include <condition_variable>
+#include <mutex>
+
 #if defined(__GNUC__)
 #  pragma GCC diagnostic ignored "-Wignored-qualifiers"
 #endif
@@ -61,8 +59,8 @@ void SqliteStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
         sqlite3_finalize(compiledStatement);
 }
 
-class UnlockNotification {
-
+class UnlockNotification
+{
 public:
     static void unlockNotifyCallBack(void **arguments, int argumentCount)
     {
@@ -74,27 +72,24 @@ public:
 
     void wakeupWaitCondition()
     {
-        mutex.lock();
-        fired = 1;
-        waitCondition.wakeAll();
-        mutex.unlock();
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            m_fired = 1;
+        }
+        m_waitCondition.notify_all();
     }
 
     void wait()
     {
-        mutex.lock();
+        std::unique_lock<std::mutex> lock(m_mutex);
 
-        if (!fired) {
-            waitCondition.wait(&mutex);
-        }
-
-        mutex.unlock();
+        m_waitCondition.wait(lock, [&] () { return m_fired; });
     }
 
 private:
-    bool fired = false;
-    QWaitCondition waitCondition;
-    QMutex mutex;
+    bool m_fired = false;
+    std::condition_variable m_waitCondition;
+    std::mutex m_mutex;
 };
 
 void SqliteStatement::waitForUnlockNotify() const
@@ -143,6 +138,7 @@ void SqliteStatement::step() const
 void SqliteStatement::execute() const
 {
     next();
+    reset();
 }
 
 int SqliteStatement::columnCount() const
@@ -168,7 +164,7 @@ void SqliteStatement::bind(int index, int value)
          throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
 }
 
-void SqliteStatement::bind(int index, qint64 value)
+void SqliteStatement::bind(int index, long long value)
 {
      int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
      if (resultCode != SQLITE_OK)
@@ -198,7 +194,8 @@ void SqliteStatement::bind(Utils::SmallStringView name, Type value)
 }
 
 template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, int value);
-template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, qint64 value);
+template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, long value);
+template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, long long value);
 template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, double value);
 template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, Utils::SmallStringView text);
 
@@ -363,21 +360,23 @@ SqliteDatabase &SqliteStatement::database() const
     return m_database;
 }
 
-static Utils::SmallString textForColumn(sqlite3_stmt *sqlStatment, int column)
+template <typename StringType>
+static StringType textForColumn(sqlite3_stmt *sqlStatment, int column)
 {
     const char *text =  reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
     std::size_t size = std::size_t(sqlite3_column_bytes(sqlStatment, column));
 
-    return Utils::SmallString(text, size);
+    return StringType(text, size);
 }
 
-static Utils::SmallString convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
+template <typename StringType>
+static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
 {
     int dataType = sqlite3_column_type(sqlStatment, column);
     switch (dataType) {
         case SQLITE_INTEGER:
         case SQLITE_FLOAT:
-        case SQLITE3_TEXT: return textForColumn(sqlStatment, column);
+        case SQLITE3_TEXT: return textForColumn<StringType>(sqlStatment, column);
         case SQLITE_BLOB:
         case SQLITE_NULL: return {};
     }
@@ -394,7 +393,13 @@ int SqliteStatement::value<int>(int column) const
 }
 
 template<>
-qint64 SqliteStatement::value<qint64>(int column) const
+long SqliteStatement::value<long>(int column) const
+{
+    return long(value<long long>(column));
+}
+
+template<>
+long long SqliteStatement::value<long long>(int column) const
 {
     checkIfIsReadyToFetchValues();
     checkColumnIsValid(column);
@@ -409,14 +414,17 @@ double SqliteStatement::value<double>(int column) const
     return sqlite3_column_double(m_compiledStatement.get(), column);
 }
 
-template<>
-Utils::SmallString SqliteStatement::value<Utils::SmallString>(int column) const
+template<typename StringType>
+StringType SqliteStatement::value(int column) const
 {
     checkIfIsReadyToFetchValues();
     checkColumnIsValid(column);
-    return convertToTextForColumn(m_compiledStatement.get(), column);
+    return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
 }
 
+template SQLITE_EXPORT Utils::SmallString SqliteStatement::value<Utils::SmallString>(int column) const;
+template SQLITE_EXPORT Utils::PathString SqliteStatement::value<Utils::PathString>(int column) const;
+
 Utils::SmallString SqliteStatement::text(int column) const
 {
     return value<Utils::SmallString>(column);
@@ -434,45 +442,6 @@ ContainerType SqliteStatement::columnValues(const std::vector<int> &columnIndice
     return valueContainer;
 }
 
-template <typename ContainerType>
-ContainerType SqliteStatement::values(const std::vector<int> &columns, int size) const
-{
-    checkColumnsAreValid(columns);
-
-    ContainerType resultValues;
-    resultValues.reserve(typename ContainerType::size_type(size));
-
-    reset();
-
-    while (next()) {
-        auto values = columnValues<ContainerType>(columns);
-        std::move(values.begin(), values.end(), std::back_inserter(resultValues));
-    }
-
-    return resultValues;
-}
-
-template SQLITE_EXPORT Utils::SmallStringVector SqliteStatement::values<Utils::SmallStringVector>(const std::vector<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.push_back(value<ElementType>(column));
-    }
-
-    return resultValues;
-}
-
-template SQLITE_EXPORT std::vector<qint64> SqliteStatement::values<std::vector<qint64>>(int column) const;
-template SQLITE_EXPORT std::vector<double> SqliteStatement::values<std::vector<double>>(int column) const;
-template SQLITE_EXPORT Utils::SmallStringVector SqliteStatement::values<Utils::SmallStringVector>(int column) const;
-
 template <typename Type>
 Type SqliteStatement::toValue(Utils::SmallStringView sqlStatement, SqliteDatabase &database)
 {
@@ -484,7 +453,7 @@ Type SqliteStatement::toValue(Utils::SmallStringView sqlStatement, SqliteDatabas
 }
 
 template SQLITE_EXPORT int SqliteStatement::toValue<int>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
-template SQLITE_EXPORT qint64 SqliteStatement::toValue<qint64>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
+template SQLITE_EXPORT long long SqliteStatement::toValue<long long>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
 template SQLITE_EXPORT double SqliteStatement::toValue<double>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
 template SQLITE_EXPORT Utils::SmallString SqliteStatement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
 
diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitestatement.h
index 5f74c267ef380f05f79ed0d871db1193d770313b..09c75c16d974055e0f38a820fc8b23f7d74f79e4 100644
--- a/src/libs/sqlite/sqlitestatement.h
+++ b/src/libs/sqlite/sqlitestatement.h
@@ -31,8 +31,12 @@
 
 #include <utils/smallstringvector.h>
 
-#include <type_traits>
+#include <cstdint>
 #include <memory>
+#include <type_traits>
+#include <tuple>
+
+using std::int64_t;
 
 struct sqlite3_stmt;
 struct sqlite3;
@@ -61,31 +65,45 @@ protected:
     Utils::SmallStringVector columnNames() const;
 
     void bind(int index, int value);
-    void bind(int index, qint64 value);
+    void bind(int index, long long value);
     void bind(int index, double value);
     void bind(int index, Utils::SmallStringView value);
 
-    template<typename ... Values>
-    void bindValues(Values ... values)
+    void bind(int index, uint value)
+    {
+        bind(index, static_cast<long long>(value));
+    }
+
+    void bind(int index, long value)
+    {
+        bind(index, static_cast<long long>(value));
+    }
+
+    void bindValues()
+    {
+    }
+
+    template<typename... Values>
+    void bindValues(Values... values)
     {
         bindValuesByIndex(1, values...);
     }
 
-    template<typename ... Values>
-    void write(Values ... values)
+    template<typename... Values>
+    void write(Values... values)
     {
         bindValuesByIndex(1, values...);
         execute();
     }
 
-    template<typename ... Values>
-    void bindNameValues(Values ... values)
+    template<typename... Values>
+    void bindNameValues(Values... values)
     {
         bindValuesByName(values...);
     }
 
-    template<typename ... Values>
-    void writeNamed(Values ... values)
+    template<typename... Values>
+    void writeNamed(Values... values)
     {
         bindValuesByName(values...);
         execute();
@@ -99,11 +117,231 @@ protected:
     void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
     const Utils::SmallStringVector &bindingColumnNames() const;
 
-    template <typename ContainerType>
-    ContainerType values(const std::vector<int> &columns, int size = 0) const;
+    template <typename... ResultType>
+    std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize)
+    {
+        using Container = std::vector<std::tuple<ResultType...>>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
 
-    template <typename ContainerType>
-    ContainerType values(int column = 0) const;
+        while (next())
+           emplaceTupleValues<Container, ResultType...>(resultValues);
+
+        reset();
+
+        return resultValues;
+    }
+
+    template <typename... ResultType,
+              typename... QueryType>
+    std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const QueryType&... queryValues)
+    {
+        using Container = std::vector<std::tuple<ResultType...>>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        bindValues(queryValues...);
+
+        while (next())
+           emplaceTupleValues<Container, ResultType...>(resultValues);
+
+        reset();
+
+        return resultValues;
+    }
+
+    template <typename... ResultType,
+              typename... ElementType>
+    std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize,
+                                                       const std::vector<std::tuple<ElementType...>> &queryTuples)
+    {
+        using Container = std::vector<std::tuple<ResultType...>>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const auto &queryTuple : queryTuples) {
+            bindTupleValues(queryTuple);
+
+            while (next())
+                emplaceTupleValues<Container, ResultType...>(resultValues);
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename... ResultType,
+              typename QueryElementType>
+    std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize,
+                                                       const std::vector<QueryElementType> &queryValues)
+    {
+        using Container = std::vector<std::tuple<ResultType...>>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const QueryElementType &queryValue : queryValues) {
+            bindValues(queryValue);
+
+            while (next())
+                emplaceTupleValues<Container, ResultType...>(resultValues);
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ResultEntryType>
+    std::vector<ResultType> structValues(std::size_t reserveSize)
+    {
+        using Container = std::vector<ResultType>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        while (next())
+           pushBackStructValues<Container, ResultEntryType...>(resultValues);
+
+        reset();
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ResultEntryType,
+              typename... QueryType>
+    std::vector<ResultType> structValues(std::size_t reserveSize, const QueryType&... queryValues)
+    {
+        using Container = std::vector<ResultType>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        bindValues(queryValues...);
+
+        while (next())
+           pushBackStructValues<Container, ResultEntryType...>(resultValues);
+
+        reset();
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ResultEntryType,
+              typename QueryElementType>
+    std::vector<ResultType> structValues(std::size_t reserveSize,
+                                         const std::vector<QueryElementType> &queryValues)
+    {
+        using Container = std::vector<ResultType>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const QueryElementType &queryValue : queryValues) {
+            bindValues(queryValue);
+
+            while (next())
+                pushBackStructValues<Container, ResultEntryType...>(resultValues);
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ResultEntryType,
+              typename... QueryElementType>
+    std::vector<ResultType> structValues(std::size_t reserveSize,
+                                         const std::vector<std::tuple<QueryElementType...>> &queryTuples)
+    {
+        using Container = std::vector<ResultType>;
+        Container resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const auto &queryTuple : queryTuples) {
+            bindTupleValues(queryTuple);
+
+            while (next())
+                pushBackStructValues<Container, ResultEntryType...>(resultValues);
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ElementType>
+    std::vector<ResultType> values(std::size_t reserveSize)
+    {
+        std::vector<ResultType> resultValues;
+        resultValues.reserve(reserveSize);
+
+        while (next())
+            resultValues.push_back(value<ResultType>(0));
+
+        reset();
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... ElementType>
+    std::vector<ResultType> values(std::size_t reserveSize,
+                                   const std::vector<std::tuple<ElementType...>> &queryTuples)
+    {
+        std::vector<ResultType> resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const auto &queryTuple : queryTuples) {
+            bindTupleValues(queryTuple);
+
+            while (next())
+                resultValues.push_back(value<ResultType>(0));
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename ElementType>
+    std::vector<ResultType> values(std::size_t reserveSize,
+                                   const std::vector<ElementType> &queryValues)
+    {
+        std::vector<ResultType> resultValues;
+        resultValues.reserve(reserveSize);
+
+        for (const ElementType &queryValue : queryValues) {
+            bindValues(queryValue);
+
+            while (next())
+                resultValues.push_back(value<ResultType>(0));
+
+            reset();
+        }
+
+        return resultValues;
+    }
+
+    template <typename ResultType,
+              typename... QueryType>
+    std::vector<ResultType> values(std::size_t reserveSize, const QueryType&... queryValues)
+    {
+        std::vector<ResultType> resultValues;
+        resultValues.reserve(reserveSize);
+
+        bindValues(queryValues...);
+
+        while (next())
+            resultValues.push_back(value<ResultType>(0));
+
+        reset();
+
+        return resultValues;
+    }
 
     template <typename Type>
     static Type toValue(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
@@ -141,14 +379,45 @@ protected:
                              SqliteDatabaseBackend &databaseBackend);
 
 private:
+    template <typename Container,
+              typename... ResultType,
+              int... Index>
+    void emplaceTupleValues(Container &container, std::integer_sequence<int, Index...>)
+    {
+        container.emplace_back(value<ResultType>(Index)...);
+    }
+
+    template <typename Container,
+              typename... ResultType>
+    void emplaceTupleValues(Container &container)
+    {
+        emplaceTupleValues<Container, ResultType...>(container, std::make_integer_sequence<int, sizeof...(ResultType)>{});
+    }
+
+    template <typename Container,
+              typename... ResultEntryType,
+              int... Index>
+    void pushBackStructValues(Container &container, std::integer_sequence<int, Index...>)
+    {
+        using ResultType = typename Container::value_type;
+        container.push_back(ResultType{value<ResultEntryType>(Index)...});
+    }
+
+    template <typename Container,
+              typename... ResultEntryType>
+    void pushBackStructValues(Container &container)
+    {
+        pushBackStructValues<Container, ResultEntryType...>(container, std::make_integer_sequence<int, sizeof...(ResultEntryType)>{});
+    }
+
     template<typename Type>
     void bindValuesByIndex(int index, Type value)
     {
         bind(index, value);
     }
 
-    template<typename Type, typename ... Value>
-    void bindValuesByIndex(int index, Type value, Value ... values)
+    template<typename Type, typename... Value>
+    void bindValuesByIndex(int index, Type value, Value... values)
     {
         bind(index, value);
         bindValuesByIndex(index + 1, values...);
@@ -160,13 +429,26 @@ private:
        bind(bindingIndexForName(name), value);
     }
 
-    template<typename Type, typename ... Values>
-    void bindValuesByName(Utils::SmallStringView name, Type value, Values ... values)
+    template<typename Type, typename... Values>
+    void bindValuesByName(Utils::SmallStringView name, Type value, Values... values)
     {
        bind(bindingIndexForName(name), value);
        bindValuesByName(values...);
     }
 
+    template <typename TupleType, std::size_t... Index>
+    void bindTupleValuesElement(const TupleType &tuple, std::index_sequence<Index...>)
+    {
+        bindValues(std::get<Index>(tuple)...);
+    }
+
+    template <typename TupleType,
+              typename Indices = std::make_index_sequence<std::tuple_size<TupleType>::value>>
+    void bindTupleValues(const TupleType &element)
+    {
+        bindTupleValuesElement(element, Indices());
+    }
+
 private:
     std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement;
     Utils::SmallStringVector m_bindingColumnNames;
@@ -176,4 +458,21 @@ private:
     mutable bool m_isReadyToFetchValues;
 };
 
+extern template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, int value);
+extern template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, long value);
+extern template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, long long value);
+extern template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, double value);
+extern template SQLITE_EXPORT void SqliteStatement::bind(Utils::SmallStringView name, Utils::SmallStringView text);
+
+extern template SQLITE_EXPORT int SqliteStatement::toValue<int>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
+extern template SQLITE_EXPORT long long SqliteStatement::toValue<long long>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
+extern template SQLITE_EXPORT double SqliteStatement::toValue<double>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
+extern template SQLITE_EXPORT Utils::SmallString SqliteStatement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, SqliteDatabase &database);
+
+template <> SQLITE_EXPORT int SqliteStatement::value<int>(int column) const;
+template <> SQLITE_EXPORT long SqliteStatement::value<long>(int column) const;
+template <> SQLITE_EXPORT long long SqliteStatement::value<long long>(int column) const;
+template <> SQLITE_EXPORT double SqliteStatement::value<double>(int column) const;
+extern template SQLITE_EXPORT Utils::SmallString SqliteStatement::value<Utils::SmallString>(int column) const;
+extern template SQLITE_EXPORT Utils::PathString SqliteStatement::value<Utils::PathString>(int column) const;
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetable.cpp b/src/libs/sqlite/sqlitetable.cpp
index dc987f4477276643c0aed11719b2efdbc37c38fe..99b0e95938cdb7205b89548948aec59f146533f1 100644
--- a/src/libs/sqlite/sqlitetable.cpp
+++ b/src/libs/sqlite/sqlitetable.cpp
@@ -25,32 +25,8 @@
 
 #include "sqlitetable.h"
 
-#include "sqlitecolumn.h"
-#include "sqlitedatabase.h"
-#include "createtablesqlstatementbuilder.h"
-#include "sqlitewritestatement.h"
-#include "sqlitetransaction.h"
-
 namespace Sqlite {
 
-void SqliteTable::initialize()
-{
-    try {
-        CreateTableSqlStatementBuilder createTableSqlStatementBuilder;
-
-        createTableSqlStatementBuilder.setTable(m_tableName.clone());
-        createTableSqlStatementBuilder.setUseWithoutRowId(m_withoutRowId);
-        createTableSqlStatementBuilder.setColumns(m_sqliteColumns);
-
-        SqliteImmediateTransaction transaction(m_sqliteDatabase);
-        m_sqliteDatabase.execute(createTableSqlStatementBuilder.sqlStatement());
-        transaction.commit();
-
-        m_isReady = true;
 
-    } catch (const SqliteException &exception) {
-        exception.printWarning();
-    }
-}
 
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index 62b6b41cb3fe07a3eb8cc7f3560ee06710019fda..d591f39a59f8dd10975581e86646da2debe57639 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -25,8 +25,10 @@
 
 #pragma once
 
+#include "createtablesqlstatementbuilder.h"
 #include "sqliteglobal.h"
 #include "sqlitecolumn.h"
+#include "sqliteexception.h"
 
 namespace Sqlite {
 
@@ -35,11 +37,6 @@ class SqliteDatabase;
 class SqliteTable
 {
 public:
-    SqliteTable(SqliteDatabase &m_sqliteDatabase)
-        : m_sqliteDatabase(m_sqliteDatabase)
-    {
-    }
-
     void setName(Utils::SmallString &&name)
     {
         m_tableName = std::move(name);
@@ -60,11 +57,16 @@ public:
         return m_withoutRowId;
     }
 
+    void setUseIfNotExists(bool useIfNotExists)
+    {
+        m_useIfNotExists = useIfNotExists;
+    }
+
     SqliteColumn &addColumn(Utils::SmallString &&name,
                             ColumnType type = ColumnType::Numeric,
-                            IsPrimaryKey isPrimaryKey = IsPrimaryKey::No)
+                            Contraint constraint = Contraint::NoConstraint)
     {
-        m_sqliteColumns.emplace_back(std::move(name), type, isPrimaryKey);
+        m_sqliteColumns.emplace_back(std::move(name), type, constraint);
 
         return m_sqliteColumns.back();
     }
@@ -79,13 +81,31 @@ public:
         return m_isReady;
     }
 
-    void initialize();
+    template <typename Database>
+    void initialize(Database &database)
+    {
+        try {
+            CreateTableSqlStatementBuilder builder;
+
+            builder.setTableName(m_tableName.clone());
+            builder.setUseWithoutRowId(m_withoutRowId);
+            builder.setUseIfNotExists(m_useIfNotExists);
+            builder.setColumns(m_sqliteColumns);
+
+            database.execute(builder.sqlStatement());
+
+            m_isReady = true;
+
+        } catch (const SqliteException &exception) {
+            exception.printWarning();
+        }
+    }
 
     friend bool operator==(const SqliteTable &first, const SqliteTable &second)
     {
         return first.m_tableName == second.m_tableName
-            && &first.m_sqliteDatabase == &second.m_sqliteDatabase
             && first.m_withoutRowId == second.m_withoutRowId
+            && first.m_useIfNotExists == second.m_useIfNotExists
             && first.m_isReady == second.m_isReady
             && first.m_sqliteColumns == second.m_sqliteColumns;
     }
@@ -93,8 +113,8 @@ public:
 private:
     Utils::SmallString m_tableName;
     SqliteColumns m_sqliteColumns;
-    SqliteDatabase &m_sqliteDatabase;
     bool m_withoutRowId = false;
+    bool m_useIfNotExists = false;
     bool m_isReady = false;
 };
 
diff --git a/src/libs/sqlite/sqlitetransaction.cpp b/src/libs/sqlite/sqlitetransaction.cpp
index dd790ee55296b8d4c97abc1482a6b80be17d665c..2ee17131c25fc53dbbf94fa7da1a48004e6e98cb 100644
--- a/src/libs/sqlite/sqlitetransaction.cpp
+++ b/src/libs/sqlite/sqlitetransaction.cpp
@@ -31,44 +31,4 @@
 
 namespace Sqlite {
 
-SqliteAbstractTransaction::~SqliteAbstractTransaction()
-{
-    if (!m_isAlreadyCommited)
-        m_databaseBackend.execute("ROLLBACK");
-}
-
-void SqliteAbstractTransaction::commit()
-{
-    m_databaseBackend.execute("COMMIT");
-    m_isAlreadyCommited = true;
-}
-
-SqliteAbstractTransaction::SqliteAbstractTransaction(SqliteDatabaseBackend &backend)
-    : m_databaseBackend(backend)
-{
-}
-
-SqliteAbstractTransaction::SqliteAbstractTransaction(SqliteDatabase &database)
-    : SqliteAbstractTransaction(database.backend())
-{
-}
-
-SqliteTransaction::SqliteTransaction(SqliteDatabase &database)
-    : SqliteAbstractTransaction(database)
-{
-    m_databaseBackend.execute("BEGIN");
-}
-
-SqliteImmediateTransaction::SqliteImmediateTransaction(SqliteDatabase &database)
-    : SqliteAbstractTransaction(database)
-{
-    m_databaseBackend.execute("BEGIN IMMEDIATE");
-}
-
-SqliteExclusiveTransaction::SqliteExclusiveTransaction(SqliteDatabase &database)
-    : SqliteAbstractTransaction(database)
-{
-    m_databaseBackend.execute("BEGIN EXCLUSIVE");
-}
-
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h
index 994fbe2b1f5c0003ae3afed79ab1e49e5dfb73e9..373b33fd8a928de6044f773c634549fa771fc32a 100644
--- a/src/libs/sqlite/sqlitetransaction.h
+++ b/src/libs/sqlite/sqlitetransaction.h
@@ -32,43 +32,66 @@ namespace Sqlite {
 class SqliteDatabaseBackend;
 class SqliteDatabase;
 
-class SQLITE_EXPORT SqliteAbstractTransaction
+template <typename Database>
+class SqliteAbstractTransaction
 {
 public:
-    virtual ~SqliteAbstractTransaction();
-
-    void commit();
-
-protected:
-    SqliteAbstractTransaction(SqliteDatabaseBackend &backend);
-    SqliteAbstractTransaction(SqliteDatabase &database);
+    virtual ~SqliteAbstractTransaction()
+    {
+        if (!m_isAlreadyCommited)
+            m_database.execute("ROLLBACK");
+    }
+
+    void commit()
+    {
+        m_database.execute("COMMIT");
+        m_isAlreadyCommited = true;
+    }
 
 protected:
-    SqliteDatabaseBackend &m_databaseBackend;
+    SqliteAbstractTransaction(Database &database)
+        : m_database(database)
+    {
+    }
 
 private:
+    Database &m_database;
     bool m_isAlreadyCommited = false;
 };
 
-
-class SQLITE_EXPORT SqliteTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class SqliteTransaction final : public SqliteAbstractTransaction<Database>
 {
 public:
-    SqliteTransaction(SqliteDatabase &database);
+    SqliteTransaction(Database &database)
+        : SqliteAbstractTransaction<Database>(database)
+    {
+        database.execute("BEGIN");
+    }
 
 };
 
-class SQLITE_EXPORT SqliteImmediateTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class SqliteImmediateTransaction final : public SqliteAbstractTransaction<Database>
 {
 public:
-    SqliteImmediateTransaction(SqliteDatabase &database);
+    SqliteImmediateTransaction(Database &database)
+        : SqliteAbstractTransaction<Database>(database)
+    {
+        database.execute("BEGIN IMMEDIATE");
+    }
 
 };
 
-class SQLITE_EXPORT SqliteExclusiveTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class SqliteExclusiveTransaction final : public SqliteAbstractTransaction<Database>
 {
 public:
-    SqliteExclusiveTransaction(SqliteDatabase &database);
+    SqliteExclusiveTransaction(Database &database)
+        : SqliteAbstractTransaction<Database>(database)
+    {
+        database.execute("BEGIN EXCLUSIVE");
+    }
 
 };
 
diff --git a/src/libs/sqlite/sqlstatementbuilder.cpp b/src/libs/sqlite/sqlstatementbuilder.cpp
index 4104d8c1f0c4fb53d328a7936ae255c7e3d24b4d..cfa08a2b7b360e59e12892abbc5d5d9ce1cfdb3a 100644
--- a/src/libs/sqlite/sqlstatementbuilder.cpp
+++ b/src/libs/sqlite/sqlstatementbuilder.cpp
@@ -33,7 +33,7 @@
 
 namespace Sqlite {
 
-SqlStatementBuilder::SqlStatementBuilder(Utils::SmallString &&sqlTemplate)
+SqlStatementBuilder::SqlStatementBuilder(Utils::SmallStringView sqlTemplate)
     : m_sqlTemplate(std::move(sqlTemplate))
 {
 }
diff --git a/src/libs/sqlite/sqlstatementbuilder.h b/src/libs/sqlite/sqlstatementbuilder.h
index c24e0b9ed947dd20f766d70a17252a4038185154..670455dc41a5764fff8cdb7518fbe46a42825864 100644
--- a/src/libs/sqlite/sqlstatementbuilder.h
+++ b/src/libs/sqlite/sqlstatementbuilder.h
@@ -38,7 +38,7 @@ class SQLITE_EXPORT SqlStatementBuilder
 {
     using BindingPair = std::pair<Utils::SmallString, Utils::SmallString>;
 public:
-    SqlStatementBuilder(Utils::SmallString &&m_sqlTemplate);
+    SqlStatementBuilder(Utils::SmallStringView m_sqlTemplate);
 
     void bindEmptyText(Utils::SmallString &&name);
     void bind(Utils::SmallString &&name, Utils::SmallString &&text);
@@ -79,8 +79,8 @@ protected:
     Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage);
 
 private:
-    Utils::SmallString m_sqlTemplate;
-    mutable Utils::SmallString m_sqlStatement;
+    Utils::BasicSmallString<510> m_sqlTemplate;
+    mutable Utils::BasicSmallString<510> m_sqlStatement;
     mutable std::vector<BindingPair> m_bindings;
 };
 
diff --git a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
index faea6c850dacb1fc1936bf6b7148b3a8a4367f03..1114403ac66ca4ede8f5a6025817361cf26b490c 100644
--- a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
+++ b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
@@ -30,6 +30,10 @@
 
 namespace {
 
+using Sqlite::ColumnType;
+using Sqlite::Contraint;
+using Sqlite::JournalMode;
+using Sqlite::OpenMode;
 using Sqlite::SqliteColumn;
 using Sqlite::SqliteColumns;
 
@@ -81,7 +85,7 @@ TEST_F(CreateTableSqlStatementBuilder, SqlStatement)
     bindValues();
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)");
+                "CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)");
 }
 
 TEST_F(CreateTableSqlStatementBuilder, AddColumnToExistingColumns)
@@ -91,17 +95,17 @@ TEST_F(CreateTableSqlStatementBuilder, AddColumnToExistingColumns)
     builder.addColumn("number2", ColumnType::Real);
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC, number2 REAL)");
+                "CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC, number2 REAL)");
 }
 
 TEST_F(CreateTableSqlStatementBuilder, ChangeTable)
 {
     bindValues();
 
-    builder.setTable("test2");
+    builder.setTableName("test2");
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test2(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)"
+                "CREATE TABLE test2(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)"
                 );
 }
 
@@ -124,7 +128,7 @@ TEST_F(CreateTableSqlStatementBuilder, ClearColumnsAndAddColumnNewColumns)
     builder.addColumn("number3", ColumnType::Real);
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test(name3 TEXT, number3 REAL)");
+                "CREATE TABLE test(name3 TEXT, number3 REAL)");
 }
 
 TEST_F(CreateTableSqlStatementBuilder, SetWitoutRowId)
@@ -134,25 +138,60 @@ TEST_F(CreateTableSqlStatementBuilder, SetWitoutRowId)
     builder.setUseWithoutRowId(true);
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC) WITHOUT ROWID");
+                "CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC) WITHOUT ROWID");
 }
 
 TEST_F(CreateTableSqlStatementBuilder, SetColumnDefinitions)
 {
     builder.clear();
-    builder.setTable("test");
+    builder.setTableName("test");
 
     builder.setColumns(createColumns());
 
     ASSERT_THAT(builder.sqlStatement(),
-                "CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)");
+                "CREATE TABLE test(id INTEGER PRIMARY KEY, name TEXT, number NUMERIC)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, UniqueContraint)
+{
+    builder.clear();
+    builder.setTableName("test");
+
+    builder.addColumn("id", ColumnType::Integer, Contraint::Unique);
+
+    ASSERT_THAT(builder.sqlStatement(),
+                "CREATE TABLE test(id INTEGER UNIQUE)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, IfNotExitsModifier)
+{
+    builder.clear();
+    builder.setTableName("test");
+    builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
+
+    builder.setUseIfNotExists(true);
+
+    ASSERT_THAT(builder.sqlStatement(),
+                "CREATE TABLE IF NOT EXISTS test(id INTEGER)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, TemporaryTable)
+{
+    builder.clear();
+    builder.setTableName("test");
+    builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
+
+    builder.setUseTemporaryTable(true);
+
+    ASSERT_THAT(builder.sqlStatement(),
+                "CREATE TEMPORARY TABLE test(id INTEGER)");
 }
 
 void CreateTableSqlStatementBuilder::bindValues()
 {
     builder.clear();
-    builder.setTable("test");
-    builder.addColumn("id", ColumnType::Integer, IsPrimaryKey::Yes);
+    builder.setTableName("test");
+    builder.addColumn("id", ColumnType::Integer, Contraint::PrimaryKey);
     builder.addColumn("name", ColumnType::Text);
     builder.addColumn("number",ColumnType:: Numeric);
 }
@@ -160,7 +199,7 @@ void CreateTableSqlStatementBuilder::bindValues()
 SqliteColumns CreateTableSqlStatementBuilder::createColumns()
 {
     SqliteColumns columns;
-    columns.emplace_back("id", ColumnType::Integer, IsPrimaryKey::Yes);
+    columns.emplace_back("id", ColumnType::Integer, Contraint::PrimaryKey);
     columns.emplace_back("name", ColumnType::Text);
     columns.emplace_back("number", ColumnType::Numeric);
 
diff --git a/tests/unit/unittest/sqlitecolumn-test.cpp b/tests/unit/unittest/sqlitecolumn-test.cpp
index a7778cc2107e7d84302f05d31d6177e12600e115..c850fcccae86592ed1799c828d73ef7da28281b6 100644
--- a/tests/unit/unittest/sqlitecolumn-test.cpp
+++ b/tests/unit/unittest/sqlitecolumn-test.cpp
@@ -33,6 +33,10 @@ using testing::AllOf;
 using testing::Contains;
 using testing::Property;
 
+using Sqlite::ColumnType;
+using Sqlite::Contraint;
+using Sqlite::JournalMode;
+using Sqlite::OpenMode;
 using Column = Sqlite::SqliteColumn;
 using Sqlite::SqliteColumns;
 
@@ -63,16 +67,16 @@ TEST_F(SqliteColumn, ChangeType)
     ASSERT_THAT(column.type(), ColumnType::Text);
 }
 
-TEST_F(SqliteColumn, DefaultPrimaryKey)
+TEST_F(SqliteColumn, DefaultConstraint)
 {
-    ASSERT_FALSE(column.isPrimaryKey());
+    ASSERT_THAT(column.constraint(), Contraint::NoConstraint);
 }
 
-TEST_F(SqliteColumn, SetPrimaryKey)
+TEST_F(SqliteColumn, SetConstraint)
 {
-    column.setIsPrimaryKey(IsPrimaryKey::Yes);
+    column.setContraint(Contraint::PrimaryKey);
 
-    ASSERT_TRUE(column.isPrimaryKey());
+    ASSERT_THAT(column.constraint(),  Contraint::PrimaryKey);
 }
 
 TEST_F(SqliteColumn, GetColumnDefinition)
@@ -83,7 +87,7 @@ TEST_F(SqliteColumn, GetColumnDefinition)
                     AllOf(
                         Property(&Column::name, "Claudia"),
                         Property(&Column::type, ColumnType::Numeric),
-                        Property(&Column::isPrimaryKey, false)));
+                        Property(&Column::constraint, Contraint::NoConstraint)));
 }
 
 void SqliteColumn::SetUp()
diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp
index 59d9467246bb96ca2ff29aed8218b9da04fa1c39..85b8a68e80904c6592923eb0e83d29da183e25e4 100644
--- a/tests/unit/unittest/sqlitedatabase-test.cpp
+++ b/tests/unit/unittest/sqlitedatabase-test.cpp
@@ -38,6 +38,9 @@ namespace {
 
 using testing::Contains;
 
+using Sqlite::ColumnType;
+using Sqlite::JournalMode;
+using Sqlite::OpenMode;
 using Sqlite::SqliteTable;
 
 class SqliteDatabase : public ::testing::Test
diff --git a/tests/unit/unittest/sqlitedatabasebackend-test.cpp b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
index 90252eb39fa32ebb40640d83a243c86b64bb277e..67648a60c5cfbb51a7fa0198c6e451adf09351d6 100644
--- a/tests/unit/unittest/sqlitedatabasebackend-test.cpp
+++ b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
@@ -38,6 +38,11 @@ namespace {
 
 using Backend = Sqlite::SqliteDatabaseBackend;
 
+using Sqlite::ColumnType;
+using Sqlite::Contraint;
+using Sqlite::JournalMode;
+using Sqlite::OpenMode;
+using Sqlite::TextEncoding;
 using Sqlite::SqliteException;
 using Sqlite::SqliteWriteStatement;
 
@@ -106,35 +111,35 @@ TEST_F(SqliteDatabaseBackend, PersistJournalMode)
 
 TEST_F(SqliteDatabaseBackend, DefaultTextEncoding)
 {
-    ASSERT_THAT(databaseBackend.textEncoding(), Utf8);
+    ASSERT_THAT(databaseBackend.textEncoding(), TextEncoding::Utf8);
 }
 
 TEST_F(SqliteDatabaseBackend, Utf16TextEncoding)
 {
-    databaseBackend.setTextEncoding(Utf16);
+    databaseBackend.setTextEncoding(TextEncoding::Utf16);
 
-    ASSERT_THAT(databaseBackend.textEncoding(), Utf16);
+    ASSERT_THAT(databaseBackend.textEncoding(), TextEncoding::Utf16);
 }
 
 TEST_F(SqliteDatabaseBackend, Utf16beTextEncoding)
 {
-    databaseBackend.setTextEncoding(Utf16be);
+    databaseBackend.setTextEncoding(TextEncoding::Utf16be);
 
-    ASSERT_THAT(databaseBackend.textEncoding(), Utf16be);
+    ASSERT_THAT(databaseBackend.textEncoding(),TextEncoding::Utf16be);
 }
 
 TEST_F(SqliteDatabaseBackend, Utf16leTextEncoding)
 {
-    databaseBackend.setTextEncoding(Utf16le);
+    databaseBackend.setTextEncoding(TextEncoding::Utf16le);
 
-    ASSERT_THAT(databaseBackend.textEncoding(), Utf16le);
+    ASSERT_THAT(databaseBackend.textEncoding(), TextEncoding::Utf16le);
 }
 
 TEST_F(SqliteDatabaseBackend, Utf8TextEncoding)
 {
-    databaseBackend.setTextEncoding(Utf8);
+    databaseBackend.setTextEncoding(TextEncoding::Utf8);
 
-    ASSERT_THAT(databaseBackend.textEncoding(), Utf8);
+    ASSERT_THAT(databaseBackend.textEncoding(), TextEncoding::Utf8);
 }
 
 TEST_F(SqliteDatabaseBackend, TextEncodingCannotBeChangedAfterTouchingDatabase)
@@ -143,7 +148,7 @@ TEST_F(SqliteDatabaseBackend, TextEncodingCannotBeChangedAfterTouchingDatabase)
 
     databaseBackend.execute("CREATE TABLE text(name, number)");
 
-    ASSERT_THROW(databaseBackend.setTextEncoding(Utf16), SqliteException);
+    ASSERT_THROW(databaseBackend.setTextEncoding(TextEncoding::Utf16), SqliteException);
 }
 
 TEST_F(SqliteDatabaseBackend, OpenModeReadOnly)
diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp
index 3bf97e6d73d5a3235898b5e6f7d4cba7268a7652..b3523bdc77056130b5fda29a20d0cba721f25913 100644
--- a/tests/unit/unittest/sqlitestatement-test.cpp
+++ b/tests/unit/unittest/sqlitestatement-test.cpp
@@ -30,14 +30,15 @@
 #include <sqlitereadwritestatement.h>
 #include <sqlitewritestatement.h>
 
+#include <utils/smallstringio.h>
+
 #include <QDir>
 
 #include <vector>
 
 namespace {
-using testing::ElementsAre;
-using testing::PrintToString;
 
+using Sqlite::JournalMode;
 using Sqlite::SqliteException;
 using Sqlite::SqliteDatabase;
 using Sqlite::SqliteReadStatement;
@@ -71,6 +72,21 @@ protected:
     SqliteDatabase database;
 };
 
+struct Output
+{
+    Utils::SmallString name;
+    Utils::SmallString number;
+    long long value;
+    friend bool operator==(const Output &f, const Output &s)
+    {
+        return f.name == s.name && f.number == s.number && f.value == s.value;
+    }
+    friend std::ostream &operator<<(std::ostream &out, const Output &o)
+    {
+        return out << "(" << o.name << ", " << ", " << o.number<< ", " << o.value<< ")";
+    }
+};
+
 TEST_F(SqliteStatement, PrepareFailure)
 {
     ASSERT_THROW(SqliteReadStatement("blah blah blah", database), SqliteException);
@@ -99,11 +115,11 @@ TEST_F(SqliteStatement, Value)
     statement.next();
 
     ASSERT_THAT(statement.value<int>(0), 0);
-    ASSERT_THAT(statement.value<qint64>(0), 0);
+    ASSERT_THAT(statement.value<int64_t>(0), 0);
     ASSERT_THAT(statement.value<double>(0), 0.0);
     ASSERT_THAT(statement.text(0), "foo");
     ASSERT_THAT(statement.value<int>(1), 23);
-    ASSERT_THAT(statement.value<qint64>(1), 23);
+    ASSERT_THAT(statement.value<int64_t>(1), 23);
     ASSERT_THAT(statement.value<double>(1), 23.3);
     ASSERT_THAT(statement.text(1), "23.3");
 }
@@ -127,12 +143,14 @@ TEST_F(SqliteStatement, ValueFailure)
 
 TEST_F(SqliteStatement, ToIntergerValue)
 {
-    ASSERT_THAT(SqliteReadStatement::toValue<int>("SELECT number FROM test WHERE name='foo'", database), 23);
+    auto value = SqliteReadStatement::toValue<int>("SELECT number FROM test WHERE name='foo'", database);
+
+    ASSERT_THAT(value, 23);
 }
 
 TEST_F(SqliteStatement, ToLongIntergerValue)
 {
-    ASSERT_THAT(SqliteReadStatement::toValue<qint64>("SELECT number FROM test WHERE name='foo'", database), 23LL);
+    ASSERT_THAT(SqliteReadStatement::toValue<qint64>("SELECT number FROM test WHERE name='foo'", database), Eq(23));
 }
 
 TEST_F(SqliteStatement, ToDoubleValue)
@@ -145,31 +163,6 @@ TEST_F(SqliteStatement, ToStringValue)
     ASSERT_THAT(SqliteReadStatement::toValue<Utils::SmallString>("SELECT name FROM test WHERE name='foo'", database), "foo");
 }
 
-TEST_F(SqliteStatement, Utf8Values)
-{
-    SqliteReadStatement statement("SELECT name, number FROM test ORDER by name", database);
-
-    auto values = statement.values<Utils::SmallStringVector>();
-
-    ASSERT_THAT(values, ElementsAre("bar", "foo", "poo"));
-}
-TEST_F(SqliteStatement, DoubleValues)
-{
-    SqliteReadStatement statement("SELECT name, number FROM test ORDER by name", database);
-
-    auto values = statement.values<std::vector<double>>(1);
-
-    ASSERT_THAT(values, ElementsAre(0.0, 23.3, 40.0));
-}
-
-TEST_F(SqliteStatement, ValuesFailure)
-{
-    SqliteReadStatement statement("SELECT name, number FROM test", database);
-
-    ASSERT_THROW(statement.values<Utils::SmallStringVector>({1, 2}), SqliteException);
-    ASSERT_THROW(statement.values<Utils::SmallStringVector>({-1, 1}), SqliteException);
-}
-
 TEST_F(SqliteStatement, ColumnNames)
 {
     SqliteReadStatement statement("SELECT name, number FROM test", database);
@@ -206,7 +199,7 @@ TEST_F(SqliteStatement, BindLongInteger)
 {
     SqliteReadStatement statement("SELECT name, number FROM test WHERE number=?", database);
 
-    statement.bind(1, qint64(40));
+    statement.bind(1, int64_t(40));
     statement.next();
 
     ASSERT_THAT(statement.text(0), "poo");
@@ -236,7 +229,7 @@ TEST_F(SqliteStatement, BindLongIntegerByParameter)
 {
     SqliteReadStatement statement("SELECT name, number FROM test WHERE number=@number", database);
 
-    statement.bind("@number", qint64(40));
+    statement.bind("@number", int64_t(40));
     statement.next();
 
     ASSERT_THAT(statement.text(0), "poo");
@@ -315,14 +308,156 @@ TEST_F(SqliteStatement, ClosedDatabase)
     database.open(QDir::tempPath() + QStringLiteral("/SqliteStatementTest.db"));
 }
 
+TEST_F(SqliteStatement, GetTupleValuesWithoutArguments)
+{
+    using Tuple = std::tuple<Utils::SmallString, double, int>;
+    SqliteReadStatement statement("SELECT name, number, value FROM test", database);
+
+    auto values = statement.tupleValues<Utils::SmallString, double, int>(3);
+
+    ASSERT_THAT(values, ElementsAre(Tuple{"bar", 0, 1},
+                                    Tuple{"foo", 23.3, 2},
+                                    Tuple{"poo", 40.0, 3}));
+}
+
+TEST_F(SqliteStatement, GetSingleValuesWithoutArguments)
+{
+    SqliteReadStatement statement("SELECT name FROM test", database);
+
+    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3);
+
+    ASSERT_THAT(values, ElementsAre("bar", "foo", "poo"));
+}
+
+TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
+{
+    SqliteReadStatement statement("SELECT name, number, value FROM test", database);
+
+    auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3);
+
+    ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1},
+                                    Output{"foo", "23.3", 2},
+                                    Output{"poo", "40", 3}));
+}
+
+
+TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes)
+{
+    SqliteReadStatement statement("SELECT name FROM test WHERE number=?", database);
+    statement.values<Utils::SmallString>(3, 40);
+
+    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, 40);
+
+    ASSERT_THAT(values, ElementsAre("poo"));
+}
+
+TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryValues)
+{
+    using Tuple = std::tuple<Utils::SmallString, double, double>;
+    std::vector<double> queryValues = {40, 23.3};
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
+
+    auto values = statement.tupleValues<Utils::SmallString, double, double>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre(Tuple{"poo", 40, 3.},
+                                    Tuple{"foo", 23.3, 2.}));
+}
+
+TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryValues)
+{
+    std::vector<double> queryValues = {40, 23.3};
+    SqliteReadStatement statement("SELECT name, number FROM test WHERE number=?", database);
+
+    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre("poo", "foo"));
+}
+
+TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryTupleValues)
+{
+    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, int>;
+    using Tuple2 = std::tuple<Utils::SmallString, double, int>;
+    std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
+
+    auto values = statement.tupleValues<Utils::SmallString, double, int>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre(Tuple2{"poo", 40, 3},
+                                    Tuple2{"bar", 0, 1}));
+}
+
+TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryTupleValues)
+{
+    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString>;
+    std::vector<Tuple> queryValues = {{"poo", "40"}, {"bar", "blah"}};
+    SqliteReadStatement statement("SELECT name, number FROM test WHERE name= ? AND number=?", database);
+
+    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre("poo", "bar"));
+}
+
+TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndMultipleQueryValue)
+{
+    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
+
+    auto values = statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah", 1);
+
+    ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
+}
+
+TEST_F(SqliteStatement, CallGetValuesForMultipleOutputValuesAndMultipleQueryValueMultipleTimes)
+{
+    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=?", database);
+    statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah");
+
+    auto values = statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah");
+
+    ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
+}
+
+TEST_F(SqliteStatement, GetStructOutputValuesAndMultipleQueryValue)
+{
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
+
+    auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah", 1);
+
+    ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1}));
+}
+
+TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryValues)
+{
+    std::vector<double> queryValues = {40, 23.3};
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
+
+    auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
+                                    Output{"foo", "23.3", 2}));
+}
+
+TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryTupleValues)
+{
+    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, int>;
+    std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
+    SqliteReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
+
+    auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, queryValues);
+
+    ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
+                                    Output{"bar", "blah", 1}));
+}
+
 void SqliteStatement::SetUp()
 {
     database.setJournalMode(JournalMode::Memory);
     database.open(":memory:");
-    database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC)");
-    database.execute("INSERT INTO  test VALUES ('bar', 'blah')");
-    database.execute("INSERT INTO  test VALUES ('foo', 23.3)");
-    database.execute("INSERT INTO  test VALUES ('poo', 40)");
+    database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)");
+    database.execute("INSERT INTO  test VALUES ('bar', 'blah', 1)");
+    database.execute("INSERT INTO  test VALUES ('foo', 23.3, 2)");
+    database.execute("INSERT INTO  test VALUES ('poo', 40, 3)");
 }
 
 void SqliteStatement::TearDown()
diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp
index 9c1b2aa79ab4f4bb275c11d0cf18ac377667e918..7873181580c7fedc18fffcb3841886edbed4cc5f 100644
--- a/tests/unit/unittest/sqlitetable-test.cpp
+++ b/tests/unit/unittest/sqlitetable-test.cpp
@@ -32,6 +32,9 @@
 
 namespace {
 
+using Sqlite::ColumnType;
+using Sqlite::JournalMode;
+using Sqlite::OpenMode;
 using Sqlite::SqliteColumn;
 using Sqlite::SqliteDatabase;
 
diff --git a/tests/unit/unittest/sqlstatementbuilder-test.cpp b/tests/unit/unittest/sqlstatementbuilder-test.cpp
index 028a141c72947b7ed0c7c6622071cd5bcdbf08b5..ef3a66e1da5b7f1873cf9ee054bbb53b36f26d65 100644
--- a/tests/unit/unittest/sqlstatementbuilder-test.cpp
+++ b/tests/unit/unittest/sqlstatementbuilder-test.cpp
@@ -30,6 +30,7 @@
 
 using namespace ::testing;
 
+using Sqlite::ColumnType;
 using Sqlite::SqlStatementBuilder;
 using Sqlite::SqlStatementBuilderException;