column generator progress

This commit is contained in:
2025-11-12 22:18:56 +01:00
parent 1c5b2b21b0
commit 0d08ad4179
9 changed files with 202 additions and 65 deletions
+78 -46
View File
@@ -22,13 +22,18 @@ enum class column_generator_options {
ForceLazy = 1 << 1
};
template<typename EnumType>
class enum_flags {
public:
explicit enum_flags(EnumType value) : value_(value) {}
private:
EnumType value_;
};
// template<typename EnumType>
// class enum_flags {
// public:
// explicit enum_flags(EnumType value) : value_(value) {}
//
// operator EnumType() const { return value_; }
//
// enum_flags operator|=(EnumType other) { value_ |= other; return *this; }
// enum_flags operator&=(EnumType other) { value_ |= other; return *this; })
// private:
// EnumType value_;
// };
inline column_generator_options operator|(column_generator_options a, column_generator_options b) { return static_cast<column_generator_options>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b)); }
inline column_generator_options operator&(column_generator_options a, column_generator_options b) { return static_cast<column_generator_options>(static_cast<unsigned int>(a) & static_cast<unsigned int>(b)); }
@@ -187,7 +192,7 @@ public:
result_.emplace_back(utils::_);
}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
@@ -196,53 +201,74 @@ public:
private:
std::vector<utils::placeholder> result_;
};
enum class column_value_generator_options {
None = 0,
ValuesAsPlaceHolder = 1 << 0
};
inline column_value_generator_options operator|(column_value_generator_options a, column_value_generator_options b) { return static_cast<column_value_generator_options>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b)); }
inline column_value_generator_options operator&(column_value_generator_options a, column_value_generator_options b) { return static_cast<column_value_generator_options>(static_cast<unsigned int>(a) & static_cast<unsigned int>(b)); }
inline column_value_generator_options& operator|= (column_value_generator_options& a, column_value_generator_options b) { return reinterpret_cast<column_value_generator_options&>(reinterpret_cast<int&>(a) |= static_cast<int>(b)); }
inline column_value_generator_options& operator&= (column_value_generator_options& a, column_value_generator_options b) { return reinterpret_cast<column_value_generator_options&>(reinterpret_cast<int&>(a) &= static_cast<int>(b)); }
inline bool is_column_value_generator_option_set(const column_value_generator_options source, const column_value_generator_options needle) { return static_cast<int>(source & needle) > 0; }
class column_value_generator final {
public:
template< class Type >
std::vector<internal::column_value_pair> generate() {
Type obj;
return generate(obj);
}
explicit column_value_generator(column_value_generator_options options = column_value_generator_options::None);
template< class Type >
std::vector<internal::column_value_pair> generate() {
Type obj;
return generate(obj);
}
template< class Type >
std::vector<internal::column_value_pair> generate(const Type &obj) {
result_.clear();
access::process(*this, obj);
template< class Type >
std::vector<internal::column_value_pair> generate(const Type &obj) {
result_.clear();
access::process(*this, obj);
return result_;
}
return result_;
}
template < class V >
void on_primary_key(const char *id, V &x, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
result_.emplace_back(id, x);
}
void on_revision(const char *id, uint64_t &/*rev*/);
template < class V >
void on_primary_key(const char *id, V &x, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
push_back(id, x);
}
void on_revision(const char *id, uint64_t &/*rev*/);
template<typename Type>
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
result_.emplace_back(id, x);
}
template<typename Type>
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
push_back(id, x);
}
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
result_.emplace_back(id, fk_value_extractor_.extract(*x));
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
push_back(id, fk_value_extractor_.extract(*x));
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
push_back(id, fk_value_extractor_.extract(*x));
}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
template<typename Type>
void push_back(const char* id, const Type& value) {
if (is_column_value_generator_option_set(options_, column_value_generator_options::ValuesAsPlaceHolder)) {
result_.emplace_back(id, utils::_);
} else {
result_.emplace_back(id, value);
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
result_.emplace_back(id, fk_value_extractor_.extract(*x));
}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
}
private:
detail::fk_value_extractor fk_value_extractor_{};
std::vector<internal::column_value_pair> result_;
detail::fk_value_extractor fk_value_extractor_{};
std::vector<internal::column_value_pair> result_;
column_value_generator_options options_{column_value_generator_options::None};
};
template<typename Type>
@@ -258,11 +284,17 @@ std::vector<utils::placeholder> placeholders(const Type &obj) {
}
template<typename Type>
std::vector<internal::column_value_pair> column_value_pairs(const Type &obj) {
column_value_generator generator;
std::vector<internal::column_value_pair> column_value_pairs(const Type &obj, const column_value_generator_options options = column_value_generator_options::None) {
column_value_generator generator(options);
return generator.generate(obj);
}
template<typename Type>
std::vector<internal::column_value_pair> column_value_pairs() {
Type obj;
return column_value_pairs(obj, column_value_generator_options::ValuesAsPlaceHolder);
}
template<typename Type>
std::vector<sql::column> columns(const object::repository &repo,
const std::string &table_name = "",
@@ -19,11 +19,6 @@ public:
executable_query values(std::vector<utils::placeholder> &&values);
executable_query values(std::vector<utils::database_type> &&values);
template<class Type>
executable_query values() {
Type obj;
return values(obj);
}
template<class Type>
executable_query values(const Type &obj) {
return values(value_extractor::extract(obj));
}
@@ -18,11 +18,6 @@ public:
query_set_intermediate set(std::initializer_list<internal::column_value_pair> columns);
query_set_intermediate set(std::vector<internal::column_value_pair> &&columns);
template<class Type>
query_set_intermediate set() {
Type obj;
return set(obj);
}
template<class Type>
query_set_intermediate set(const Type &obj) {
return set(key_value_generator::generate(obj));
}