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;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("symbols");
|
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 &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||||
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||||
const Sqlite::Column &symbolKindColumn = table.addColumn("symbolKind", Sqlite::ColumnType::Integer);
|
const Sqlite::Column &symbolKindColumn = table.addColumn("symbolKind", Sqlite::ColumnType::Integer);
|
||||||
@@ -100,7 +100,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("sources");
|
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 &directoryIdColumn = table.addColumn("directoryId", Sqlite::ColumnType::Integer);
|
||||||
const Sqlite::Column &sourceNameColumn = table.addColumn("sourceName", Sqlite::ColumnType::Text);
|
const Sqlite::Column &sourceNameColumn = table.addColumn("sourceName", Sqlite::ColumnType::Text);
|
||||||
table.addUniqueIndex({directoryIdColumn, sourceNameColumn});
|
table.addUniqueIndex({directoryIdColumn, sourceNameColumn});
|
||||||
@@ -113,7 +113,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("directories");
|
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);
|
const Sqlite::Column &directoryPathColumn = table.addColumn("directoryPath", Sqlite::ColumnType::Text);
|
||||||
table.addUniqueIndex({directoryPathColumn});
|
table.addUniqueIndex({directoryPathColumn});
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("projectParts");
|
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);
|
const Sqlite::Column &projectPartNameColumn = table.addColumn("projectPartName", Sqlite::ColumnType::Text);
|
||||||
table.addColumn("toolChainArguments", Sqlite::ColumnType::Text);
|
table.addColumn("toolChainArguments", Sqlite::ColumnType::Text);
|
||||||
table.addColumn("compilerMacros", Sqlite::ColumnType::Text);
|
table.addColumn("compilerMacros", Sqlite::ColumnType::Text);
|
||||||
@@ -160,7 +160,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("usedMacros");
|
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 &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||||
const Sqlite::Column ¯oNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text);
|
const Sqlite::Column ¯oNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text);
|
||||||
table.addIndex({sourceIdColumn, macroNameColumn});
|
table.addIndex({sourceIdColumn, macroNameColumn});
|
||||||
@@ -174,9 +174,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("fileStatuses");
|
table.setName("fileStatuses");
|
||||||
table.addColumn("sourceId",
|
table.addColumn("sourceId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
|
||||||
Sqlite::ColumnType::Integer,
|
|
||||||
Sqlite::Contraint::PrimaryKey);
|
|
||||||
table.addColumn("size", Sqlite::ColumnType::Integer);
|
table.addColumn("size", Sqlite::ColumnType::Integer);
|
||||||
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
|
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
|
||||||
table.addColumn("indexingTimeStamp", Sqlite::ColumnType::Integer);
|
table.addColumn("indexingTimeStamp", Sqlite::ColumnType::Integer);
|
||||||
@@ -201,7 +199,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setName("precompiledHeaders");
|
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("projectPchPath", Sqlite::ColumnType::Text);
|
||||||
table.addColumn("projectPchBuildTime", Sqlite::ColumnType::Integer);
|
table.addColumn("projectPchBuildTime", Sqlite::ColumnType::Integer);
|
||||||
table.addColumn("systemPchPath", Sqlite::ColumnType::Text);
|
table.addColumn("systemPchPath", Sqlite::ColumnType::Text);
|
||||||
|
|||||||
@@ -41,16 +41,11 @@ void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName
|
|||||||
|
|
||||||
void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName,
|
void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName,
|
||||||
ColumnType columnType,
|
ColumnType columnType,
|
||||||
Contraint constraint,
|
Constraints &&constraints)
|
||||||
ForeignKey &&foreignKey)
|
|
||||||
{
|
{
|
||||||
m_sqlStatementBuilder.clear();
|
m_sqlStatementBuilder.clear();
|
||||||
|
|
||||||
m_columns.emplace_back(Utils::SmallStringView{},
|
m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints));
|
||||||
columnName,
|
|
||||||
columnType,
|
|
||||||
constraint,
|
|
||||||
std::move(foreignKey));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
|
void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
|
||||||
@@ -121,30 +116,90 @@ Utils::SmallStringView actionToText(ForeignKeyAction action)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendForeignKey(Utils::SmallString &columnDefinitionString, const ForeignKey &foreignKey)
|
class ContraintsVisiter
|
||||||
{
|
{
|
||||||
columnDefinitionString.append(" REFERENCES ");
|
public:
|
||||||
columnDefinitionString.append(foreignKey.table);
|
ContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||||
|
: columnDefinitionString(columnDefinitionString)
|
||||||
|
{}
|
||||||
|
|
||||||
if (foreignKey.column.hasContent()) {
|
void operator()(const Unique &) { columnDefinitionString.append(" UNIQUE"); }
|
||||||
columnDefinitionString.append("(");
|
|
||||||
columnDefinitionString.append(foreignKey.column);
|
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(")");
|
columnDefinitionString.append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreignKey.updateAction != ForeignKeyAction::NoAction) {
|
void operator()(const Collate &collate)
|
||||||
columnDefinitionString.append(" ON UPDATE ");
|
{
|
||||||
columnDefinitionString.append(actionToText(foreignKey.updateAction));
|
columnDefinitionString.append(" COLLATE ");
|
||||||
|
columnDefinitionString.append(collate.collation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreignKey.deleteAction != ForeignKeyAction::NoAction) {
|
void operator()(const GeneratedAlways &generatedAlways)
|
||||||
columnDefinitionString.append(" ON DELETE ");
|
{
|
||||||
columnDefinitionString.append(actionToText(foreignKey.deleteAction));
|
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)
|
Utils::SmallString &columnDefinitionString;
|
||||||
columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED");
|
};
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
|
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
|
||||||
{
|
{
|
||||||
@@ -154,19 +209,10 @@ void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
|
|||||||
for (const Column &column : m_columns) {
|
for (const Column &column : m_columns) {
|
||||||
Utils::SmallString columnDefinitionString = {column.name, " ", column.typeString()};
|
Utils::SmallString columnDefinitionString = {column.name, " ", column.typeString()};
|
||||||
|
|
||||||
switch (column.constraint) {
|
ContraintsVisiter visiter{columnDefinitionString};
|
||||||
case Contraint::PrimaryKey:
|
|
||||||
columnDefinitionString.append(" PRIMARY KEY");
|
for (const Constraint &constraint : column.constraints)
|
||||||
break;
|
mpark::visit(visiter, constraint);
|
||||||
case Contraint::Unique:
|
|
||||||
columnDefinitionString.append(" UNIQUE");
|
|
||||||
break;
|
|
||||||
case Contraint::ForeignKey:
|
|
||||||
appendForeignKey(columnDefinitionString, column.foreignKey);
|
|
||||||
break;
|
|
||||||
case Contraint::NoConstraint:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
columnDefinitionStrings.push_back(columnDefinitionString);
|
columnDefinitionStrings.push_back(columnDefinitionString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ public:
|
|||||||
CreateTableSqlStatementBuilder();
|
CreateTableSqlStatementBuilder();
|
||||||
|
|
||||||
void setTableName(Utils::SmallString &&tableName);
|
void setTableName(Utils::SmallString &&tableName);
|
||||||
|
|
||||||
void addColumn(Utils::SmallStringView columnName,
|
void addColumn(Utils::SmallStringView columnName,
|
||||||
ColumnType columnType,
|
ColumnType columnType,
|
||||||
Contraint constraint = Contraint::NoConstraint,
|
Constraints &&constraints = {});
|
||||||
ForeignKey &&foreignKey = {});
|
|
||||||
void setColumns(const SqliteColumns &columns);
|
void setColumns(const SqliteColumns &columns);
|
||||||
void setUseWithoutRowId(bool useWithoutRowId);
|
void setUseWithoutRowId(bool useWithoutRowId);
|
||||||
void setUseIfNotExists(bool useIfNotExists);
|
void setUseIfNotExists(bool useIfNotExists);
|
||||||
|
|||||||
@@ -27,56 +27,135 @@
|
|||||||
|
|
||||||
#include "sqliteforeignkey.h"
|
#include "sqliteforeignkey.h"
|
||||||
|
|
||||||
|
#include <sqlitevalue.h>
|
||||||
#include <utils/smallstring.h>
|
#include <utils/smallstring.h>
|
||||||
|
#include <utils/variant.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace Sqlite {
|
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
|
class Column
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Column() = default;
|
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,
|
Column(Utils::SmallStringView tableName,
|
||||||
Utils::SmallStringView name,
|
Utils::SmallStringView name,
|
||||||
ColumnType type,
|
ColumnType type,
|
||||||
Contraint constraint,
|
Constraints &&constraints = {})
|
||||||
Utils::SmallStringView foreignKeyTable,
|
: constraints(std::move(constraints))
|
||||||
Utils::SmallStringView foreignKeycolumn,
|
|
||||||
ForeignKeyAction foreignKeyUpdateAction,
|
|
||||||
ForeignKeyAction foreignKeyDeleteAction,
|
|
||||||
Enforment foreignKeyEnforcement)
|
|
||||||
: foreignKey(foreignKeyTable,
|
|
||||||
foreignKeycolumn,
|
|
||||||
foreignKeyUpdateAction,
|
|
||||||
foreignKeyDeleteAction,
|
|
||||||
foreignKeyEnforcement)
|
|
||||||
, name(name)
|
, name(name)
|
||||||
, tableName(tableName)
|
, tableName(tableName)
|
||||||
, type(type)
|
, type(type)
|
||||||
, constraint(constraint)
|
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
name.clear();
|
name.clear();
|
||||||
type = ColumnType::Numeric;
|
type = ColumnType::Numeric;
|
||||||
constraint = Contraint::NoConstraint;
|
constraints = {};
|
||||||
foreignKey = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::SmallString typeString() const
|
Utils::SmallString typeString() const
|
||||||
@@ -100,16 +179,14 @@ public:
|
|||||||
friend bool operator==(const Column &first, const Column &second)
|
friend bool operator==(const Column &first, const Column &second)
|
||||||
{
|
{
|
||||||
return first.name == second.name && first.type == second.type
|
return first.name == second.name && first.type == second.type
|
||||||
&& first.constraint
|
&& first.constraints == second.constraints && first.tableName == second.tableName;
|
||||||
== second.constraint /* && first.foreignKey == second.foreignKey*/;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ForeignKey foreignKey;
|
Constraints constraints;
|
||||||
Utils::SmallString name;
|
Utils::SmallString name;
|
||||||
Utils::SmallString tableName;
|
Utils::SmallString tableName;
|
||||||
ColumnType type = ColumnType::Numeric;
|
ColumnType type = ColumnType::Numeric;
|
||||||
Contraint constraint = Contraint::NoConstraint;
|
|
||||||
}; // namespace Sqlite
|
}; // namespace Sqlite
|
||||||
|
|
||||||
using SqliteColumns = std::vector<Column>;
|
using SqliteColumns = std::vector<Column>;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ enum class ColumnType : char
|
|||||||
None
|
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 };
|
enum class ForeignKeyAction : char { NoAction, Restrict, SetNull, SetDefault, Cascade };
|
||||||
|
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ public:
|
|||||||
|
|
||||||
Column &addColumn(Utils::SmallStringView name,
|
Column &addColumn(Utils::SmallStringView name,
|
||||||
ColumnType type = ColumnType::Numeric,
|
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();
|
return m_sqliteColumns.back();
|
||||||
}
|
}
|
||||||
@@ -85,17 +85,16 @@ public:
|
|||||||
ForeignKeyAction foreignKeyupdateAction = {},
|
ForeignKeyAction foreignKeyupdateAction = {},
|
||||||
ForeignKeyAction foreignKeyDeleteAction = {},
|
ForeignKeyAction foreignKeyDeleteAction = {},
|
||||||
Enforment foreignKeyEnforcement = {},
|
Enforment foreignKeyEnforcement = {},
|
||||||
|
Constraints &&constraints = {},
|
||||||
ColumnType type = ColumnType::Integer)
|
ColumnType type = ColumnType::Integer)
|
||||||
{
|
{
|
||||||
m_sqliteColumns.emplace_back(m_tableName,
|
constraints.emplace_back(ForeignKey{referencedTable.name(),
|
||||||
name,
|
"",
|
||||||
type,
|
foreignKeyupdateAction,
|
||||||
Contraint::ForeignKey,
|
foreignKeyDeleteAction,
|
||||||
referencedTable.name(),
|
foreignKeyEnforcement});
|
||||||
"",
|
|
||||||
foreignKeyupdateAction,
|
m_sqliteColumns.emplace_back(m_tableName, name, type, std::move(constraints));
|
||||||
foreignKeyDeleteAction,
|
|
||||||
foreignKeyEnforcement);
|
|
||||||
|
|
||||||
return m_sqliteColumns.back();
|
return m_sqliteColumns.back();
|
||||||
}
|
}
|
||||||
@@ -104,20 +103,22 @@ public:
|
|||||||
const Column &referencedColumn,
|
const Column &referencedColumn,
|
||||||
ForeignKeyAction foreignKeyupdateAction = {},
|
ForeignKeyAction foreignKeyupdateAction = {},
|
||||||
ForeignKeyAction foreignKeyDeleteAction = {},
|
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!");
|
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,
|
m_sqliteColumns.emplace_back(m_tableName,
|
||||||
name,
|
name,
|
||||||
referencedColumn.type,
|
referencedColumn.type,
|
||||||
Contraint::ForeignKey,
|
std::move(constraints));
|
||||||
referencedColumn.tableName,
|
|
||||||
referencedColumn.name,
|
|
||||||
foreignKeyupdateAction,
|
|
||||||
foreignKeyDeleteAction,
|
|
||||||
foreignKeyEnforcement);
|
|
||||||
|
|
||||||
return m_sqliteColumns.back();
|
return m_sqliteColumns.back();
|
||||||
}
|
}
|
||||||
@@ -181,6 +182,16 @@ public:
|
|||||||
&& first.m_sqliteColumns == second.m_sqliteColumns;
|
&& 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:
|
private:
|
||||||
Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
|
Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public:
|
|||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setName("newSymbols");
|
table.setName("newSymbols");
|
||||||
table.setUseTemporaryTable(true);
|
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 &symbolIdColumn = table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||||
const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||||
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||||
|
|||||||
@@ -32,19 +32,38 @@ namespace {
|
|||||||
|
|
||||||
using Sqlite::Column;
|
using Sqlite::Column;
|
||||||
using Sqlite::ColumnType;
|
using Sqlite::ColumnType;
|
||||||
using Sqlite::Contraint;
|
using Sqlite::ConstraintType;
|
||||||
using Sqlite::Enforment;
|
using Sqlite::Enforment;
|
||||||
|
using Sqlite::ForeignKey;
|
||||||
using Sqlite::ForeignKeyAction;
|
using Sqlite::ForeignKeyAction;
|
||||||
using Sqlite::JournalMode;
|
using Sqlite::JournalMode;
|
||||||
using Sqlite::OpenMode;
|
using Sqlite::OpenMode;
|
||||||
|
using Sqlite::PrimaryKey;
|
||||||
using Sqlite::SqliteColumns;
|
using Sqlite::SqliteColumns;
|
||||||
using Sqlite::SqlStatementBuilderException;
|
using Sqlite::SqlStatementBuilderException;
|
||||||
|
using Sqlite::Unique;
|
||||||
|
|
||||||
class CreateTableSqlStatementBuilder : public ::testing::Test
|
class CreateTableSqlStatementBuilder : public ::testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void bindValues();
|
void bindValues()
|
||||||
static SqliteColumns createColumns();
|
{
|
||||||
|
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:
|
protected:
|
||||||
Sqlite::CreateTableSqlStatementBuilder builder;
|
Sqlite::CreateTableSqlStatementBuilder builder;
|
||||||
@@ -158,7 +177,7 @@ TEST_F(CreateTableSqlStatementBuilder, UniqueContraint)
|
|||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
|
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::Unique);
|
builder.addColumn("id", ColumnType::Integer, {Unique{}});
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER UNIQUE)");
|
"CREATE TABLE test(id INTEGER UNIQUE)");
|
||||||
@@ -168,7 +187,7 @@ TEST_F(CreateTableSqlStatementBuilder, IfNotExitsModifier)
|
|||||||
{
|
{
|
||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
|
builder.addColumn("id", ColumnType::Integer, {});
|
||||||
|
|
||||||
builder.setUseIfNotExists(true);
|
builder.setUseIfNotExists(true);
|
||||||
|
|
||||||
@@ -180,7 +199,7 @@ TEST_F(CreateTableSqlStatementBuilder, TemporaryTable)
|
|||||||
{
|
{
|
||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::NoConstraint);
|
builder.addColumn("id", ColumnType::Integer, {});
|
||||||
|
|
||||||
builder.setUseTemporaryTable(true);
|
builder.setUseTemporaryTable(true);
|
||||||
|
|
||||||
@@ -188,31 +207,12 @@ TEST_F(CreateTableSqlStatementBuilder, TemporaryTable)
|
|||||||
"CREATE TEMPORARY TABLE test(id INTEGER)");
|
"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)
|
TEST_F(CreateTableSqlStatementBuilder, ForeignKeyWithoutColumn)
|
||||||
{
|
{
|
||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
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)");
|
ASSERT_THAT(builder.sqlStatement(), "CREATE TABLE test(id INTEGER REFERENCES otherTable)");
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyWithColumn)
|
|||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
|
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
|
builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
||||||
@@ -233,7 +233,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateNoAction)
|
|||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
|
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
|
builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
||||||
@@ -246,8 +246,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateRestrict)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::Restrict}});
|
||||||
{"otherTable", "otherColumn", ForeignKeyAction::Restrict});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -261,8 +260,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateSetNull)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::SetNull}});
|
||||||
{"otherTable", "otherColumn", ForeignKeyAction::SetNull});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -276,8 +274,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateSetDefault)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::SetDefault}});
|
||||||
{"otherTable", "otherColumn", ForeignKeyAction::SetDefault});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -291,8 +288,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyUpdateCascade)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", ForeignKeyAction::Cascade}});
|
||||||
{"otherTable", "otherColumn", ForeignKeyAction::Cascade});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -304,7 +300,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteNoAction)
|
|||||||
builder.clear();
|
builder.clear();
|
||||||
builder.setTableName("test");
|
builder.setTableName("test");
|
||||||
|
|
||||||
builder.addColumn("id", ColumnType::Integer, Contraint::ForeignKey, {"otherTable", "otherColumn"});
|
builder.addColumn("id", ColumnType::Integer, {ForeignKey{"otherTable", "otherColumn"}});
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn))");
|
||||||
@@ -317,8 +313,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteRestrict)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::Restrict}});
|
||||||
{"otherTable", "otherColumn", {}, ForeignKeyAction::Restrict});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -332,8 +327,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteSetNull)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::SetNull}});
|
||||||
{"otherTable", "otherColumn", {}, ForeignKeyAction::SetNull});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -347,8 +341,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteSetDefault)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::SetDefault}});
|
||||||
{"otherTable", "otherColumn", {}, ForeignKeyAction::SetDefault});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -362,8 +355,7 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteCascade)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable", "otherColumn", {}, ForeignKeyAction::Cascade}});
|
||||||
{"otherTable", "otherColumn", {}, ForeignKeyAction::Cascade});
|
|
||||||
|
|
||||||
ASSERT_THAT(
|
ASSERT_THAT(
|
||||||
builder.sqlStatement(),
|
builder.sqlStatement(),
|
||||||
@@ -377,11 +369,10 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeleteAndUpdateAction)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable",
|
||||||
{"otherTable",
|
"otherColumn",
|
||||||
"otherColumn",
|
ForeignKeyAction::SetDefault,
|
||||||
ForeignKeyAction::SetDefault,
|
ForeignKeyAction::Cascade}});
|
||||||
ForeignKeyAction::Cascade});
|
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
|
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
|
||||||
@@ -395,15 +386,118 @@ TEST_F(CreateTableSqlStatementBuilder, ForeignKeyDeferred)
|
|||||||
|
|
||||||
builder.addColumn("id",
|
builder.addColumn("id",
|
||||||
ColumnType::Integer,
|
ColumnType::Integer,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"otherTable",
|
||||||
{"otherTable",
|
"otherColumn",
|
||||||
"otherColumn",
|
ForeignKeyAction::SetDefault,
|
||||||
ForeignKeyAction::SetDefault,
|
ForeignKeyAction::Cascade,
|
||||||
ForeignKeyAction::Cascade,
|
Enforment::Deferred}});
|
||||||
Enforment::Deferred});
|
|
||||||
|
|
||||||
ASSERT_THAT(builder.sqlStatement(),
|
ASSERT_THAT(builder.sqlStatement(),
|
||||||
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
|
"CREATE TABLE test(id INTEGER REFERENCES otherTable(otherColumn) ON UPDATE SET "
|
||||||
"DEFAULT ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)");
|
"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
|
} // namespace
|
||||||
|
|||||||
@@ -37,21 +37,27 @@ using testing::AnyOf;
|
|||||||
using testing::Assign;
|
using testing::Assign;
|
||||||
using testing::ByMove;
|
using testing::ByMove;
|
||||||
using testing::ByRef;
|
using testing::ByRef;
|
||||||
using testing::Contains;
|
|
||||||
using testing::ContainerEq;
|
using testing::ContainerEq;
|
||||||
|
using testing::Contains;
|
||||||
using testing::ElementsAre;
|
using testing::ElementsAre;
|
||||||
|
using testing::Eq;
|
||||||
using testing::Field;
|
using testing::Field;
|
||||||
|
using testing::Ge;
|
||||||
|
using testing::Gt;
|
||||||
using testing::HasSubstr;
|
using testing::HasSubstr;
|
||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
using testing::Invoke;
|
using testing::Invoke;
|
||||||
using testing::IsEmpty;
|
using testing::IsEmpty;
|
||||||
using testing::IsNull;
|
using testing::IsNull;
|
||||||
|
using testing::Le;
|
||||||
|
using testing::Lt;
|
||||||
using testing::Matcher;
|
using testing::Matcher;
|
||||||
using testing::Mock;
|
using testing::Mock;
|
||||||
using testing::MockFunction;
|
using testing::MockFunction;
|
||||||
|
using testing::Ne;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
using testing::NotNull;
|
|
||||||
using testing::Not;
|
using testing::Not;
|
||||||
|
using testing::NotNull;
|
||||||
using testing::Pair;
|
using testing::Pair;
|
||||||
using testing::PrintToString;
|
using testing::PrintToString;
|
||||||
using testing::Property;
|
using testing::Property;
|
||||||
@@ -64,10 +70,4 @@ using testing::StrEq;
|
|||||||
using testing::Throw;
|
using testing::Throw;
|
||||||
using testing::TypedEq;
|
using testing::TypedEq;
|
||||||
using testing::UnorderedElementsAre;
|
using testing::UnorderedElementsAre;
|
||||||
|
using testing::VariantWith;
|
||||||
using testing::Eq;
|
|
||||||
using testing::Ge;
|
|
||||||
using testing::Gt;
|
|
||||||
using testing::Le;
|
|
||||||
using testing::Lt;
|
|
||||||
using testing::Ne;
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using Sqlite::ColumnType;
|
using Sqlite::ColumnType;
|
||||||
using Sqlite::Contraint;
|
using Sqlite::ConstraintType;
|
||||||
using Sqlite::JournalMode;
|
using Sqlite::JournalMode;
|
||||||
using Sqlite::OpenMode;
|
using Sqlite::OpenMode;
|
||||||
using Column = Sqlite::Column;
|
using Column = Sqlite::Column;
|
||||||
@@ -51,13 +51,7 @@ TEST_F(SqliteColumn, DefaultConstruct)
|
|||||||
AllOf(Field(&Column::name, IsEmpty()),
|
AllOf(Field(&Column::name, IsEmpty()),
|
||||||
Field(&Column::tableName, IsEmpty()),
|
Field(&Column::tableName, IsEmpty()),
|
||||||
Field(&Column::type, ColumnType::Numeric),
|
Field(&Column::type, ColumnType::Numeric),
|
||||||
Field(&Column::constraint, Contraint::NoConstraint),
|
Field(&Column::constraints, IsEmpty())));
|
||||||
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)))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteColumn, Clear)
|
TEST_F(SqliteColumn, Clear)
|
||||||
@@ -65,11 +59,7 @@ TEST_F(SqliteColumn, Clear)
|
|||||||
column.name = "foo";
|
column.name = "foo";
|
||||||
column.name = "foo";
|
column.name = "foo";
|
||||||
column.type = ColumnType::Text;
|
column.type = ColumnType::Text;
|
||||||
column.constraint = Contraint::ForeignKey;
|
column.constraints = {Sqlite::PrimaryKey{}};
|
||||||
column.foreignKey.table = "bar";
|
|
||||||
column.foreignKey.column = "hmm";
|
|
||||||
column.foreignKey.updateAction = ForeignKeyAction::Cascade;
|
|
||||||
column.foreignKey.deleteAction = ForeignKeyAction::SetNull;
|
|
||||||
|
|
||||||
column.clear();
|
column.clear();
|
||||||
|
|
||||||
@@ -77,13 +67,7 @@ TEST_F(SqliteColumn, Clear)
|
|||||||
AllOf(Field(&Column::name, IsEmpty()),
|
AllOf(Field(&Column::name, IsEmpty()),
|
||||||
Field(&Column::tableName, IsEmpty()),
|
Field(&Column::tableName, IsEmpty()),
|
||||||
Field(&Column::type, ColumnType::Numeric),
|
Field(&Column::type, ColumnType::Numeric),
|
||||||
Field(&Column::constraint, Contraint::NoConstraint),
|
Field(&Column::constraints, IsEmpty())));
|
||||||
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)))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteColumn, Constructor)
|
TEST_F(SqliteColumn, Constructor)
|
||||||
@@ -91,24 +75,23 @@ TEST_F(SqliteColumn, Constructor)
|
|||||||
column = Sqlite::Column{"table",
|
column = Sqlite::Column{"table",
|
||||||
"column",
|
"column",
|
||||||
ColumnType::Text,
|
ColumnType::Text,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"referencedTable",
|
||||||
{"referencedTable",
|
"referencedColumn",
|
||||||
"referencedColumn",
|
ForeignKeyAction::SetNull,
|
||||||
ForeignKeyAction::SetNull,
|
ForeignKeyAction::Cascade,
|
||||||
ForeignKeyAction::Cascade,
|
Enforment::Deferred}}};
|
||||||
Enforment::Deferred}};
|
|
||||||
|
|
||||||
ASSERT_THAT(column,
|
ASSERT_THAT(column,
|
||||||
AllOf(Field(&Column::name, Eq("column")),
|
AllOf(Field(&Column::name, Eq("column")),
|
||||||
Field(&Column::tableName, Eq("table")),
|
Field(&Column::tableName, Eq("table")),
|
||||||
Field(&Column::type, ColumnType::Text),
|
Field(&Column::type, ColumnType::Text),
|
||||||
Field(&Column::constraint, Contraint::ForeignKey),
|
Field(&Column::constraints,
|
||||||
Field(&Column::foreignKey,
|
ElementsAre(VariantWith<ForeignKey>(
|
||||||
AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
|
AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
|
||||||
Field(&ForeignKey::column, Eq("referencedColumn")),
|
Field(&ForeignKey::column, Eq("referencedColumn")),
|
||||||
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
||||||
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
||||||
Field(&ForeignKey::enforcement, Enforment::Deferred)))));
|
Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteColumn, FlatConstructor)
|
TEST_F(SqliteColumn, FlatConstructor)
|
||||||
@@ -116,24 +99,23 @@ TEST_F(SqliteColumn, FlatConstructor)
|
|||||||
column = Sqlite::Column{"table",
|
column = Sqlite::Column{"table",
|
||||||
"column",
|
"column",
|
||||||
ColumnType::Text,
|
ColumnType::Text,
|
||||||
Contraint::ForeignKey,
|
{ForeignKey{"referencedTable",
|
||||||
"referencedTable",
|
"referencedColumn",
|
||||||
"referencedColumn",
|
ForeignKeyAction::SetNull,
|
||||||
ForeignKeyAction::SetNull,
|
ForeignKeyAction::Cascade,
|
||||||
ForeignKeyAction::Cascade,
|
Enforment::Deferred}}};
|
||||||
Enforment::Deferred};
|
|
||||||
|
|
||||||
ASSERT_THAT(column,
|
ASSERT_THAT(column,
|
||||||
AllOf(Field(&Column::name, Eq("column")),
|
AllOf(Field(&Column::name, Eq("column")),
|
||||||
Field(&Column::tableName, Eq("table")),
|
Field(&Column::tableName, Eq("table")),
|
||||||
Field(&Column::type, ColumnType::Text),
|
Field(&Column::type, ColumnType::Text),
|
||||||
Field(&Column::constraint, Contraint::ForeignKey),
|
Field(&Column::constraints,
|
||||||
Field(&Column::foreignKey,
|
ElementsAre(VariantWith<ForeignKey>(
|
||||||
AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
|
AllOf(Field(&ForeignKey::table, Eq("referencedTable")),
|
||||||
Field(&ForeignKey::column, Eq("referencedColumn")),
|
Field(&ForeignKey::column, Eq("referencedColumn")),
|
||||||
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
||||||
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
||||||
Field(&ForeignKey::enforcement, Enforment::Deferred)))));
|
Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace {
|
|||||||
using Backend = Sqlite::DatabaseBackend;
|
using Backend = Sqlite::DatabaseBackend;
|
||||||
|
|
||||||
using Sqlite::ColumnType;
|
using Sqlite::ColumnType;
|
||||||
using Sqlite::Contraint;
|
using Sqlite::ConstraintType;
|
||||||
using Sqlite::JournalMode;
|
using Sqlite::JournalMode;
|
||||||
using Sqlite::OpenMode;
|
using Sqlite::OpenMode;
|
||||||
using Sqlite::TextEncoding;
|
using Sqlite::TextEncoding;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace {
|
|||||||
|
|
||||||
using Sqlite::Column;
|
using Sqlite::Column;
|
||||||
using Sqlite::ColumnType;
|
using Sqlite::ColumnType;
|
||||||
using Sqlite::Contraint;
|
using Sqlite::ConstraintType;
|
||||||
using Sqlite::Database;
|
using Sqlite::Database;
|
||||||
using Sqlite::Enforment;
|
using Sqlite::Enforment;
|
||||||
using Sqlite::ForeignKey;
|
using Sqlite::ForeignKey;
|
||||||
@@ -136,9 +136,7 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithColumnCalls)
|
|||||||
{
|
{
|
||||||
Sqlite::Table foreignTable;
|
Sqlite::Table foreignTable;
|
||||||
foreignTable.setName("foreignTable");
|
foreignTable.setName("foreignTable");
|
||||||
auto &foreignColumn = foreignTable.addColumn("foreignColumn",
|
auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text, {Sqlite::Unique{}});
|
||||||
ColumnType::Text,
|
|
||||||
Sqlite::Contraint::Unique);
|
|
||||||
table.setName(tableName);
|
table.setName(tableName);
|
||||||
table.addForeignKeyColumn("name",
|
table.addForeignKeyColumn("name",
|
||||||
foreignColumn,
|
foreignColumn,
|
||||||
@@ -159,19 +157,14 @@ TEST_F(SqliteTable, AddColumn)
|
|||||||
{
|
{
|
||||||
table.setName(tableName);
|
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,
|
ASSERT_THAT(column,
|
||||||
AllOf(Field(&Column::name, Eq("name")),
|
AllOf(Field(&Column::name, Eq("name")),
|
||||||
Field(&Column::tableName, Eq(tableName)),
|
Field(&Column::tableName, Eq(tableName)),
|
||||||
Field(&Column::type, ColumnType::Text),
|
Field(&Column::type, ColumnType::Text),
|
||||||
Field(&Column::constraint, Contraint::Unique),
|
Field(&Column::constraints,
|
||||||
Field(&Column::foreignKey,
|
ElementsAre(VariantWith<Sqlite::Unique>(Eq(Sqlite::Unique{}))))));
|
||||||
AllOf(Field(&ForeignKey::table, IsEmpty()),
|
|
||||||
Field(&ForeignKey::column, IsEmpty()),
|
|
||||||
Field(&ForeignKey::updateAction, ForeignKeyAction::NoAction),
|
|
||||||
Field(&ForeignKey::deleteAction, ForeignKeyAction::NoAction),
|
|
||||||
Field(&ForeignKey::enforcement, Enforment::Immediate)))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteTable, AddForeignKeyColumnWithTable)
|
TEST_F(SqliteTable, AddForeignKeyColumnWithTable)
|
||||||
@@ -191,22 +184,20 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithTable)
|
|||||||
AllOf(Field(&Column::name, Eq("name")),
|
AllOf(Field(&Column::name, Eq("name")),
|
||||||
Field(&Column::tableName, Eq(tableName)),
|
Field(&Column::tableName, Eq(tableName)),
|
||||||
Field(&Column::type, ColumnType::Integer),
|
Field(&Column::type, ColumnType::Integer),
|
||||||
Field(&Column::constraint, Contraint::ForeignKey),
|
Field(&Column::constraints,
|
||||||
Field(&Column::foreignKey,
|
ElementsAre(VariantWith<ForeignKey>(
|
||||||
AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
|
AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
|
||||||
Field(&ForeignKey::column, IsEmpty()),
|
Field(&ForeignKey::column, IsEmpty()),
|
||||||
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
||||||
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
||||||
Field(&ForeignKey::enforcement, Enforment::Deferred)))));
|
Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteTable, AddForeignKeyColumnWithColumn)
|
TEST_F(SqliteTable, AddForeignKeyColumnWithColumn)
|
||||||
{
|
{
|
||||||
Sqlite::Table foreignTable;
|
Sqlite::Table foreignTable;
|
||||||
foreignTable.setName("foreignTable");
|
foreignTable.setName("foreignTable");
|
||||||
auto &foreignColumn = foreignTable.addColumn("foreignColumn",
|
auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text, {Sqlite::Unique{}});
|
||||||
ColumnType::Text,
|
|
||||||
Sqlite::Contraint::Unique);
|
|
||||||
table.setName(tableName);
|
table.setName(tableName);
|
||||||
|
|
||||||
auto &column = table.addForeignKeyColumn("name",
|
auto &column = table.addForeignKeyColumn("name",
|
||||||
@@ -219,22 +210,20 @@ TEST_F(SqliteTable, AddForeignKeyColumnWithColumn)
|
|||||||
AllOf(Field(&Column::name, Eq("name")),
|
AllOf(Field(&Column::name, Eq("name")),
|
||||||
Field(&Column::tableName, Eq(tableName)),
|
Field(&Column::tableName, Eq(tableName)),
|
||||||
Field(&Column::type, ColumnType::Text),
|
Field(&Column::type, ColumnType::Text),
|
||||||
Field(&Column::constraint, Contraint::ForeignKey),
|
Field(&Column::constraints,
|
||||||
Field(&Column::foreignKey,
|
ElementsAre(VariantWith<ForeignKey>(
|
||||||
AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
|
AllOf(Field(&ForeignKey::table, Eq("foreignTable")),
|
||||||
Field(&ForeignKey::column, Eq("foreignColumn")),
|
Field(&ForeignKey::column, Eq("foreignColumn")),
|
||||||
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
Field(&ForeignKey::updateAction, ForeignKeyAction::SetNull),
|
||||||
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
Field(&ForeignKey::deleteAction, ForeignKeyAction::Cascade),
|
||||||
Field(&ForeignKey::enforcement, Enforment::Deferred)))));
|
Field(&ForeignKey::enforcement, Enforment::Deferred)))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteTable, AddForeignKeyWhichIsNotUniqueThrowsAnExceptions)
|
TEST_F(SqliteTable, AddForeignKeyWhichIsNotUniqueThrowsAnExceptions)
|
||||||
{
|
{
|
||||||
Sqlite::Table foreignTable;
|
Sqlite::Table foreignTable;
|
||||||
foreignTable.setName("foreignTable");
|
foreignTable.setName("foreignTable");
|
||||||
auto &foreignColumn = foreignTable.addColumn("foreignColumn",
|
auto &foreignColumn = foreignTable.addColumn("foreignColumn", ColumnType::Text);
|
||||||
ColumnType::Text,
|
|
||||||
Sqlite::Contraint::NoConstraint);
|
|
||||||
table.setName(tableName);
|
table.setName(tableName);
|
||||||
|
|
||||||
ASSERT_THROW(table.addForeignKeyColumn("name",
|
ASSERT_THROW(table.addForeignKeyColumn("name",
|
||||||
@@ -245,4 +234,62 @@ TEST_F(SqliteTable, AddForeignKeyWhichIsNotUniqueThrowsAnExceptions)
|
|||||||
Sqlite::ForeignKeyColumnIsNotUnique);
|
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
|
} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user