#pragma once #include // std::enable_if, std::is_base_of, std::is_member_pointer, std::remove_const #include // std::index_sequence, std::make_index_sequence #include // std::string #include // std::stringstream #include // std::copy_n #include "functional/cxx_universal.h" // ::size_t #include "functional/cxx_type_traits_polyfill.h" #include "type_traits.h" #include "alias_traits.h" namespace sqlite_orm { namespace internal { /** * This is a common built-in class used for character based table aliases. * For convenience there exist public type aliases `alias_a`, `alias_b`, ... * The easiest way to create a table alias is using `"z"_alias.for_()`. */ template struct recordset_alias : alias_tag { using type = T; static std::string get() { return {A, X...}; } }; /** * Column expression with table alias attached like 'C.ID'. This is not a column alias */ template struct alias_column_t { using alias_type = T; using column_type = C; column_type column; }; /* * Encapsulates extracting the alias identifier of a non-alias. */ template struct alias_extractor { static std::string extract() { return {}; } static std::string as_alias() { return {}; } }; /* * Encapsulates extracting the alias identifier of an alias. * * `extract()` always returns the alias identifier. * `as_alias()` is used in contexts where a table is aliased. */ template struct alias_extractor> { static std::string extract() { std::stringstream ss; ss << A::get(); return ss.str(); } // for column and regular table aliases -> alias identifier template, A> = true> static std::string as_alias() { return alias_extractor::extract(); } }; /** * Used to store alias for expression */ template struct as_t { using alias_type = T; using expression_type = E; expression_type expression; }; /** * This is a common built-in class used for custom single-character column aliases. * For convenience there exist type aliases `colalias_a`, `colalias_b`, ... * The easiest way to create a column alias is using `"xyz"_col`. */ template struct column_alias : alias_tag { static std::string get() { return {A, X...}; } }; template struct alias_holder { using type = T; alias_holder() = default; }; } /** * @return column with table alias attached. Place it instead of a column statement in case you need to specify a * column with table alias prefix like 'a.column'. */ template, bool> = true> internal::alias_column_t alias_column(C c) { using aliased_type = internal::type_t; static_assert(std::is_same, aliased_type>::value, "Column must be from aliased table"); return {c}; } /** * Alias a column expression. */ template = true> internal::as_t as(E expression) { return {std::move(expression)}; } template = true> internal::alias_holder get() { return {}; } template using alias_a = internal::recordset_alias; template using alias_b = internal::recordset_alias; template using alias_c = internal::recordset_alias; template using alias_d = internal::recordset_alias; template using alias_e = internal::recordset_alias; template using alias_f = internal::recordset_alias; template using alias_g = internal::recordset_alias; template using alias_h = internal::recordset_alias; template using alias_i = internal::recordset_alias; template using alias_j = internal::recordset_alias; template using alias_k = internal::recordset_alias; template using alias_l = internal::recordset_alias; template using alias_m = internal::recordset_alias; template using alias_n = internal::recordset_alias; template using alias_o = internal::recordset_alias; template using alias_p = internal::recordset_alias; template using alias_q = internal::recordset_alias; template using alias_r = internal::recordset_alias; template using alias_s = internal::recordset_alias; template using alias_t = internal::recordset_alias; template using alias_u = internal::recordset_alias; template using alias_v = internal::recordset_alias; template using alias_w = internal::recordset_alias; template using alias_x = internal::recordset_alias; template using alias_y = internal::recordset_alias; template using alias_z = internal::recordset_alias; using colalias_a = internal::column_alias<'a'>; using colalias_b = internal::column_alias<'b'>; using colalias_c = internal::column_alias<'c'>; using colalias_d = internal::column_alias<'d'>; using colalias_e = internal::column_alias<'e'>; using colalias_f = internal::column_alias<'f'>; using colalias_g = internal::column_alias<'g'>; using colalias_h = internal::column_alias<'h'>; using colalias_i = internal::column_alias<'i'>; }