summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2020-05-13 20:29:49 +0200
committerTim Jenssen <tim.jenssen@qt.io>2020-05-14 09:15:00 +0000
commitc4bbc74e37ab74e000ba6979474d281f203feba2 (patch)
tree878288e8c0fffc6fd4218bab4f20e800a84f4ad3
parenta86fd58e40ea8b1a1a80f69d878b2073ad9ebef0 (diff)
downloadqt-creator-c4bbc74e37ab74e000ba6979474d281f203feba2.tar.gz
Sqlite: Improve constraint support
Now you can add more than one constraint. And we added some new constraints too. Change-Id: I849d2d2ef6e44c897a65ff2bdfe8d172a345c991 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h16
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.cpp116
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.h4
-rw-r--r--src/libs/sqlite/sqlitecolumn.h139
-rw-r--r--src/libs/sqlite/sqliteglobal.h2
-rw-r--r--src/libs/sqlite/sqlitetable.h49
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.h2
-rw-r--r--tests/unit/unittest/createtablesqlstatementbuilder-test.cpp206
-rw-r--r--tests/unit/unittest/google-using-declarations.h18
-rw-r--r--tests/unit/unittest/sqlitecolumn-test.cpp74
-rw-r--r--tests/unit/unittest/sqlitedatabasebackend-test.cpp2
-rw-r--r--tests/unit/unittest/sqlitetable-test.cpp111
12 files changed, 497 insertions, 242 deletions
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index 426485a1fd..b26bd4ef04 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -66,7 +66,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("symbols");
- table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("symbolId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
const Sqlite::Column &symbolKindColumn = table.addColumn("symbolKind", Sqlite::ColumnType::Integer);
@@ -100,7 +100,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("sources");
- table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("sourceId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &directoryIdColumn = table.addColumn("directoryId", Sqlite::ColumnType::Integer);
const Sqlite::Column &sourceNameColumn = table.addColumn("sourceName", Sqlite::ColumnType::Text);
table.addUniqueIndex({directoryIdColumn, sourceNameColumn});
@@ -113,7 +113,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("directories");
- table.addColumn("directoryId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("directoryId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &directoryPathColumn = table.addColumn("directoryPath", Sqlite::ColumnType::Text);
table.addUniqueIndex({directoryPathColumn});
@@ -125,7 +125,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("projectParts");
- table.addColumn("projectPartId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("projectPartId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &projectPartNameColumn = table.addColumn("projectPartName", Sqlite::ColumnType::Text);
table.addColumn("toolChainArguments", Sqlite::ColumnType::Text);
table.addColumn("compilerMacros", Sqlite::ColumnType::Text);
@@ -160,7 +160,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("usedMacros");
- table.addColumn("usedMacroId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("usedMacroId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
const Sqlite::Column &macroNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text);
table.addIndex({sourceIdColumn, macroNameColumn});
@@ -174,9 +174,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("fileStatuses");
- table.addColumn("sourceId",
- Sqlite::ColumnType::Integer,
- Sqlite::Contraint::PrimaryKey);
+ table.addColumn("sourceId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
table.addColumn("size", Sqlite::ColumnType::Integer);
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
table.addColumn("indexingTimeStamp", Sqlite::ColumnType::Integer);
@@ -201,7 +199,7 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("precompiledHeaders");
- table.addColumn("projectPartId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("projectPartId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
table.addColumn("projectPchPath", Sqlite::ColumnType::Text);
table.addColumn("projectPchBuildTime", Sqlite::ColumnType::Integer);
table.addColumn("systemPchPath", Sqlite::ColumnType::Text);
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
index c02169d2fd..aee797f8d4 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.cpp
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
@@ -41,16 +41,11 @@ void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName
void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName,
ColumnType columnType,
- Contraint constraint,
- ForeignKey &&foreignKey)
+ Constraints &&constraints)
{
m_sqlStatementBuilder.clear();
- m_columns.emplace_back(Utils::SmallStringView{},
- columnName,
- columnType,
- constraint,
- std::move(foreignKey));
+ m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints));
}
void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
@@ -121,30 +116,90 @@ Utils::SmallStringView actionToText(ForeignKeyAction action)
return "";
}
-void appendForeignKey(Utils::SmallString &columnDefinitionString, const ForeignKey &foreignKey)
+class ContraintsVisiter
{
- columnDefinitionString.append(" REFERENCES ");
- columnDefinitionString.append(foreignKey.table);
+public:
+ ContraintsVisiter(Utils::SmallString &columnDefinitionString)
+ : columnDefinitionString(columnDefinitionString)
+ {}
- if (foreignKey.column.hasContent()) {
- columnDefinitionString.append("(");
- columnDefinitionString.append(foreignKey.column);
+ void operator()(const Unique &) { columnDefinitionString.append(" UNIQUE"); }
+
+ void operator()(const PrimaryKey &) { columnDefinitionString.append(" PRIMARY KEY"); }
+
+ void operator()(const ForeignKey &foreignKey)
+ {
+ columnDefinitionString.append(" REFERENCES ");
+ columnDefinitionString.append(foreignKey.table);
+
+ if (foreignKey.column.hasContent()) {
+ columnDefinitionString.append("(");
+ columnDefinitionString.append(foreignKey.column);
+ columnDefinitionString.append(")");
+ }
+
+ if (foreignKey.updateAction != ForeignKeyAction::NoAction) {
+ columnDefinitionString.append(" ON UPDATE ");
+ columnDefinitionString.append(actionToText(foreignKey.updateAction));
+ }
+
+ if (foreignKey.deleteAction != ForeignKeyAction::NoAction) {
+ columnDefinitionString.append(" ON DELETE ");
+ columnDefinitionString.append(actionToText(foreignKey.deleteAction));
+ }
+
+ if (foreignKey.enforcement == Enforment::Deferred)
+ columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED");
+ }
+
+ void operator()(const NotNull &) { columnDefinitionString.append(" NOT NULL"); }
+
+ void operator()(const DefaultValue &defaultValue)
+ {
+ columnDefinitionString.append(" DEFAULT ");
+ switch (defaultValue.value.type()) {
+ case Sqlite::ValueType::Integer:
+ columnDefinitionString.append(
+ Utils::SmallString::number(defaultValue.value.toInteger()));
+ break;
+ case Sqlite::ValueType::Float:
+ columnDefinitionString.append(Utils::SmallString::number(defaultValue.value.toFloat()));
+ break;
+ case Sqlite::ValueType::String:
+ columnDefinitionString.append("\"");
+ columnDefinitionString.append(defaultValue.value.toStringView());
+ columnDefinitionString.append("\"");
+ break;
+ }
+ }
+
+ void operator()(const DefaultExpression &defaultexpression)
+ {
+ columnDefinitionString.append(" DEFAULT (");
+ columnDefinitionString.append(defaultexpression.expression);
columnDefinitionString.append(")");
}
- if (foreignKey.updateAction != ForeignKeyAction::NoAction) {
- columnDefinitionString.append(" ON UPDATE ");
- columnDefinitionString.append(actionToText(foreignKey.updateAction));
+ void operator()(const Collate &collate)
+ {
+ columnDefinitionString.append(" COLLATE ");
+ columnDefinitionString.append(collate.collation);
}
- if (foreignKey.deleteAction != ForeignKeyAction::NoAction) {
- columnDefinitionString.append(" ON DELETE ");
- columnDefinitionString.append(actionToText(foreignKey.deleteAction));
+ void operator()(const GeneratedAlways &generatedAlways)
+ {
+ columnDefinitionString.append(" GENERATED ALWAYS AS (");
+ columnDefinitionString.append(generatedAlways.expression);
+ columnDefinitionString.append(")");
+
+ if (generatedAlways.storage == Sqlite::GeneratedAlwaysStorage::Virtual)
+ columnDefinitionString.append(" VIRTUAL");
+ else
+ columnDefinitionString.append(" STORED");
}
- if (foreignKey.enforcement == Enforment::Deferred)
- columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED");
-}
+ Utils::SmallString &columnDefinitionString;
+};
} // namespace
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
{
@@ -154,19 +209,10 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
for (const Column &column : m_columns) {
Utils::SmallString columnDefinitionString = {column.name, " ", column.typeString()};
- switch (column.constraint) {
- case Contraint::PrimaryKey:
- columnDefinitionString.append(" PRIMARY KEY");
- break;
- case Contraint::Unique:
- columnDefinitionString.append(" UNIQUE");
- break;
- case Contraint::ForeignKey:
- appendForeignKey(columnDefinitionString, column.foreignKey);
- break;
- case Contraint::NoConstraint:
- break;
- }
+ ContraintsVisiter visiter{columnDefinitionString};
+
+ for (const Constraint &constraint : column.constraints)
+ mpark::visit(visiter, constraint);
columnDefinitionStrings.push_back(columnDefinitionString);
}
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h
index a62f1f4adb..786753fdfa 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.h
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.h
@@ -36,10 +36,10 @@ public:
CreateTableSqlStatementBuilder();
void setTableName(Utils::SmallString &&tableName);
+
void addColumn(Utils::SmallStringView columnName,
ColumnType columnType,
- Contraint constraint = Contraint::NoConstraint,
- ForeignKey &&foreignKey = {});
+ Constraints &&constraints = {});
void setColumns(const SqliteColumns &columns);
void setUseWithoutRowId(bool useWithoutRowId);
void setUseIfNotExists(bool useIfNotExists);
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
index fd31998f44..aae8230421 100644
--- a/src/libs/sqlite/sqlitecolumn.h
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -27,56 +27,135 @@
#include "sqliteforeignkey.h"
+#include <sqlitevalue.h>
#include <utils/smallstring.h>
+#include <utils/variant.h>
#include <functional>
namespace Sqlite {
-class Column
+class Unique
+{
+ friend bool operator==(Unique, Unique) { return true; }
+};
+
+class PrimaryKey
+{
+ friend bool operator==(PrimaryKey, PrimaryKey) { return true; }
+};
+
+class NotNull
+{
+ friend bool operator==(NotNull, NotNull) { return true; }
+};
+
+class DefaultValue
{
public:
- Column() = default;
+ DefaultValue(long long value)
+ : value(value)
+ {}
- Column(Utils::SmallStringView tableName,
- Utils::SmallStringView name,
- ColumnType type = ColumnType::Numeric,
- Contraint constraint = Contraint::NoConstraint,
- ForeignKey &&foreignKey = {})
- : foreignKey(std::move(foreignKey))
- , name(name)
- , tableName(tableName)
- , type(type)
- , constraint(constraint)
+ DefaultValue(double value)
+ : value(value)
{}
+ DefaultValue(Utils::SmallStringView value)
+ : value(value)
+ {}
+
+ friend bool operator==(const DefaultValue &first, const DefaultValue &second)
+ {
+ return first.value == second.value;
+ }
+
+public:
+ Sqlite::Value value;
+};
+
+class DefaultExpression
+{
+public:
+ DefaultExpression(Utils::SmallStringView expression)
+ : expression(expression)
+ {}
+
+ friend bool operator==(const DefaultExpression &first, const DefaultExpression &second)
+ {
+ return first.expression == second.expression;
+ }
+
+public:
+ Utils::SmallString expression;
+};
+
+class Collate
+{
+public:
+ Collate(Utils::SmallStringView collation)
+ : collation(collation)
+ {}
+
+ friend bool operator==(const Collate &first, const Collate &second)
+ {
+ return first.collation == second.collation;
+ }
+
+public:
+ Utils::SmallString collation;
+};
+
+enum class GeneratedAlwaysStorage { Stored, Virtual };
+
+class GeneratedAlways
+{
+public:
+ GeneratedAlways(Utils::SmallStringView expression, GeneratedAlwaysStorage storage)
+ : expression(expression)
+ , storage(storage)
+ {}
+
+ friend bool operator==(const GeneratedAlways &first, const GeneratedAlways &second)
+ {
+ return first.expression == second.expression;
+ }
+
+public:
+ Utils::SmallString expression;
+ GeneratedAlwaysStorage storage = {};
+};
+
+using Constraint = Utils::variant<Unique,
+ PrimaryKey,
+ ForeignKey,
+ NotNull,
+ DefaultValue,
+ DefaultExpression,
+ Collate,
+ GeneratedAlways>;
+using Constraints = std::vector<Constraint>;
+
+class Column
+{
+public:
+ Column() = default;
+
Column(Utils::SmallStringView tableName,
Utils::SmallStringView name,
ColumnType type,
- Contraint constraint,
- Utils::SmallStringView foreignKeyTable,
- Utils::SmallStringView foreignKeycolumn,
- ForeignKeyAction foreignKeyUpdateAction,
- ForeignKeyAction foreignKeyDeleteAction,
- Enforment foreignKeyEnforcement)
- : foreignKey(foreignKeyTable,
- foreignKeycolumn,
- foreignKeyUpdateAction,
- foreignKeyDeleteAction,
- foreignKeyEnforcement)
+ Constraints &&constraints = {})
+ : constraints(std::move(constraints))
, name(name)
, tableName(tableName)
, type(type)
- , constraint(constraint)
-
{}
void clear()
{
name.clear();
type = ColumnType::Numeric;
- constraint = Contraint::NoConstraint;
- foreignKey = {};
+ constraints = {};
}
Utils::SmallString typeString() const
@@ -100,16 +179,14 @@ public:
friend bool operator==(const Column &first, const Column &second)
{
return first.name == second.name && first.type == second.type
- && first.constraint
- == second.constraint /* && first.foreignKey == second.foreignKey*/;
+ && first.constraints == second.constraints && first.tableName == second.tableName;
}
public:
- ForeignKey foreignKey;
+ Constraints constraints;
Utils::SmallString name;
Utils::SmallString tableName;
ColumnType type = ColumnType::Numeric;
- Contraint constraint = Contraint::NoConstraint;
}; // namespace Sqlite
using SqliteColumns = std::vector<Column>;
diff --git a/src/libs/sqlite/sqliteglobal.h b/src/libs/sqlite/sqliteglobal.h
index 625c45a9ee..ed2b15e8b4 100644
--- a/src/libs/sqlite/sqliteglobal.h
+++ b/src/libs/sqlite/sqliteglobal.h
@@ -48,7 +48,7 @@ enum class ColumnType : char
None
};
-enum class Contraint : char { NoConstraint, PrimaryKey, Unique, ForeignKey };
+enum class ConstraintType : char { NoConstraint, PrimaryKey, Unique, ForeignKey };
enum class ForeignKeyAction : char { NoAction, Restrict, SetNull, SetDefault, Cascade };
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index 8c98959ef9..a7b524cd3b 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -73,9 +73,9 @@ public:
Column &addColumn(Utils::SmallStringView name,
ColumnType type = ColumnType::Numeric,
- Contraint constraint = Contraint::NoConstraint)
+ Constraints &&constraints = {})
{
- m_sqliteColumns.emplace_back(m_tableName, name, type, constraint);
+ m_sqliteColumns.emplace_back(m_tableName, name, type, std::move(constraints));
return m_sqliteColumns.back();
}
@@ -85,17 +85,16 @@ public:
ForeignKeyAction foreignKeyupdateAction = {},
ForeignKeyAction foreignKeyDeleteAction = {},
Enforment foreignKeyEnforcement = {},
+ Constraints &&constraints = {},
ColumnType type = ColumnType::Integer)
{
- m_sqliteColumns.emplace_back(m_tableName,
- name,
- type,
- Contraint::ForeignKey,
- referencedTable.name(),
- "",
- foreignKeyupdateAction,
- foreignKeyDeleteAction,
- foreignKeyEnforcement);
+ constraints.emplace_back(ForeignKey{referencedTable.name(),
+ "",
+ foreignKeyupdateAction,
+ foreignKeyDeleteAction,
+ foreignKeyEnforcement});
+
+ m_sqliteColumns.emplace_back(m_tableName, name, type, std::move(constraints));
return m_sqliteColumns.back();
}
@@ -104,20 +103,22 @@ public:
const Column &referencedColumn,
ForeignKeyAction foreignKeyupdateAction = {},
ForeignKeyAction foreignKeyDeleteAction = {},
- Enforment foreignKeyEnforcement = {})
+ Enforment foreignKeyEnforcement = {},
+ Constraints &&constraints = {})
{
- if (referencedColumn.constraint != Contraint::Unique)
+ if (!constainsUniqueIndex(referencedColumn.constraints))
throw ForeignKeyColumnIsNotUnique("Foreign column key must be unique!");
+ constraints.emplace_back(ForeignKey{referencedColumn.tableName,
+ referencedColumn.name,
+ foreignKeyupdateAction,
+ foreignKeyDeleteAction,
+ foreignKeyEnforcement});
+
m_sqliteColumns.emplace_back(m_tableName,
name,
referencedColumn.type,
- Contraint::ForeignKey,
- referencedColumn.tableName,
- referencedColumn.name,
- foreignKeyupdateAction,
- foreignKeyDeleteAction,
- foreignKeyEnforcement);
+ std::move(constraints));
return m_sqliteColumns.back();
}
@@ -181,6 +182,16 @@ public:
&& first.m_sqliteColumns == second.m_sqliteColumns;
}
+ static bool constainsUniqueIndex(const Constraints &constraints)
+ {
+ return std::find_if(constraints.begin(),
+ constraints.end(),
+ [](const Constraint &constraint) {
+ return Utils::holds_alternative<Unique>(constraint);
+ })
+ != constraints.end();
+ }
+
private:
Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
{
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
index f61dc0557d..89855b98cb 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorage.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -123,7 +123,7 @@ public:
Sqlite::Table table;
table.setName("newSymbols");
table.setUseTemporaryTable(true);
- table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
const Sqlite::Column &symbolIdColumn = table.addColumn("symbolId", Sqlite::ColumnType::Integer);
const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
diff --git a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
index 39e927797b..c8ff7b47b2 100644
--- a/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
+++ b/tests/unit/unittest/createtablesqlstatementbuilder-test.cpp
@@ -32,19 +32,38 @@ namespace {
using Sqlite::Column;
using Sqlite::ColumnType;
-using Sqlite::Contraint;
+using Sqlite::ConstraintType;
using Sqlite::Enforment;
+using Sqlite::ForeignKey;
using Sqlite::ForeignKeyAction;
using Sqlite::JournalMode;
using Sqlite::OpenMode;
+using Sqlite::PrimaryKey;
using Sqlite::SqliteColumns;
using Sqlite::SqlStatementBuilderException;
+using Sqlite::Unique;
class CreateTableSqlStatementBuilder : public ::testing::Test
{
protected:
- void bindValues();
- static SqliteColumns createColumns();
+ void bindValues()
+ {
+ builder.clear();
+ builder.setTableName("test");
+ builder.addColumn("id", ColumnType::Integer, {PrimaryKey{}});
+ builder.addColumn("name", ColumnType::Text);
+ builder.addColumn("number", ColumnType::Numeric);
+ }
+
+ static SqliteColumns createColumns()
+ {
+ SqliteColumns columns;
+ columns.emplace_back("", "id", ColumnType::Integer, Sqlite::Constraints{PrimaryKey{}});
+ columns.emplace_back("", "name", ColumnType::Text);
+ columns.emplace_back("", "number", ColumnType::Numeric);
+
+ return columns;
+ }
protected:
Sqlite::CreateTableSqlStatementBuilder builder;
@@ -158,7 +177,7 @@ TEST_F(CreateTableSqlStatementBuilder, UniqueContraint)
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::Unique);
+ builder.addColumn("id", ColumnType::Integer, {Unique{}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER UNIQUE)");
@@ -168,7 +187,7 @@ TEST_F(CreateTableSqlStatementBuilder, IfNotExitsModifier)
{
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
+ builder.addColumn("id", ColumnType::Integer, {});
builder.setUseIfNotExists(true);
@@ -180,7 +199,7 @@ TEST_F(CreateTableSqlStatementBuilder, TemporaryTable)
{
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
+ builder.addColumn("id", ColumnType::Integer, {});
builder.setUseTemporaryTable(true);
@@ -188,31 +207,12 @@ TEST_F(CreateTableSqlStatementBuilder, TemporaryTable)
"CREATE TEMPORARY TABLE test(id INTEGER)");
}
-void CreateTableSqlStatementBuilder::bindValues()
-{
- builder.clear();
- builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::PrimaryKey);
- builder.addColumn("name", ColumnType::Text);
- builder.addColumn("number",ColumnType:: Numeric);
-}
-
-SqliteColumns CreateTableSqlStatementBuilder::createColumns()
-{
- SqliteColumns columns;
- columns.emplace_back("", "id", ColumnType::Integer, Contraint::PrimaryKey);
- columns.emplace_back("", "name", ColumnType::Text);
- columns.emplace_back("", "number", ColumnType::Numeric);
-
- return columns;
-}
-
TEST_F(CreateTableSqlStatementBuilder, ForeignKeyWithoutColumn)
{
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", ""});
+ builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", ""}});
ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id INTEGER REFERENCES otherTable)");
}
@@ -222,7 +222,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyWithColumn)
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
+ builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
@@ -233,7 +233,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateNoAction)
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
+ builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
@@ -246,8 +246,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateRestrict)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", ForeignKeyAction::Restrict});
+ {ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::Restrict}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -261,8 +260,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateSetNull)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", ForeignKeyAction::SetNull});
+ {ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::SetNull}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -276,8 +274,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateSetDefault)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", ForeignKeyAction::SetDefault});
+ {ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::SetDefault}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -291,8 +288,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateCascade)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", ForeignKeyAction::Cascade});
+ {ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::Cascade}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -304,7 +300,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteNoAction)
builder.clear();
builder.setTableName("test");
- builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
+ builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
@@ -317,8 +313,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteRestrict)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", {}, ForeignKeyAction::Restrict});
+ {ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::Restrict}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -332,8 +327,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteSetNull)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", {}, ForeignKeyAction::SetNull});
+ {ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::SetNull}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -347,8 +341,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteSetDefault)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", {}, ForeignKeyAction::SetDefault});
+ {ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::SetDefault}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -362,8 +355,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteCascade)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable", "otherColumn", {}, ForeignKeyAction::Cascade});
+ {ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::Cascade}});
ASSERT_THAT(
builder.sqlStatement(),
@@ -377,11 +369,10 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteAndUpdateAction)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable",
- "otherColumn",
- ForeignKeyAction::SetDefault,
- ForeignKeyAction::Cascade});
+ {ForeignKey{"otherTable",
+ "otherColumn",
+ ForeignKeyAction::SetDefault,
+ ForeignKeyAction::Cascade}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
@@ -395,15 +386,118 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeferred)
builder.addColumn("id",
ColumnType::Integer,
- Contraint::ForeignKey,
- {"otherTable",
- "otherColumn",
- ForeignKeyAction::SetDefault,
- ForeignKeyAction::Cascade,
- Enforment::Deferred});
+ {ForeignKey{"otherTable",
+ "otherColumn",
+ ForeignKeyAction::SetDefault,
+ ForeignKeyAction::Cascade,
+ Enforment::Deferred}});
ASSERT_THAT(builder.sqlStatement(),
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
"DEFAULT ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)");
}
+
+TEST_F(CreateTableSqlStatementBuilder, NotNullConstraint)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Integer, {Sqlite::NotNull{}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id INTEGER NOT NULL)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, NotNullAndUniqueConstraint)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Integer, {Sqlite::Unique{}, Sqlite::NotNull{}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id INTEGER UNIQUE NOT NULL)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, DefaultValueInt)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Integer, {Sqlite::DefaultValue{1LL}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id INTEGER DEFAULT 1)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, DefaultValueFloat)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Real, {Sqlite::DefaultValue{1.1}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id REAL DEFAULT 1.100000)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, DefaultValueString)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Text, {Sqlite::DefaultValue{"foo"}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id TEXT DEFAULT \"foo\")");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, DefaultExpression)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id",
+ ColumnType::Integer,
+ {Sqlite::DefaultExpression{"SELECT name FROM foo WHERE id=?"}});
+
+ ASSERT_THAT(builder.sqlStatement(),
+ "CREATE TABLE test(id INTEGER DEFAULT (SELECT name FROM foo WHERE id=?))");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, Collation)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id", ColumnType::Text, {Sqlite::Collate{"unicode"}});
+
+ ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id TEXT COLLATE unicode)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, GeneratedAlwaysStored)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id",
+ ColumnType::Text,
+ {Sqlite::GeneratedAlways{"SELECT name FROM foo WHERE id=?",
+ Sqlite::GeneratedAlwaysStorage::Stored}});
+
+ ASSERT_THAT(
+ builder.sqlStatement(),
+ "CREATE TABLE test(id TEXT GENERATED ALWAYS AS (SELECT name FROM foo WHERE id=?) STORED)");
+}
+
+TEST_F(CreateTableSqlStatementBuilder, GeneratedAlwaysVirtual)
+{
+ builder.clear();
+ builder.setTableName("test");
+
+ builder.addColumn("id",
+ ColumnType::Text,
+ {Sqlite::GeneratedAlways{"SELECT name FROM foo WHERE id=?",
+ Sqlite::GeneratedAlwaysStorage::Virtual}});
+
+ ASSERT_THAT(builder.sqlStatement(),
+ "CREATE TABLE test(id TEXT GENERATED ALWAYS AS (SELECT name FROM foo WHERE id=?) "
+ "VIRTUAL)");
+}
+
} // namespace
diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h
index e8bbd52800..a1975ae7a8 100644
--- a/tests/unit/unittest/google-using-declarations.h
+++ b/tests/unit/unittest/google-using-declarations.h
@@ -37,21 +37,27 @@ using testing::AnyOf;
using testing::Assign;
using testing::ByMove;
using testing::ByRef;
-using testing::Contains;
using testing::ContainerEq;
+using testing::Contains;
using testing::ElementsAre;
+using testing::Eq;
using testing::Field;
+using testing::Ge;
+using testing::Gt;
using testing::HasSubstr;
using testing::InSequence;
using testing::Invoke;
using testing::IsEmpty;
using testing::IsNull;
+using testing::Le;
+using testing::Lt;
using testing::Matcher;
using testing::Mock;
using testing::MockFunction;
+using testing::Ne;
using testing::NiceMock;
-using testing::NotNull;
using testing::Not;
+using testing::NotNull;
using testing::Pair;
using testing::PrintToString;
using testing::Property;
@@ -64,10 +70,4 @@ using testing::StrEq;
using testing::Throw;
using testing::TypedEq;
using testing::UnorderedElementsAre;
-
-using testing::Eq;
-using testing::Ge;
-using testing::Gt;
-using testing::Le;
-using testing::Lt;
-using testing::Ne;
+using testing::VariantWith;
diff --git a/tests/unit/unittest/sqlitecolumn-test.cpp b/tests/unit/unittest/sqlitecolumn-test.cpp
index 0d6b1401ad..9753457c94 100644
--- a/tests/unit/unittest/sqlitecolumn-test.cpp
+++ b/tests/unit/unittest/sqlitecolumn-test.cpp
@@ -30,7 +30,7 @@
namespace {
using Sqlite::ColumnType;
-using Sqlite::Contraint;
+using Sqlite::ConstraintType;
using Sqlite::JournalMode;
using Sqlite::OpenMode;
using Column = Sqlite::Column;
@@ -51,13 +51,7 @@ TEST_F(SqliteColumn, DefaultConstruct)
AllOf(Field(&Column::name, IsEmpty()),
Field(&Column::tableName, IsEmpty()),
Field(&Column::type, ColumnType::Numeric),
- Field(&Column::constraint, Contraint::NoConstraint),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, IsEmpty()),
- Field(&ForeignKey::column, IsEmpty()),
- Field(&ForeignKey::updateAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::enforcement, Enforment::Immediate)))));
+ Field(&Column::constraints, IsEmpty())));
}
TEST_F(SqliteColumn, Clear)
@@ -65,11 +59,7 @@ TEST_F(SqliteColumn, Clear)
column.name = "foo";
column.name = "foo";
column.type = ColumnType::Text;
- column.constraint = Contraint::ForeignKey;
- column.foreignKey.table = "bar";
- column.foreignKey.column = "hmm";
- column.foreignKey.updateAction = ForeignKeyAction::Cascade;
- column.foreignKey.deleteAction = ForeignKeyAction::SetNull;
+ column.constraints = {Sqlite::PrimaryKey{}};
column.clear();
@@ -77,13 +67,7 @@ TEST_F(SqliteColumn, Clear)
AllOf(Field(&Column::name, IsEmpty()),
Field(&Column::tableName, IsEmpty()),
Field(&Column::type, ColumnType::Numeric),
- Field(&Column::constraint, Contraint::NoConstraint),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, IsEmpty()),
- Field(&ForeignKey::column, IsEmpty()),
- Field(&ForeignKey::updateAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::enforcement, Enforment::Immediate)))));
+ Field(&Column::constraints, IsEmpty())));
}
TEST_F(SqliteColumn, Constructor)
@@ -91,24 +75,23 @@ TEST_F(SqliteColumn, Constructor)
column = Sqlite::Column{"table",
"column",
ColumnType::Text,
- Contraint::ForeignKey,
- {"referencedTable",
- "referencedColumn",
- ForeignKeyAction::SetNull,
- ForeignKeyAction::Cascade,
- Enforment::Deferred}};
+ {ForeignKey{"referencedTable",
+ "referencedColumn",
+ ForeignKeyAction::SetNull,
+ ForeignKeyAction::Cascade,
+ Enforment::Deferred}}};
ASSERT_THAT(column,
AllOf(Field(&Column::name, Eq("column")),
Field(&Column::tableName, Eq("table")),
Field(&Column::type, ColumnType::Text),
- Field(&Column::constraint, Contraint::ForeignKey),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
- Field(&ForeignKey::column, Eq("referencedColumn")),
- Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
- Field(&ForeignKey::enforcement, Enforment::Deferred)))));
+ Field(&Column::constraints,
+ ElementsAre(VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
+ Field(&ForeignKey::column, Eq("referencedColumn")),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
}
TEST_F(SqliteColumn, FlatConstructor)
@@ -116,24 +99,23 @@ TEST_F(SqliteColumn, FlatConstructor)
column = Sqlite::Column{"table",
"column",
ColumnType::Text,
- Contraint::ForeignKey,
- "referencedTable",
- "referencedColumn",
- ForeignKeyAction::SetNull,
- ForeignKeyAction::Cascade,
- Enforment::Deferred};
+ {ForeignKey{"referencedTable",
+ "referencedColumn",
+ ForeignKeyAction::SetNull,
+ ForeignKeyAction::Cascade,
+ Enforment::Deferred}}};
ASSERT_THAT(column,
AllOf(Field(&Column::name, Eq("column")),
Field(&Column::tableName, Eq("table")),
Field(&Column::type, ColumnType::Text),
- Field(&Column::constraint, Contraint::ForeignKey),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
- Field(&ForeignKey::column, Eq("referencedColumn")),
- Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
- Field(&ForeignKey::enforcement, Enforment::Deferred)))));
+ Field(&Column::constraints,
+ ElementsAre(VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
+ Field(&ForeignKey::column, Eq("referencedColumn")),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
}
} // namespace
diff --git a/tests/unit/unittest/sqlitedatabasebackend-test.cpp b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
index 40227148bc..9957d3d4c7 100644
--- a/tests/unit/unittest/sqlitedatabasebackend-test.cpp
+++ b/tests/unit/unittest/sqlitedatabasebackend-test.cpp
@@ -39,7 +39,7 @@ namespace {
using Backend = Sqlite::DatabaseBackend;
using Sqlite::ColumnType;
-using Sqlite::Contraint;
+using Sqlite::ConstraintType;
using Sqlite::JournalMode;
using Sqlite::OpenMode;
using Sqlite::TextEncoding;
diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp
index 89dfb7f867..05d3e73462 100644
--- a/tests/unit/unittest/sqlitetable-test.cpp
+++ b/tests/unit/unittest/sqlitetable-test.cpp
@@ -34,7 +34,7 @@ namespace {
using Sqlite::Column;
using Sqlite::ColumnType;
-using Sqlite::Contraint;
+using Sqlite::ConstraintType;
using Sqlite::Database;
using Sqlite::Enforment;
using Sqlite::ForeignKey;
@@ -136,9 +136,7 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithColumnCalls)
{
Sqlite::Table foreignTable;
foreignTable.setName("foreignTable");
- auto &foreignColumn = foreignTable.addColumn("foreignColumn",
- ColumnType::Text,
- Sqlite::Contraint::Unique);
+ auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text, {Sqlite::Unique{}});
table.setName(tableName);
table.addForeignKeyColumn("name",
foreignColumn,
@@ -159,19 +157,14 @@ TEST_F(SqliteTable, AddColumn)
{
table.setName(tableName);
- auto &column = table.addColumn("name", ColumnType::Text, Sqlite::Contraint::Unique);
+ auto &column = table.addColumn("name", ColumnType::Text, {Sqlite::Unique{}});
ASSERT_THAT(column,
AllOf(Field(&Column::name, Eq("name")),
Field(&Column::tableName, Eq(tableName)),
Field(&Column::type, ColumnType::Text),
- Field(&Column::constraint, Contraint::Unique),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, IsEmpty()),
- Field(&ForeignKey::column, IsEmpty()),
- Field(&ForeignKey::updateAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::NoAction),
- Field(&ForeignKey::enforcement, Enforment::Immediate)))));
+ Field(&Column::constraints,
+ ElementsAre(VariantWith<Sqlite::Unique>(Eq(Sqlite::Unique{}))))));
}
TEST_F(SqliteTable, AddForeignKeyColumnWithTable)
@@ -191,22 +184,20 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithTable)
AllOf(Field(&Column::name, Eq("name")),
Field(&Column::tableName, Eq(tableName)),
Field(&Column::type, ColumnType::Integer),
- Field(&Column::constraint, Contraint::ForeignKey),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
- Field(&ForeignKey::column, IsEmpty()),
- Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
- Field(&ForeignKey::enforcement, Enforment::Deferred)))));
+ Field(&Column::constraints,
+ ElementsAre(VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
+ Field(&ForeignKey::column, IsEmpty()),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
}
TEST_F(SqliteTable, AddForeignKeyColumnWithColumn)
{
Sqlite::Table foreignTable;
foreignTable.setName("foreignTable");
- auto &foreignColumn = foreignTable.addColumn("foreignColumn",
- ColumnType::Text,
- Sqlite::Contraint::Unique);
+ auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text, {Sqlite::Unique{}});
table.setName(tableName);
auto &column = table.addForeignKeyColumn("name",
@@ -219,22 +210,20 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithColumn)
AllOf(Field(&Column::name, Eq("name")),
Field(&Column::tableName, Eq(tableName)),
Field(&Column::type, ColumnType::Text),
- Field(&Column::constraint, Contraint::ForeignKey),
- Field(&Column::foreignKey,
- AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
- Field(&ForeignKey::column, Eq("foreignColumn")),
- Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
- Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
- Field(&ForeignKey::enforcement, Enforment::Deferred)))));
+ Field(&Column::constraints,
+ ElementsAre(VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
+ Field(&ForeignKey::column, Eq("foreignColumn")),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
}
TEST_F(SqliteTable, AddForeignKeyWhichIsNotUniqueThrowsAnExceptions)
{
Sqlite::Table foreignTable;
foreignTable.setName("foreignTable");
- auto &foreignColumn = foreignTable.addColumn("foreignColumn",
- ColumnType::Text,
- Sqlite::Contraint::NoConstraint);
+ auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text);
table.setName(tableName);
ASSERT_THROW(table.addForeignKeyColumn("name",
@@ -245,4 +234,62 @@ TEST_F(SqliteTable, AddForeignKeyWhichIsNotUniqueThrowsAnExceptions)
Sqlite::ForeignKeyColumnIsNotUnique);
}
+TEST_F(SqliteTable, AddForeignKeyColumnWithTableAndNotNull)
+{
+ Sqlite::Table foreignTable;
+ foreignTable.setName("foreignTable");
+
+ table.setName(tableName);
+
+ auto &column = table.addForeignKeyColumn("name",
+ foreignTable,
+ ForeignKeyAction::SetNull,
+ ForeignKeyAction::Cascade,
+ Enforment::Deferred,
+ {Sqlite::NotNull{}});
+
+ ASSERT_THAT(column,
+ AllOf(Field(&Column::name, Eq("name")),
+ Field(&Column::tableName, Eq(tableName)),
+ Field(&Column::type, ColumnType::Integer),
+ Field(&Column::constraints,
+ UnorderedElementsAre(
+ VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
+ Field(&ForeignKey::column, IsEmpty()),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred))),
+ VariantWith<Sqlite::NotNull>(Eq(Sqlite::NotNull{}))))));
+}
+
+TEST_F(SqliteTable, AddForeignKeyColumnWithColumnAndNotNull)
+{
+ Sqlite::Table foreignTable;
+ foreignTable.setName("foreignTable");
+ auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text, {Sqlite::Unique{}});
+ table.setName(tableName);
+
+ auto &column = table.addForeignKeyColumn("name",
+ foreignColumn,
+ ForeignKeyAction::SetNull,
+ ForeignKeyAction::Cascade,
+ Enforment::Deferred,
+ {Sqlite::NotNull{}});
+
+ ASSERT_THAT(column,
+ AllOf(Field(&Column::name, Eq("name")),
+ Field(&Column::tableName, Eq(tableName)),
+ Field(&Column::type, ColumnType::Text),
+ Field(&Column::constraints,
+ UnorderedElementsAre(
+ VariantWith<ForeignKey>(
+ AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
+ Field(&ForeignKey::column, Eq("foreignColumn")),
+ Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
+ Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
+ Field(&ForeignKey::enforcement, Enforment::Deferred))),
+ VariantWith<Sqlite::NotNull>(Eq(Sqlite::NotNull{}))))));
+}
+
} // namespace