#pragma once #include #include #include namespace cpphibernate { namespace mariadb { /* order_by_builder */ template 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; using is_order_by_type = is_order_by_modifier; hana::eval_if( is_order_by_type { }, [&](auto _){ hana::for_each(_(modifier).order_directions, [&](auto& dir){ using order_direction_type = mp::decay_t; using is_ascencing_type = is_ascending; 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 inline decltype(auto) build_order_by(const schema_t& schema, const T_modifiers& modifiers) { static order_by_builder builder; return builder.assign(schema, modifiers); } } }