aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/sqlite/constraints.h5
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.cpp44
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.h8
-rw-r--r--src/libs/sqlite/sqlite-lib.pri1
-rw-r--r--src/libs/sqlite/sqlitetable.h13
-rw-r--r--src/libs/sqlite/tableconstraints.h49
-rw-r--r--tests/unit/unittest/createtablesqlstatementbuilder-test.cpp13
-rw-r--r--tests/unit/unittest/sqlitetable-test.cpp13
8 files changed, 139 insertions, 7 deletions
diff --git a/src/libs/sqlite/constraints.h b/src/libs/sqlite/constraints.h
index d60a767a28..c8e1ecf7d7 100644
--- a/src/libs/sqlite/constraints.h
+++ b/src/libs/sqlite/constraints.h
@@ -42,7 +42,10 @@ enum class AutoIncrement { No, Yes };
class PrimaryKey
{
- friend bool operator==(PrimaryKey, PrimaryKey) { return true; }
+ friend bool operator==(PrimaryKey first, PrimaryKey second)
+ {
+ return first.autoincrement == second.autoincrement;
+ }
public:
AutoIncrement autoincrement = AutoIncrement::No;
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
index 2a14fe9ca5..2ea93d2bcd 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.cpp
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
@@ -48,7 +48,17 @@ void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName
m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints));
}
-void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
+void CreateTableSqlStatementBuilder::addConstraint(TableConstraint &&constraint)
+{
+ m_tableConstraints.push_back(std::move(constraint));
+}
+
+void CreateTableSqlStatementBuilder::setConstraints(TableConstraints constraints)
+{
+ m_tableConstraints = std::move(constraints);
+}
+
+void CreateTableSqlStatementBuilder::setColumns(SqliteColumns columns)
{
m_sqlStatementBuilder.clear();
@@ -212,8 +222,25 @@ public:
Utils::SmallString &columnDefinitionString;
};
+
+class TableContraintsVisiter
+{
+public:
+ TableContraintsVisiter(Utils::SmallString &columnDefinitionString)
+ : columnDefinitionString(columnDefinitionString)
+ {}
+
+ void operator()(const TablePrimaryKey &primaryKey)
+ {
+ columnDefinitionString.append("PRIMARY KEY(");
+ columnDefinitionString.append(primaryKey.columns.join(", "));
+ columnDefinitionString.append(")");
+ }
+
+ Utils::SmallString &columnDefinitionString;
+};
} // namespace
-void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
+void CreateTableSqlStatementBuilder::bindColumnDefinitionsAndTableConstraints() const
{
Utils::SmallStringVector columnDefinitionStrings;
columnDefinitionStrings.reserve(m_columns.size());
@@ -226,7 +253,16 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
for (const Constraint &constraint : column.constraints)
Utils::visit(visiter, constraint);
- columnDefinitionStrings.push_back(columnDefinitionString);
+ columnDefinitionStrings.push_back(std::move(columnDefinitionString));
+ }
+
+ for (const TableConstraint &constraint : m_tableConstraints) {
+ Utils::SmallString columnDefinitionString;
+
+ TableContraintsVisiter visiter{columnDefinitionString};
+ Utils::visit(visiter, constraint);
+
+ columnDefinitionStrings.push_back(std::move(columnDefinitionString));
}
m_sqlStatementBuilder.bind("$columnDefinitions", columnDefinitionStrings);
@@ -238,7 +274,7 @@ void CreateTableSqlStatementBuilder::bindAll() const
bindTemporary();
bindIfNotExists();
- bindColumnDefinitions();
+ bindColumnDefinitionsAndTableConstraints();
bindWithoutRowId();
}
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h
index 786753fdfa..3e3743e9da 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.h
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.h
@@ -27,6 +27,7 @@
#include "sqlitecolumn.h"
#include "sqlstatementbuilder.h"
+#include "tableconstraints.h"
namespace Sqlite {
@@ -40,7 +41,9 @@ public:
void addColumn(Utils::SmallStringView columnName,
ColumnType columnType,
Constraints &&constraints = {});
- void setColumns(const SqliteColumns &columns);
+ void addConstraint(TableConstraint &&constraint);
+ void setConstraints(TableConstraints constraints);
+ void setColumns(SqliteColumns columns);
void setUseWithoutRowId(bool useWithoutRowId);
void setUseIfNotExists(bool useIfNotExists);
void setUseTemporaryTable(bool useTemporaryTable);
@@ -53,7 +56,7 @@ public:
bool isValid() const;
protected:
- void bindColumnDefinitions() const;
+ void bindColumnDefinitionsAndTableConstraints() const;
void bindAll() const;
void bindWithoutRowId() const;
void bindIfNotExists() const;
@@ -63,6 +66,7 @@ private:
mutable SqlStatementBuilder m_sqlStatementBuilder;
Utils::SmallString m_tableName;
SqliteColumns m_columns;
+ TableConstraints m_tableConstraints;
bool m_useWithoutRowId = false;
bool m_useIfNotExits = false;
bool m_useTemporaryTable = false;
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
index 4c0b3a18e7..1ab7631387 100644
--- a/src/libs/sqlite/sqlite-lib.pri
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -27,6 +27,7 @@ SOURCES += \
$$PWD/sqlitebasestatement.cpp
HEADERS += \
$$PWD/constraints.h \
+ $$PWD/tableconstraints.h \
$$PWD/createtablesqlstatementbuilder.h \
$$PWD/lastchangedrowid.h \
$$PWD/sqlitedatabasebackend.h \
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index a7b524cd3b..9883415a9f 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -123,6 +123,17 @@ public:
return m_sqliteColumns.back();
}
+ void addPrimaryKeyContraint(const SqliteColumnConstReferences &columns)
+ {
+ Utils::SmallStringVector columnNames;
+ columnNames.reserve(columns.size());
+
+ for (const auto &column : columns)
+ columnNames.emplace_back(column.get().name);
+
+ m_tableConstraints.emplace_back(TablePrimaryKey{std::move(columnNames)});
+ }
+
Index &addIndex(const SqliteColumnConstReferences &columns)
{
m_sqliteIndices.emplace_back(m_tableName.clone(), sqliteColumnNames(columns));
@@ -159,6 +170,7 @@ public:
builder.setUseIfNotExists(m_useIfNotExists);
builder.setUseTemporaryTable(m_useTemporaryTable);
builder.setColumns(m_sqliteColumns);
+ builder.setConstraints(m_tableConstraints);
database.execute(builder.sqlStatement());
@@ -207,6 +219,7 @@ private:
Utils::SmallString m_tableName;
SqliteColumns m_sqliteColumns;
SqliteIndices m_sqliteIndices;
+ TableConstraints m_tableConstraints;
bool m_withoutRowId = false;
bool m_useIfNotExists = false;
bool m_useTemporaryTable = false;
diff --git a/src/libs/sqlite/tableconstraints.h b/src/libs/sqlite/tableconstraints.h
new file mode 100644
index 0000000000..b2dee2c928
--- /dev/null
+++ b/src/libs/sqlite/tableconstraints.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "sqliteglobal.h"
+
+#include <sqlitevalue.h>
+#include <utils/smallstringvector.h>
+#include <utils/variant.h>
+
+namespace Sqlite {
+class TablePrimaryKey
+{
+ friend bool operator==(TablePrimaryKey first, TablePrimaryKey second)
+ {
+ return first.columns == second.columns;
+ }
+
+public:
+ Utils::SmallStringVector columns;
+};
+
+using TableConstraint = Utils::variant<TablePrimaryKey>;
+using TableConstraints = std::vector<TableConstraint>;
+
+} // namespace Sqlite
diff --git a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
index 49099081a0..0e92b06897 100644
--- a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
+++ b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
@@ -530,4 +530,17 @@ TEST_F(CreateTableSqlStatementBuilder, BlobType)
ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(data BLOB)");
}
+TEST_F(CreateTableSqlStatementBuilder, TablePrimaryKeyConstaint)
+{
+ builder.clear();
+ builder.setTableName("test");
+ builder.addColumn("id", ColumnType::Integer);
+ builder.addColumn("text", ColumnType::Text);
+
+ builder.addConstraint(Sqlite::TablePrimaryKey{{"id, text"}});
+ auto statement = builder.sqlStatement();
+
+ ASSERT_THAT(statement, "CREATE TABLE test(id INTEGER, text TEXT, PRIMARY KEY(id, text))");
+}
+
} // namespace
diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp
index 05d3e73462..f96b451785 100644
--- a/tests/unit/unittest/sqlitetable-test.cpp
+++ b/tests/unit/unittest/sqlitetable-test.cpp
@@ -292,4 +292,17 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithColumnAndNotNull)
VariantWith<Sqlite::NotNull>(Eq(Sqlite::NotNull{}))))));
}
+TEST_F(SqliteTable, AddPrimaryTableContraint)
+{
+ table.setName(tableName.clone());
+ const auto &idColumn = table.addColumn("id");
+ const auto &nameColumn = table.addColumn("name");
+ table.addPrimaryKeyContraint({idColumn, nameColumn});
+
+ EXPECT_CALL(mockDatabase,
+ execute(
+ Eq("CREATE TABLE testTable(id NUMERIC, name NUMERIC, PRIMARY KEY(id, name))")));
+
+ table.initialize(mockDatabase);
+}
} // namespace