forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -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 ¯oNameColumn = 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);
|
||||
|
||||
@@ -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,7 +116,18 @@ Utils::SmallStringView actionToText(ForeignKeyAction action)
|
||||
return "";
|
||||
}
|
||||
|
||||
void appendForeignKey(Utils::SmallString &columnDefinitionString, const ForeignKey &foreignKey)
|
||||
class ContraintsVisiter
|
||||
{
|
||||
public:
|
||||
ContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||
: columnDefinitionString(columnDefinitionString)
|
||||
{}
|
||||
|
||||
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);
|
||||
@@ -145,6 +151,55 @@ void appendForeignKey(Utils::SmallString &columnDefinitionString, const ForeignK
|
||||
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(")");
|
||||
}
|
||||
|
||||
void operator()(const Collate &collate)
|
||||
{
|
||||
columnDefinitionString.append(" COLLATE ");
|
||||
columnDefinitionString.append(collate.collation);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -27,56 +27,135 @@
|
||||
|
||||
#include "sqliteforeignkey.h"
|
||||
|
||||
#include <sqlitevalue.h>
|
||||
#include <utils/smallstring.h>
|
||||
#include <utils/variant.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
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:
|
||||
DefaultValue(long long value)
|
||||
: value(value)
|
||||
{}
|
||||
|
||||
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 = ColumnType::Numeric,
|
||||
Contraint constraint = Contraint::NoConstraint,
|
||||
ForeignKey &&foreignKey = {})
|
||||
: foreignKey(std::move(foreignKey))
|
||||
, name(name)
|
||||
, tableName(tableName)
|
||||
, type(type)
|
||||
, constraint(constraint)
|
||||
{}
|
||||
|
||||
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>;
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -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(),
|
||||
constraints.emplace_back(ForeignKey{referencedTable.name(),
|
||||
"",
|
||||
foreignKeyupdateAction,
|
||||
foreignKeyDeleteAction,
|
||||
foreignKeyEnforcement);
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
{ForeignKey{"otherTable",
|
||||
"otherColumn",
|
||||
ForeignKeyAction::SetDefault,
|
||||
ForeignKeyAction::Cascade});
|
||||
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",
|
||||
{ForeignKey{"otherTable",
|
||||
"otherColumn",
|
||||
ForeignKeyAction::SetDefault,
|
||||
ForeignKeyAction::Cascade,
|
||||
Enforment::Deferred});
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
{ForeignKey{"referencedTable",
|
||||
"referencedColumn",
|
||||
ForeignKeyAction::SetNull,
|
||||
ForeignKeyAction::Cascade,
|
||||
Enforment::Deferred}};
|
||||
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,
|
||||
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)))));
|
||||
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",
|
||||
{ForeignKey{"referencedTable",
|
||||
"referencedColumn",
|
||||
ForeignKeyAction::SetNull,
|
||||
ForeignKeyAction::Cascade,
|
||||
Enforment::Deferred};
|
||||
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,
|
||||
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)))));
|
||||
Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
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)))));
|
||||
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,
|
||||
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)))));
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user