removed the value field from attribute_definition because it's a definition and should not hold a value.

This commit is contained in:
Sascha Kühl 2025-11-17 13:16:18 +01:00
parent d1731a7f15
commit 9ffcee1317
10 changed files with 53 additions and 105 deletions

View File

@ -102,7 +102,7 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_co
const auto type = oid2type(PQftype(res, i)); const auto type = oid2type(PQftype(res, i));
// const char *col_name = PQfname(res, i); // const char *col_name = PQfname(res, i);
// const auto size = PQfmod(res, i); // const auto size = PQfmod(res, i);
prototype.at(i).type(type); prototype.at(i).change_type(type);
} }
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), prototype)); return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), prototype));
@ -110,7 +110,7 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_co
std::string postgres_connection::generate_statement_name(const sql::query_context &query) { std::string postgres_connection::generate_statement_name(const sql::query_context &query) {
std::stringstream name; std::stringstream name;
name << query.table.name << "_" << query.command_name; name << query.table.name() << "_" << query.command_name;
auto result = postgres_connection::statement_name_map_.find(name.str()); auto result = postgres_connection::statement_name_map_.find(name.str());
if (result == postgres_connection::statement_name_map_.end()) { if (result == postgres_connection::statement_name_map_.end()) {

View File

@ -27,14 +27,14 @@ public:
attribute_definition() = default; attribute_definition() = default;
template<typename Type> template<typename Type>
explicit attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr) attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr)
: attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr) : attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr)
{} {}
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes& attr); attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes& attr);
template<typename Type> template<typename Type>
explicit attribute_definition(std::string name, const utils::field_attributes& attr) attribute_definition(std::string name, const utils::field_attributes& attr)
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr) : attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr)
{} {}
@ -48,15 +48,15 @@ public:
: attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt)
{} {}
attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0); attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, int index = 0);
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0); attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, int index = 0);
template<typename Type> template<typename Type>
attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt) attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt)
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt)
{} {}
attribute_definition(std::string name, utils::basic_type type, size_t index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt); attribute_definition(std::string name, utils::basic_type type, int index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt);
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
void name(const std::string& n); void name(const std::string& n);
@ -68,6 +68,11 @@ public:
[[nodiscard]] utils::field_attributes& attributes(); [[nodiscard]] utils::field_attributes& attributes();
[[nodiscard]] bool is_nullable() const; [[nodiscard]] bool is_nullable() const;
[[nodiscard]] utils::basic_type type() const; [[nodiscard]] utils::basic_type type() const;
void change_type(utils::basic_type type, const utils::field_attributes &attr = utils::null_attributes);
template < typename Type >
void change_type(const utils::field_attributes &attr = utils::null_attributes) {
type_ = utils::data_type_traits<Type>::type(attr.size());
}
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const; [[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
[[nodiscard]] bool is_foreign_reference() const; [[nodiscard]] bool is_foreign_reference() const;
@ -81,49 +86,12 @@ public:
[[nodiscard]] bool is_blob() const; [[nodiscard]] bool is_blob() const;
[[nodiscard]] bool is_null() const; [[nodiscard]] bool is_null() const;
void type(utils::basic_type type);
template< typename Type > template< typename Type >
[[nodiscard]] bool is_type_of() const { [[nodiscard]] bool is_type_of() const {
return std::holds_alternative<Type>(value_); return type() == utils::data_type_traits<Type>::type(attributes().size());
} }
[[nodiscard]] std::string str() const;
template<typename Type>
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
{
attributes_ = attr;
value_ = value;
}
void set(const std::string &value, const utils::field_attributes &attr)
{
value_ = value;
attributes_ = attr;
}
void set(const char *value, const utils::field_attributes &attr)
{
value_ = std::string(value);
attributes_ = attr;
}
template<class Type>
std::optional<Type> as() const
{
return value_.as<Type>();
}
friend std::ostream& operator<<(std::ostream &out, const attribute_definition &col);
private: private:
template<class Operator>
void process(Operator &op)
{
op.on_attribute(name_.c_str(), value_, attributes_);
}
using data_type_index = std::vector<utils::basic_type>; using data_type_index = std::vector<utils::basic_type>;
private: private:
@ -134,7 +102,9 @@ private:
int index_{-1}; int index_{-1};
utils::field_attributes attributes_; utils::field_attributes attributes_;
null_option null_option_{null_option::NOT_NULL}; null_option null_option_{null_option::NOT_NULL};
utils::value value_; utils::basic_type type_{utils::basic_type::type_null};
size_t size_{0};
std::shared_ptr<attribute_definition> reference_column_; std::shared_ptr<attribute_definition> reference_column_;
}; };

View File

@ -11,10 +11,7 @@ namespace matador::utils {
namespace detail { namespace detail {
template<typename Type> template<typename Type>
size_t determine_size(const Type &/*val*/) size_t determine_size(const Type &/*val*/) { return 0; }
{
return 0;
}
size_t determine_size(const std::string &val); size_t determine_size(const std::string &val);
size_t determine_size(const char *val); size_t determine_size(const char *val);
size_t determine_size(const blob &val); size_t determine_size(const blob &val);

View File

@ -22,42 +22,44 @@ attribute_definition::attribute_definition(std::string name,
, table_(std::move(table_name)) , table_(std::move(table_name))
, index_(0) , index_(0)
, attributes_(attr) , attributes_(attr)
, value_(type, attr.size()) { , type_(type){
} }
attribute_definition::attribute_definition(std::string name, const utils::basic_type type, attribute_definition::attribute_definition(std::string name,
const utils::field_attributes &attr, const null_option null_opt, const utils::basic_type type,
const size_t index) const utils::field_attributes &attr,
const null_option null_opt,
const int index)
: name_(std::move(name)) : name_(std::move(name))
, index_(index) , index_(index)
, attributes_(attr) , attributes_(attr)
, null_option_(null_opt) , null_option_(null_opt)
, value_(type, attr.size()) { , type_(type) {
} }
attribute_definition::attribute_definition(std::string name, attribute_definition::attribute_definition(std::string name,
std::string table_name, std::string table_name,
const utils::basic_type type, const utils::basic_type type,
const utils::field_attributes &attr, const null_option null_opt, const utils::field_attributes &attr, const null_option null_opt,
const size_t index) const int index)
: name_(std::move(name)) : name_(std::move(name))
, table_(std::move(table_name)) , table_(std::move(table_name))
, index_(index) , index_(index)
, attributes_(attr) , attributes_(attr)
, null_option_(null_opt) , null_option_(null_opt)
, value_(type, attr.size()) { , type_(type) {
} }
attribute_definition::attribute_definition(std::string name, attribute_definition::attribute_definition(std::string name,
const utils::basic_type type, const utils::basic_type type,
const size_t index, const int index,
const std::shared_ptr<attribute_definition> &ref_column, const std::shared_ptr<attribute_definition> &ref_column,
const utils::field_attributes &attr, const null_option null_opt) const utils::field_attributes &attr, const null_option null_opt)
: name_(std::move(name)) : name_(std::move(name))
, index_(index) , index_(index)
, attributes_(attr) , attributes_(attr)
, null_option_(null_opt) , null_option_(null_opt)
, value_(type, attr.size()) , type_(type)
, reference_column_(ref_column) { , reference_column_(ref_column) {
} }
@ -98,7 +100,12 @@ bool attribute_definition::is_nullable() const {
} }
utils::basic_type attribute_definition::type() const { utils::basic_type attribute_definition::type() const {
return value_.type(); return type_;
}
void attribute_definition::change_type(const utils::basic_type type, const utils::field_attributes& attr) {
attributes_ = attr;
type_ = type;
} }
std::shared_ptr<attribute_definition> attribute_definition::reference_column() const { std::shared_ptr<attribute_definition> attribute_definition::reference_column() const {
@ -110,52 +117,39 @@ bool attribute_definition::is_foreign_reference() const {
} }
bool attribute_definition::is_integer() const { bool attribute_definition::is_integer() const {
return value_.is_integer(); return type_ >= utils::basic_type::type_int8 && type_ <= utils::basic_type::type_uint64;
} }
bool attribute_definition::is_floating_point() const { bool attribute_definition::is_floating_point() const {
return value_.is_floating_point(); return type_ == utils::basic_type::type_float || type_ == utils::basic_type::type_double;
} }
bool attribute_definition::is_bool() const { bool attribute_definition::is_bool() const {
return value_.is_bool(); return type_ == utils::basic_type::type_bool;
} }
bool attribute_definition::is_string() const { bool attribute_definition::is_string() const {
return value_.is_string(); return type_ == utils::basic_type::type_text;
} }
bool attribute_definition::is_varchar() const { bool attribute_definition::is_varchar() const {
return value_.is_varchar(); return type_ == utils::basic_type::type_varchar;
} }
bool attribute_definition::is_date() const { bool attribute_definition::is_date() const {
return value_.is_date(); return type_ == utils::basic_type::type_date;
} }
bool attribute_definition::is_time() const { bool attribute_definition::is_time() const {
return value_.is_time(); return type_ == utils::basic_type::type_time;
} }
bool attribute_definition::is_blob() const { bool attribute_definition::is_blob() const {
return value_.is_blob(); return type_ == utils::basic_type::type_blob;
} }
bool attribute_definition::is_null() const { bool attribute_definition::is_null() const {
return value_.is_null(); return type_ == utils::basic_type::type_null;
}
void attribute_definition::type(const utils::basic_type type) {
value_.type(type);
}
std::string attribute_definition::str() const {
return value_.str();
}
std::ostream &operator<<(std::ostream &out, const attribute_definition &col) {
out << col.str();
return out;
} }
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr, attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,

View File

@ -112,7 +112,7 @@ std::shared_ptr<attribute_definition> repository_node::determine_reference_colum
tree.missing_references_.erase(it); tree.missing_references_.erase(it);
ref_column->name(pk_info.pk_column_name); ref_column->name(pk_info.pk_column_name);
ref_column->table_name(name); ref_column->table_name(name);
ref_column->type(pk_info.type); ref_column->change_type(pk_info.type);
ref_column->attributes() = utils::constraints::FOREIGN_KEY; ref_column->attributes() = utils::constraints::FOREIGN_KEY;
if (name.empty()) { if (name.empty()) {

View File

@ -7,18 +7,15 @@ namespace detail {
void initialize_by_basic_type(basic_type type, database_type &val); void initialize_by_basic_type(basic_type type, database_type &val);
size_t determine_size(const std::string &val) size_t determine_size(const std::string &val) {
{
return val.size(); return val.size();
} }
size_t determine_size(const char *val) size_t determine_size(const char *val) {
{
return strlen(val); return strlen(val);
} }
size_t determine_size(const blob &val) size_t determine_size(const blob &val) {
{
return val.size(); return val.size();
} }

View File

@ -101,7 +101,7 @@ utils::result<sql::query_result<sql::record>, utils::error> session::fetch_all(c
// adjust columns from given query // adjust columns from given query
for (auto &col: q.prototype) { for (auto &col: q.prototype) {
if (const auto rit = it->second.find(col.name()); rit != it->second.end()) { if (const auto rit = it->second.find(col.name()); rit != it->second.end()) {
const_cast<object::attribute_definition &>(col).type(rit->type()); const_cast<object::attribute_definition &>(col).change_type(rit->type());
} }
} }
auto res = fetch(q); auto res = fetch(q);

View File

@ -39,7 +39,7 @@ std::string handle_column(sql::query_context &ctx, const sql::dialect *d, const
ctx.column_aliases.insert({column_table->has_alias() ? column_table->alias() : column_table->name() + "." + col.column_name(), col.alias()}); ctx.column_aliases.insert({column_table->has_alias() ? column_table->alias() : column_table->name() + "." + col.column_name(), col.alias()});
if (col.is_function()) { if (col.is_function()) {
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.column_name()); ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.column_name());
ctx.prototype.back().type(utils::basic_type::type_int32); ctx.prototype.back().change_type(utils::basic_type::type_int32);
} else { } else {
ctx.prototype.emplace_back(col.column_name()); ctx.prototype.emplace_back(col.column_name());
} }

View File

@ -229,7 +229,7 @@ utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform
[&col](const auto &value) { return value.name() == col.name(); } [&col](const auto &value) { return value.name() == col.name(); }
); );
if (col.type() == utils::basic_type::type_null && rit != result->end()) { if (col.type() == utils::basic_type::type_null && rit != result->end()) {
const_cast<object::attribute_definition&>(col).type(rit->type()); const_cast<object::attribute_definition&>(col).change_type(rit->type());
} }
} }
} }

View File

@ -13,15 +13,11 @@ TEST_CASE("Test create empty column", "[column]") {
REQUIRE(c.type() == basic_type::type_null); REQUIRE(c.type() == basic_type::type_null);
REQUIRE(!c.reference_column()); REQUIRE(!c.reference_column());
c.set(std::string{"george"}, 255); c.change_type<std::string>(255);
REQUIRE(c.type() == basic_type::type_varchar); REQUIRE(c.type() == basic_type::type_varchar);
REQUIRE(c.as<std::string>() == "george");
c.set(7); c.change_type<int32_t>(7);
REQUIRE(c.type() == basic_type::type_int32); REQUIRE(c.type() == basic_type::type_int32);
REQUIRE(c.as<std::string>() == "7");
REQUIRE(c.as<int>() == 7);
REQUIRE(c.str() == "7");
} }
TEST_CASE("Test copy and move column", "[column]") { TEST_CASE("Test copy and move column", "[column]") {
@ -30,17 +26,15 @@ TEST_CASE("Test copy and move column", "[column]") {
basic_type::type_varchar, basic_type::type_varchar,
2, 2,
std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY), std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY),
constraints::FOREIGN_KEY, {255, constraints::FOREIGN_KEY},
null_option::NOT_NULL null_option::NOT_NULL
); );
c.set(std::string{"george"}, 255);
REQUIRE(c.name() == "name"); REQUIRE(c.name() == "name");
REQUIRE(c.index() == 2); REQUIRE(c.index() == 2);
REQUIRE(c.reference_column()); REQUIRE(c.reference_column());
REQUIRE(c.reference_column()->name() == "author"); REQUIRE(c.reference_column()->name() == "author");
REQUIRE(c.reference_column()->table_name() == "books"); REQUIRE(c.reference_column()->table_name() == "books");
REQUIRE(c.type() == basic_type::type_varchar); REQUIRE(c.type() == basic_type::type_varchar);
REQUIRE(c.as<std::string>() == "george");
REQUIRE(c.attributes().size() == 255); REQUIRE(c.attributes().size() == 255);
auto c2 = c; auto c2 = c;
@ -50,7 +44,6 @@ TEST_CASE("Test copy and move column", "[column]") {
REQUIRE(c2.reference_column()->name() == "author"); REQUIRE(c2.reference_column()->name() == "author");
REQUIRE(c2.reference_column()->table_name() == "books"); REQUIRE(c2.reference_column()->table_name() == "books");
REQUIRE(c2.type() == basic_type::type_varchar); REQUIRE(c2.type() == basic_type::type_varchar);
REQUIRE(c2.as<std::string>() == "george");
REQUIRE(c2.attributes().size() == 255); REQUIRE(c2.attributes().size() == 255);
auto c3 = std::move(c2); auto c3 = std::move(c2);
@ -60,13 +53,10 @@ TEST_CASE("Test copy and move column", "[column]") {
REQUIRE(c3.reference_column()->name() == "author"); REQUIRE(c3.reference_column()->name() == "author");
REQUIRE(c3.reference_column()->table_name() == "books"); REQUIRE(c3.reference_column()->table_name() == "books");
REQUIRE(c3.type() == basic_type::type_varchar); REQUIRE(c3.type() == basic_type::type_varchar);
REQUIRE(c3.as<std::string>() == "george");
REQUIRE(c3.attributes().size() == 255); REQUIRE(c3.attributes().size() == 255);
REQUIRE(c2.name().empty()); REQUIRE(c2.name().empty());
REQUIRE(c2.index() == 2); REQUIRE(c2.index() == 2);
REQUIRE(!c2.reference_column()); REQUIRE(!c2.reference_column());
REQUIRE(c2.type() == basic_type::type_null);
// REQUIRE(!c2.as<std::string>().has_value());
REQUIRE(c2.attributes().size() == 255); REQUIRE(c2.attributes().size() == 255);
} }