|
- #pragma once
-
- #include <cpphibernate/modifier/order_by.h>
- #include <cpphibernate/modifier/order_by/ascending.h>
- #include <cpphibernate/modifier/order_by/descending.h>
-
- namespace cpphibernate {
- namespace mariadb {
-
- /* order_by_builder */
-
- template<typename T_modifiers>
- struct order_by_builder
- {
- private:
- struct build_t
- {
- const schema_t& schema;
- const T_modifiers& modifiers;
- std::ostringstream os;
-
- inline build_t(const schema_t& p_schema, const T_modifiers& p_modifiers)
- : schema (p_schema)
- , modifiers (p_modifiers)
- { }
-
- inline void build(::cppmariadb::statement& statement)
- {
- size_t index = 0;
- hana::for_each(modifiers, [&](auto& modifier){
- using modifier_type = mp::decay_t<decltype(modifier)>;
- using is_order_by_type = is_order_by_modifier<modifier_type>;
- hana::eval_if(
- is_order_by_type { },
- [&](auto _){
- hana::for_each(_(modifier).order_directions, [&](auto& dir){
- using order_direction_type = mp::decay_t<decltype(dir)>;
- using is_ascencing_type = is_ascending<order_direction_type>;
- if (index++ == 0) os << "ORDER_BY ";
- else os << ", ";
- auto& field = schema.field(get_type_id(dir.wrapped_field));
- os << "`"
- << field.table.name
- << "`.`"
- << field.name
- << "` "
- << (is_ascencing_type::value
- ? "ASC"
- : "DESC");
- });
- },
- []{ });
- });
- statement.assign(os.str());
- }
- };
-
- private:
- const schema_t* _schema { nullptr };
- ::cppmariadb::statement _statement;
-
- public:
- inline ::cppmariadb::statement& assign(const schema_t& schema, const T_modifiers& modifiers)
- {
- if (_schema != &schema)
- {
- build_t(schema, modifiers).build(_statement);
- _schema = &schema;
- }
- return _statement;
- }
- };
-
- template<typename T_modifiers>
- inline decltype(auto) build_order_by(const schema_t& schema, const T_modifiers& modifiers)
- {
- static order_by_builder<T_modifiers> builder;
- return builder.assign(schema, modifiers);
- }
-
- } }
|