constraint progress

This commit is contained in:
Sascha Kühl 2025-12-14 20:50:00 +01:00
parent 348f3a16d0
commit 9418f28348
14 changed files with 158 additions and 49 deletions

View File

@ -11,9 +11,11 @@ namespace matador::query {
class constraint { class constraint {
public: public:
constraint() = default; constraint() = default;
constraint(std::string column_name, utils::constraints type, std::string referenced_table, std::string referenced_column); constraint(std::string column_name, std::string table_name, utils::constraints type);
constraint(std::string column_name, std::string table_name, utils::constraints type, std::string referenced_table, std::string referenced_column);
[[nodiscard]] std::string column_name() const; [[nodiscard]] std::string column_name() const;
[[nodiscard]] std::string table_name() const;
[[nodiscard]] const utils::constraints& type() const; [[nodiscard]] const utils::constraints& type() const;
[[nodiscard]] bool is_primary_key_constraint() const; [[nodiscard]] bool is_primary_key_constraint() const;
[[nodiscard]] bool is_foreign_key_constraint() const; [[nodiscard]] bool is_foreign_key_constraint() const;
@ -23,6 +25,7 @@ public:
private: private:
std::string column_name_; std::string column_name_;
std::string table_name_;
utils::constraints type_{}; utils::constraints type_{};
std::string referenced_table_; std::string referenced_table_;
std::string referenced_column_; std::string referenced_column_;

View File

@ -1,9 +1,11 @@
#ifndef MATADOR_QUERY_ALTER_TABLE_INTERMEDIATE_HPP #ifndef MATADOR_QUERY_ALTER_TABLE_INTERMEDIATE_HPP
#define MATADOR_QUERY_ALTER_TABLE_INTERMEDIATE_HPP #define MATADOR_QUERY_ALTER_TABLE_INTERMEDIATE_HPP
#include "executable_query.hpp" #include "matador/query/intermediates/executable_query.hpp"
#include "matador/object/restriction.hpp"
#include "matador/query/intermediates/query_intermediate.hpp" #include "matador/query/intermediates/query_intermediate.hpp"
#include "matador/query/constraint.hpp"
#include "matador/object/restriction.hpp"
namespace matador::query { namespace matador::query {
class query_add_primary_key_constraint_intermediate final : public executable_query { class query_add_primary_key_constraint_intermediate final : public executable_query {
@ -35,7 +37,9 @@ class query_alter_table_intermediate final : public query_intermediate {
public: public:
using query_intermediate::query_intermediate; using query_intermediate::query_intermediate;
executable_query add_constraint(const object::restriction& rest);
query_add_key_constraint_intermediate add_constraint(const std::string& name); query_add_key_constraint_intermediate add_constraint(const std::string& name);
executable_query drop_constraint(const object::restriction& rest);
executable_query drop_constraint(const std::string& name); executable_query drop_constraint(const std::string& name);
}; };
} }

View File

@ -15,6 +15,8 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include "matador/object/restriction.hpp"
namespace matador::query::internal { namespace matador::query::internal {
class query_alter_part final : public query_part { class query_alter_part final : public query_part {
@ -46,9 +48,19 @@ private:
std::string name_; std::string name_;
}; };
class query_drop_key_constraint_part final : public query_part { class query_add_constraint_part_by_constraint final : public query_part {
public: public:
explicit query_drop_key_constraint_part(std::string name); explicit query_add_constraint_part_by_constraint(const constraint& co);
void accept(query_part_visitor &visitor) override;
[[nodiscard]] const class constraint& constraint() const;
private:
class constraint constraint_;
};
class query_drop_key_constraint_part_by_name final : public query_part {
public:
explicit query_drop_key_constraint_part_by_name(std::string name);
void accept(query_part_visitor &visitor) override; void accept(query_part_visitor &visitor) override;
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
@ -56,6 +68,16 @@ private:
std::string name_; std::string name_;
}; };
class query_drop_key_constraint_part_by_constraint final : public query_part {
public:
explicit query_drop_key_constraint_part_by_constraint(const constraint& co);
void accept(query_part_visitor &visitor) override;
[[nodiscard]] const class constraint& constraint() const;
private:
class constraint constraint_;
};
class query_add_foreign_key_constraint_part final : public query_part { class query_add_foreign_key_constraint_part final : public query_part {
public: public:
explicit query_add_foreign_key_constraint_part( const std::vector<column>& columns); explicit query_add_foreign_key_constraint_part( const std::vector<column>& columns);
@ -89,12 +111,6 @@ private:
std::vector<column> columns_; std::vector<column> columns_;
}; };
class query_drop_foreign_key_constraint_part final : public query_part {
public:
query_drop_foreign_key_constraint_part();
void accept(query_part_visitor &visitor) override;
};
/** /**
* Represents the SQL SELECT part * Represents the SQL SELECT part
*/ */

View File

@ -38,8 +38,9 @@ protected:
void visit(internal::query_add_foreign_key_constraint_part& part) override; void visit(internal::query_add_foreign_key_constraint_part& part) override;
void visit(internal::query_add_primary_key_constraint_part& part) override; void visit(internal::query_add_primary_key_constraint_part& part) override;
void visit(internal::query_add_foreign_key_reference_part& part) override; void visit(internal::query_add_foreign_key_reference_part& part) override;
void visit(internal::query_drop_key_constraint_part& part) override; void visit(internal::query_add_constraint_part_by_constraint &part) override;
void visit(internal::query_drop_foreign_key_constraint_part& part) override; void visit(internal::query_drop_key_constraint_part_by_name &part) override;
void visit(internal::query_drop_key_constraint_part_by_constraint &part) override;
protected: protected:
void visit(internal::query_select_part &part) override; void visit(internal::query_select_part &part) override;
@ -76,6 +77,10 @@ protected:
static std::string build_table_name(sql::dialect_token token, const sql::dialect &d, const table& t); static std::string build_table_name(sql::dialect_token token, const sql::dialect &d, const table& t);
static std::string determine_value(value_visitor &visitor, const std::variant<utils::placeholder, utils::database_type> &val); static std::string determine_value(value_visitor &visitor, const std::variant<utils::placeholder, utils::database_type> &val);
std::string build_add_constraint_string(const class constraint& c);
std::string build_drop_constraint_string(const class constraint& c);
std::string build_constraint_name(const class constraint& c);
protected: protected:
const query_data *data_{}; const query_data *data_{};
sql::query_context query_; sql::query_context query_;

View File

@ -7,9 +7,10 @@ namespace internal {
class query_alter_part; class query_alter_part;
class query_alter_table_part; class query_alter_table_part;
class query_add_key_constraint_part; class query_add_key_constraint_part;
class query_drop_key_constraint_part; class query_drop_key_constraint_part_by_name;
class query_drop_foreign_key_constraint_part; class query_drop_key_constraint_part_by_constraint;
class query_add_foreign_key_constraint_part; class query_add_foreign_key_constraint_part;
class query_add_constraint_part_by_constraint;
class query_add_foreign_key_reference_part; class query_add_foreign_key_reference_part;
class query_add_primary_key_constraint_part; class query_add_primary_key_constraint_part;
class query_select_part; class query_select_part;
@ -48,10 +49,11 @@ public:
virtual void visit(internal::query_alter_table_part &part) = 0; virtual void visit(internal::query_alter_table_part &part) = 0;
virtual void visit(internal::query_add_key_constraint_part &part) = 0; virtual void visit(internal::query_add_key_constraint_part &part) = 0;
virtual void visit(internal::query_add_foreign_key_constraint_part &part) = 0; virtual void visit(internal::query_add_foreign_key_constraint_part &part) = 0;
virtual void visit(internal::query_add_constraint_part_by_constraint &part) = 0;
virtual void visit(internal::query_add_primary_key_constraint_part &part) = 0; virtual void visit(internal::query_add_primary_key_constraint_part &part) = 0;
virtual void visit(internal::query_add_foreign_key_reference_part &part) = 0; virtual void visit(internal::query_add_foreign_key_reference_part &part) = 0;
virtual void visit(internal::query_drop_key_constraint_part &part) = 0; virtual void visit(internal::query_drop_key_constraint_part_by_name &part) = 0;
virtual void visit(internal::query_drop_foreign_key_constraint_part &part) = 0; virtual void visit(internal::query_drop_key_constraint_part_by_constraint &part) = 0;
virtual void visit(internal::query_select_part &part) = 0; virtual void visit(internal::query_select_part &part) = 0;
virtual void visit(internal::query_from_part &part) = 0; virtual void visit(internal::query_from_part &part) = 0;

View File

@ -171,6 +171,7 @@ public:
[[nodiscard]] const std::string& start_quote() const; [[nodiscard]] const std::string& start_quote() const;
[[nodiscard]] const std::string& string_quote() const; [[nodiscard]] const std::string& string_quote() const;
[[nodiscard]] const std::string& table() const; [[nodiscard]] const std::string& table() const;
[[nodiscard]] const std::string& unique() const;
[[nodiscard]] const std::string& update() const; [[nodiscard]] const std::string& update() const;
[[nodiscard]] const std::string& values() const; [[nodiscard]] const std::string& values() const;
[[nodiscard]] const std::string& where() const; [[nodiscard]] const std::string& where() const;
@ -237,6 +238,7 @@ private:
{dialect_token::StartQuote, "\""}, {dialect_token::StartQuote, "\""},
{dialect_token::StringQuote, "'"}, {dialect_token::StringQuote, "'"},
{dialect_token::Table, "TABLE"}, {dialect_token::Table, "TABLE"},
{dialect_token::Unique, "UNIQUE"},
{dialect_token::Update, "UPDATE"}, {dialect_token::Update, "UPDATE"},
{dialect_token::Values, "VALUES"}, {dialect_token::Values, "VALUES"},
{dialect_token::Where, "WHERE"} {dialect_token::Where, "WHERE"}

View File

@ -55,6 +55,7 @@ enum class dialect_token : uint8_t {
StartQuote, StartQuote,
StringQuote, StringQuote,
Table, Table,
Unique,
Update, Update,
Values, Values,
Where Where

View File

@ -110,7 +110,7 @@ utils::result<void, utils::error> schema::drop() const {
} }
auto ctx = query::query::alter() auto ctx = query::query::alter()
.table(node->name()) .table(node->name())
.drop_constraint("cons.name()") .drop_constraint(cons)
.compile(*c); .compile(*c);
std::cout << ctx.sql << std::endl; std::cout << ctx.sql << std::endl;
@ -128,7 +128,7 @@ utils::result<void, utils::error> schema::drop() const {
} }
auto ctx = query::query::alter() auto ctx = query::query::alter()
.table(node->name()) .table(node->name())
.drop_constraint("cons.name()") .drop_constraint(cons)
.compile(*c); .compile(*c);
std::cout << ctx.sql << std::endl; std::cout << ctx.sql << std::endl;
@ -185,16 +185,13 @@ sql::query_context schema::build_add_constraint_context( const object::repositor
if (cons.is_foreign_key_constraint()) { if (cons.is_foreign_key_constraint()) {
return query::query::alter() return query::query::alter()
.table(node.name()) .table(node.name())
.add_constraint("cons.name()") .add_constraint(cons)
.foreign_key(cons.column_name())
.references(cons.ref_table_name(), {cons.ref_column_name()})
.compile(*pool_.acquire()); .compile(*pool_.acquire());
} }
if (cons.is_primary_key_constraint()) { if (cons.is_primary_key_constraint()) {
return query::query::alter() return query::query::alter()
.table(node.name()) .table(node.name())
.add_constraint("cons.name()") .add_constraint(cons)
.primary_key(cons.column_name())
.compile(*pool_.acquire()); .compile(*pool_.acquire());
} }
return {}; return {};
@ -203,7 +200,7 @@ sql::query_context schema::build_add_constraint_context( const object::repositor
sql::query_context schema::build_drop_constraint_context( const object::repository_node& node, const class object::restriction& cons ) const { sql::query_context schema::build_drop_constraint_context( const object::repository_node& node, const class object::restriction& cons ) const {
return query::query::alter() return query::query::alter()
.table(node.name()) .table(node.name())
.drop_constraint("cons.name()") .drop_constraint(cons)
.compile(*pool_.acquire()); .compile(*pool_.acquire());
} }
} }

View File

@ -80,16 +80,13 @@ sql::query_context session::build_add_constraint_context(const std::string& tabl
if (cons.is_foreign_key_constraint()) { if (cons.is_foreign_key_constraint()) {
return query::query::alter() return query::query::alter()
.table(table_name) .table(table_name)
.add_constraint("cons.name()") .add_constraint(cons)
.foreign_key(cons.column_name())
.references(cons.ref_table_name(), {cons.ref_column_name()})
.compile(*conn); .compile(*conn);
} }
if (cons.is_primary_key_constraint()) { if (cons.is_primary_key_constraint()) {
return query::query::alter() return query::query::alter()
.table(table_name) .table(table_name)
.add_constraint("cons.name()") .add_constraint(cons)
.primary_key(cons.column_name())
.compile(*conn); .compile(*conn);
} }
return {}; return {};
@ -102,7 +99,7 @@ utils::result<void, utils::error> session::drop_schema() const {
for (const auto& cons : node->info().constraints()) { for (const auto& cons : node->info().constraints()) {
auto ctx = query::query::alter() auto ctx = query::query::alter()
.table(node->name()) .table(node->name())
.drop_constraint("cons.name()") .drop_constraint(cons)
.compile(*c); .compile(*c);
std::cout << ctx.sql << std::endl; std::cout << ctx.sql << std::endl;

View File

@ -3,8 +3,14 @@
#include "matador/utils/constraints.hpp" #include "matador/utils/constraints.hpp"
namespace matador::query { namespace matador::query {
constraint::constraint(std::string column_name, utils::constraints type, std::string referenced_table, std::string referenced_column) constraint::constraint(std::string column_name, std::string table_name, utils::constraints type)
: column_name_(std::move(column_name)) : column_name_(std::move(column_name))
, table_name_(std::move(table_name))
, type_(type) {}
constraint::constraint(std::string column_name, std::string table_name, utils::constraints type, std::string referenced_table, std::string referenced_column)
: column_name_(std::move(column_name))
, table_name_(std::move(table_name))
, type_(type) , type_(type)
, referenced_table_(std::move(referenced_table)) , referenced_table_(std::move(referenced_table))
, referenced_column_(std::move(referenced_column)) {} , referenced_column_(std::move(referenced_column)) {}
@ -13,6 +19,10 @@ std::string constraint::column_name() const {
return column_name_; return column_name_;
} }
std::string constraint::table_name() const {
return table_name_;
}
const utils::constraints& constraint::type() const { const utils::constraints& constraint::type() const {
return type_; return type_;
} }

View File

@ -1,5 +1,6 @@
#include "matador/query/intermediates/query_alter_table_intermediate.hpp" #include "matador/query/intermediates/query_alter_table_intermediate.hpp"
#include "matador/object/object.hpp"
#include "matador/query/internal/query_parts.hpp" #include "matador/query/internal/query_parts.hpp"
namespace matador::query { namespace matador::query {
@ -29,14 +30,29 @@ query_add_foreign_key_constraint_intermediate query_add_key_constraint_intermedi
return {context_}; return {context_};
} }
query_add_key_constraint_intermediate query_alter_table_intermediate::add_constraint( const std::string& name ) { executable_query query_alter_table_intermediate::add_constraint(const object::restriction &rest) {
context_->parts.push_back(std::make_unique<internal::query_add_constraint_part_by_constraint>(
constraint{rest.column_name(), rest.owner()->name(), rest.attribute().attributes().options(), rest.ref_table_name(), rest.ref_column_name()}
));
return {context_};
}
query_add_key_constraint_intermediate query_alter_table_intermediate::add_constraint(const std::string& name) {
context_->parts.push_back(std::make_unique<internal::query_add_key_constraint_part>(name)); context_->parts.push_back(std::make_unique<internal::query_add_key_constraint_part>(name));
return {context_}; return {context_};
} }
executable_query query_alter_table_intermediate::drop_constraint( const std::string& name ) { executable_query query_alter_table_intermediate::drop_constraint(const object::restriction &rest) {
context_->parts.push_back(std::make_unique<internal::query_drop_key_constraint_part>(name)); context_->parts.push_back(std::make_unique<internal::query_drop_key_constraint_part_by_constraint>(
constraint{rest.column_name(), rest.owner()->name(), rest.attribute().attributes().options(), rest.ref_table_name(), rest.ref_column_name()})
);
return {context_};
}
executable_query query_alter_table_intermediate::drop_constraint(const std::string& name) {
context_->parts.push_back(std::make_unique<internal::query_drop_key_constraint_part_by_name>(name));
return {context_}; return {context_};
} }
} }

View File

@ -34,25 +34,42 @@ const std::string& query_add_key_constraint_part::name() const {
return name_; return name_;
} }
query_drop_key_constraint_part::query_drop_key_constraint_part(std::string name) query_add_constraint_part_by_constraint::query_add_constraint_part_by_constraint(const query::constraint &co)
: query_part(sql::dialect_token::AddConstraint)
, constraint_(co) {}
void query_add_constraint_part_by_constraint::accept(query_part_visitor &visitor) {
visitor.visit(*this);
}
const class constraint & query_add_constraint_part_by_constraint::constraint() const {
return constraint_;
}
query_drop_key_constraint_part_by_name::query_drop_key_constraint_part_by_name(std::string name)
: query_part( sql::dialect_token::DropConstraint ) : query_part( sql::dialect_token::DropConstraint )
, name_(std::move( name )){} , name_(std::move( name )){}
void query_drop_key_constraint_part::accept( query_part_visitor& visitor ) { void query_drop_key_constraint_part_by_name::accept(query_part_visitor& visitor) {
visitor.visit(*this); visitor.visit(*this);
} }
const std::string& query_drop_key_constraint_part::name() const { const std::string& query_drop_key_constraint_part_by_name::name() const {
return name_; return name_;
} }
query_drop_foreign_key_constraint_part::query_drop_foreign_key_constraint_part() query_drop_key_constraint_part_by_constraint::query_drop_key_constraint_part_by_constraint(const class constraint &co)
: query_part( sql::dialect_token::DropConstraint ) {} : query_part( sql::dialect_token::DropConstraint )
, constraint_(co) {}
void query_drop_foreign_key_constraint_part::accept( query_part_visitor& visitor ) { void query_drop_key_constraint_part_by_constraint::accept(query_part_visitor& visitor) {
visitor.visit(*this); visitor.visit(*this);
} }
const class constraint& query_drop_key_constraint_part_by_constraint::constraint() const {
return constraint_;
}
query_add_foreign_key_constraint_part::query_add_foreign_key_constraint_part(const std::vector<column>& columns) query_add_foreign_key_constraint_part::query_add_foreign_key_constraint_part(const std::vector<column>& columns)
: query_part(sql::dialect_token::ForeignKey) : query_part(sql::dialect_token::ForeignKey)
, columns_(columns) {} , columns_(columns) {}

View File

@ -117,11 +117,15 @@ void query_compiler::visit(internal::query_add_foreign_key_reference_part& part)
query_.sql += ")"; query_.sql += ")";
} }
void query_compiler::visit(internal::query_drop_key_constraint_part& part) { void query_compiler::visit(internal::query_add_constraint_part_by_constraint &part) {
query_.sql += build_add_constraint_string(part.constraint());
}
void query_compiler::visit(internal::query_drop_key_constraint_part_by_name& part) {
query_.sql += " " + dialect_->token_at(part.token()) + " " + part.name(); query_.sql += " " + dialect_->token_at(part.token()) + " " + part.name();
} }
void query_compiler::visit(internal::query_drop_foreign_key_constraint_part& part) { void query_compiler::visit(internal::query_drop_key_constraint_part_by_constraint& part) {
} }
void query_compiler::visit(internal::query_select_part &part) { void query_compiler::visit(internal::query_select_part &part) {
@ -385,10 +389,13 @@ std::string build_create_column(const column &col, const sql::dialect &d) {
result.append("(" + std::to_string(col.attributes().size()) + ")"); result.append("(" + std::to_string(col.attributes().size()) + ")");
} }
if (!col.is_nullable()) { if (!col.is_nullable()) {
result.append(" NOT NULL"); result.append(" ").append(d.not_null());
} }
if (is_constraint_set(col.attributes().options(), utils::constraints::Unique)) { if (is_constraint_set(col.attributes().options(), utils::constraints::Unique)) {
result.append(" UNIQUE"); result.append(" ").append(d.unique());
}
if (is_constraint_set(col.attributes().options(), utils::constraints::PrimaryKey)) {
result.append(" ").append(d.primary_key());
} }
return result; return result;
@ -429,4 +436,32 @@ std::string query_compiler::build_table_name(const sql::dialect_token token, con
(t.alias().empty() ? "" : " " + d.prepare_identifier_string(t.alias())); (t.alias().empty() ? "" : " " + d.prepare_identifier_string(t.alias()));
} }
std::string query_compiler::build_add_constraint_string(const class constraint &c) {
std::string result = dialect_->add_constraint() + " " + build_constraint_name(c) + " ";
if (c.is_primary_key_constraint()) {
result.append(dialect_->primary_key()).append(" (").append(c.column_name()).append(")");
} else if (c.is_foreign_key_constraint()) {
result.append(dialect_->foreign_key()).append(" (").append(c.column_name()).append(") ").append(dialect_->references()).append(" ").append(c.referenced_table()).append(" (").append(c.referenced_column()).append(")");
} else if (c.is_unique_constraint()) {
result.append(dialect_->unique()).append(" (").append(c.column_name()).append(")");
}
return result;
}
std::string query_compiler::build_drop_constraint_string(const class constraint &c) {
}
std::string query_compiler::build_constraint_name(const class constraint &c) {
if (c.is_primary_key_constraint()) {
return "PK_" + c.table_name();
}
if (c.is_foreign_key_constraint()) {
return "FK_" + c.column_name() + "_" + c.table_name();
}
if (c.is_unique_constraint()) {
return "UK_" + c.column_name() + "_" + c.table_name();
}
return "";
}
} }

View File

@ -308,6 +308,10 @@ const std::string& dialect::table() const {
return token_at(dialect_token::Table); return token_at(dialect_token::Table);
} }
const std::string & dialect::unique() const {
return token_at(dialect_token::Unique);
}
const std::string& dialect::update() const { const std::string& dialect::update() const {
return token_at(dialect_token::Update); return token_at(dialect_token::Update);
} }