mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'feature/trivial-value-is-null' into develop
This commit is contained in:
commit
4a25f5bcb9
@ -28,6 +28,7 @@
|
||||
#define SQLPP_BOOLEAN_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
@ -98,6 +99,7 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
@ -133,15 +135,28 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
@ -189,7 +204,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e)
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -34,52 +34,52 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
template<bool... b>
|
||||
struct and_impl;
|
||||
struct all_impl;
|
||||
|
||||
template<>
|
||||
struct and_impl<>
|
||||
struct all_impl<>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<bool... Rest>
|
||||
struct and_impl<true, Rest...>
|
||||
struct all_impl<true, Rest...>
|
||||
{
|
||||
static constexpr bool value = and_impl<Rest...>::value;
|
||||
static constexpr bool value = all_impl<Rest...>::value;
|
||||
};
|
||||
|
||||
template<bool... Rest>
|
||||
struct and_impl<false, Rest...>
|
||||
struct all_impl<false, Rest...>
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
using and_t = and_impl<Predicate<T>::value...>;
|
||||
using all_t = all_impl<Predicate<T>::value...>;
|
||||
|
||||
template<bool... b>
|
||||
struct or_impl;
|
||||
struct any_impl;
|
||||
|
||||
template<>
|
||||
struct or_impl<>
|
||||
struct any_impl<>
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<bool... Rest>
|
||||
struct or_impl<false, Rest...>
|
||||
struct any_impl<false, Rest...>
|
||||
{
|
||||
static constexpr bool value = or_impl<Rest...>::value;
|
||||
static constexpr bool value = any_impl<Rest...>::value;
|
||||
};
|
||||
|
||||
template<bool... Rest>
|
||||
struct or_impl<true, Rest...>
|
||||
struct any_impl<true, Rest...>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
using or_t = or_impl<Predicate<T>::value...>;
|
||||
using any_t = any_impl<Predicate<T>::value...>;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,10 @@ namespace sqlpp
|
||||
{
|
||||
// some forward declarations and helpers
|
||||
template<typename... T>
|
||||
struct make_set;
|
||||
struct make_type_set;
|
||||
|
||||
template<typename E, typename SET>
|
||||
struct is_element_of;
|
||||
|
||||
// A type set
|
||||
template<typename... Elements>
|
||||
@ -47,118 +50,126 @@ namespace sqlpp
|
||||
using size = std::integral_constant<size_t, sizeof...(Elements)>;
|
||||
using _is_type_set = std::true_type;
|
||||
|
||||
static_assert(std::is_same<type_set, typename make_set<Elements...>::type>::value, "use make_set to construct a set");
|
||||
|
||||
template<typename T>
|
||||
struct count
|
||||
{
|
||||
template<typename E>
|
||||
using same = std::is_same<T, E>;
|
||||
static constexpr bool value = or_t<same, Elements...>::value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_superset_of
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_superset_of");
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct is_superset_of<type_set<T...>>
|
||||
{
|
||||
static constexpr bool value = and_t<count, T...>::value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct join
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for type_set::join");
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct join<type_set<T...>>
|
||||
{
|
||||
using type = typename make_set<Elements..., T...>::type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_subset_of
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_subset_of");
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct is_subset_of<type_set<T...>>
|
||||
{
|
||||
static constexpr bool value = type_set<T...>::template is_superset_of<type_set>::value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_disjunct_from
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_disjunct_from");
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct is_disjunct_from<type_set<T...>>
|
||||
{
|
||||
static constexpr bool value = not(or_t<type_set::count, T...>::value or or_t<type_set<T...>::template count, Elements...>::value);
|
||||
};
|
||||
static_assert(std::is_same<type_set, typename make_type_set<Elements...>::type>::value, "use make_type_set to construct a set");
|
||||
|
||||
template<typename T>
|
||||
struct insert
|
||||
{
|
||||
using type = typename std::conditional<count<T>::value,
|
||||
type_set,
|
||||
type_set<T, Elements...>>::type;
|
||||
using type = typename std::conditional<not is_element_of<T, type_set>::value,
|
||||
type_set<T, Elements...>,
|
||||
type_set>::type;
|
||||
};
|
||||
|
||||
template<template<typename A> class Predicate, typename T>
|
||||
struct insert_if
|
||||
{
|
||||
using type = typename std::conditional<Predicate<T>::value,
|
||||
using type = typename std::conditional<Predicate<T>::value and not is_element_of<T, type_set>::value,
|
||||
type_set<Elements..., T>,
|
||||
type_set>::type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<typename E, typename SET>
|
||||
struct is_element_of
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<E, SET>::value, "SET has to be a type set");
|
||||
};
|
||||
|
||||
template<typename E, typename... Elements>
|
||||
struct is_element_of<E, type_set<Elements...>>
|
||||
{
|
||||
template<typename X>
|
||||
using matchE = std::is_same<E, X>;
|
||||
static constexpr bool value = any_t<matchE, Elements...>::value;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
struct is_superset_of
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
|
||||
};
|
||||
|
||||
template<typename... LElements, typename... RElements>
|
||||
struct is_superset_of<type_set<LElements...>, type_set<RElements...>>
|
||||
{
|
||||
template<typename X>
|
||||
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
|
||||
static constexpr bool value = all_t<is_element_of_L, RElements...>::value;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
struct is_subset_of
|
||||
{
|
||||
static constexpr bool value = is_superset_of<R, L>::value;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
struct joined_set
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
|
||||
};
|
||||
|
||||
template<typename... LElements, typename... RElements>
|
||||
struct joined_set<type_set<LElements...>, type_set<RElements...>>
|
||||
{
|
||||
using type = typename make_type_set<LElements..., RElements...>::type;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
struct is_disjunct_from
|
||||
{
|
||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "invalid argument for is_disjunct_from");
|
||||
};
|
||||
|
||||
template<typename... LElements, typename... RElements>
|
||||
struct is_disjunct_from<type_set<LElements...>, type_set<RElements...>>
|
||||
{
|
||||
template<typename X>
|
||||
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
|
||||
template<typename X>
|
||||
using is_element_of_R = is_element_of<X, type_set<RElements...>>;
|
||||
static constexpr bool value =
|
||||
not(any_t<is_element_of_L, RElements...>::value or any_t<is_element_of_R, LElements...>::value);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct make_set<>
|
||||
struct make_type_set<>
|
||||
{
|
||||
using type = type_set<>;
|
||||
};
|
||||
|
||||
template<typename T, typename... Rest>
|
||||
struct make_set<T, Rest...>
|
||||
struct make_type_set<T, Rest...>
|
||||
{
|
||||
using type = typename make_set<Rest...>::type::template insert<T>::type;
|
||||
using type = typename make_type_set<Rest...>::type::template insert<T>::type;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
struct make_set_if;
|
||||
struct make_type_set_if;
|
||||
|
||||
template<template<typename> class Predicate>
|
||||
struct make_set_if<Predicate>
|
||||
struct make_type_set_if<Predicate>
|
||||
{
|
||||
using type = type_set<>;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename T, typename... Rest>
|
||||
struct make_set_if<Predicate, T, Rest...>
|
||||
struct make_type_set_if<Predicate, T, Rest...>
|
||||
{
|
||||
using type = typename make_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type;
|
||||
using type = typename make_type_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
struct make_set_if_not
|
||||
struct make_type_set_if_not
|
||||
{
|
||||
template<typename X>
|
||||
using InversePredicate = std::integral_constant<bool, not Predicate<X>::value>;
|
||||
using type = typename make_set_if<InversePredicate, T...>::type;
|
||||
using type = typename make_type_set_if<InversePredicate, T...>::type;
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
using has_duplicates = std::integral_constant<bool, make_set<T...>::type::size::value != sizeof...(T)>;
|
||||
using has_duplicates = std::integral_constant<bool, make_type_set<T...>::type::size::value != sizeof...(T)>;
|
||||
|
||||
template<typename... T>
|
||||
struct make_joined_set
|
||||
@ -172,20 +183,12 @@ namespace sqlpp
|
||||
using type = type_set<>;
|
||||
};
|
||||
|
||||
/*
|
||||
template<typename... E>
|
||||
struct make_joined_set<type_set<E...>>
|
||||
{
|
||||
using type = type_set<E...>;
|
||||
};
|
||||
*/
|
||||
|
||||
template<typename... E, typename... T>
|
||||
struct make_joined_set<type_set<E...>, T...>
|
||||
{
|
||||
using _rest = typename make_joined_set<T...>::type;
|
||||
|
||||
using type = typename type_set<E...>::template join<_rest>::type;
|
||||
using type = typename joined_set<type_set<E...>, _rest>::type;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_FLOATING_POINT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -98,6 +99,7 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
@ -135,15 +137,28 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
@ -237,7 +252,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e)
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace sqlpp
|
||||
>
|
||||
struct insert_t
|
||||
{
|
||||
static_assert(Table::_table_set::template is_superset_of<typename InsertValueList::_table_set>::value, "columns do not match the table they are to be inserted into");
|
||||
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename InsertValueList::_table_set>::value, "columns do not match the table they are to be inserted into");
|
||||
|
||||
using _database_t = Database;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_INTEGRAL_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -98,6 +99,7 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
@ -135,15 +137,28 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
@ -244,7 +259,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e)
|
||||
template<typename Db, bool NullIsTrivial>
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, NullIsTrivial>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ namespace sqlpp
|
||||
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
|
||||
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||
|
||||
static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical");
|
||||
static_assert(::sqlpp::detail::is_disjunct_from<typename Lhs::_table_set, typename Rhs::_table_set>::value, "joined tables must not be identical");
|
||||
|
||||
using _is_table = std::true_type;
|
||||
using _is_join = std::true_type;
|
||||
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
template<typename OnT>
|
||||
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
||||
|
@ -40,7 +40,7 @@ namespace sqlpp
|
||||
template<typename Unused, typename... Columns>
|
||||
struct multi_column_t
|
||||
{
|
||||
static_assert(detail::and_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
|
||||
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
|
||||
|
||||
multi_column_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
@ -72,7 +72,7 @@ namespace sqlpp
|
||||
template<typename AliasProvider, typename... Columns>
|
||||
struct multi_column_alias_t
|
||||
{
|
||||
static_assert(detail::and_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
|
||||
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
|
||||
|
@ -36,8 +36,6 @@ namespace sqlpp
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = no_value_t;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
|
@ -41,7 +41,7 @@ namespace sqlpp
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()");
|
||||
static_assert(detail::and_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
|
||||
static_assert(detail::all_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
|
||||
|
||||
template<typename E>
|
||||
void add(E expr)
|
||||
|
@ -32,15 +32,15 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename Select>
|
||||
template<typename Database, typename Select>
|
||||
struct prepared_select_t
|
||||
{
|
||||
using _result_row_t = typename Select::_result_row_t;
|
||||
using _result_row_t = typename Select::template _result_row_t<Database>;
|
||||
using _parameter_list_t = typename Select::_parameter_list_t;
|
||||
using _dynamic_names_t = typename Select::_dynamic_names_t;
|
||||
using _prepared_statement_t = typename Db::_prepared_statement_t;
|
||||
using _prepared_statement_t = typename Database::_prepared_statement_t;
|
||||
|
||||
auto _run(Db& db) const
|
||||
auto _run(Database& db) const
|
||||
-> result_t<decltype(db.run_prepared_select(*this)), _result_row_t>
|
||||
{
|
||||
return {db.run_prepared_select(*this), _dynamic_names};
|
||||
|
@ -41,13 +41,13 @@ namespace sqlpp
|
||||
template<size_t level, size_t index, typename... NamedExpr>
|
||||
struct result_row_impl;
|
||||
|
||||
template<size_t level, size_t index, typename NamedExpr, typename... Rest>
|
||||
struct result_row_impl<level, index, NamedExpr, Rest...>:
|
||||
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::_result_entry_t>,
|
||||
public result_row_impl<level, index + 1, Rest...>
|
||||
template<size_t level, size_t index, typename Db, typename NamedExpr, typename... Rest>
|
||||
struct result_row_impl<level, index, Db, NamedExpr, Rest...>:
|
||||
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>,
|
||||
public result_row_impl<level, index + 1, Db, Rest...>
|
||||
{
|
||||
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::_result_entry_t>;
|
||||
using _rest = result_row_impl<level, index + 1, Rest...>;
|
||||
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
|
||||
using _rest = result_row_impl<level, index + 1, Db, Rest...>;
|
||||
static constexpr size_t _last_index = _rest::_last_index;
|
||||
|
||||
result_row_impl() = default;
|
||||
@ -84,13 +84,13 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
||||
struct result_row_impl<level, index, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
||||
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
||||
template<size_t level, size_t index, typename AliasProvider, typename Db, typename... Col, typename... Rest>
|
||||
struct result_row_impl<level, index, Db, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Db, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
||||
public result_row_impl<level, index + sizeof...(Col), Db, Rest...>
|
||||
{
|
||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>;
|
||||
using _rest = result_row_impl<level, index + sizeof...(Col), Rest...>;
|
||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Db, Col...>>;
|
||||
using _rest = result_row_impl<level, index + sizeof...(Col), Db, Rest...>;
|
||||
static constexpr size_t _last_index = _rest::_last_index;
|
||||
|
||||
result_row_impl() = default;
|
||||
@ -126,8 +126,8 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t level, size_t index>
|
||||
struct result_row_impl<level, index>
|
||||
template<size_t level, size_t index, typename Db>
|
||||
struct result_row_impl<level, index, Db>
|
||||
{
|
||||
static constexpr size_t _last_index = index;
|
||||
result_row_impl() = default;
|
||||
@ -155,10 +155,10 @@ namespace sqlpp
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... NamedExpr>
|
||||
struct result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
||||
template<typename Db, typename... NamedExpr>
|
||||
struct result_row_t: public detail::result_row_impl<0, 0, Db, NamedExpr...>
|
||||
{
|
||||
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
||||
using _impl = detail::result_row_impl<0, 0, Db, NamedExpr...>;
|
||||
bool _is_valid;
|
||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||
|
||||
@ -221,11 +221,11 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... NamedExpr>
|
||||
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
||||
template<typename Db, typename... NamedExpr>
|
||||
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, Db, NamedExpr...>
|
||||
{
|
||||
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
||||
using _field_type = detail::text::_result_entry_t;
|
||||
using _impl = detail::result_row_impl<0, 0, Db, NamedExpr...>;
|
||||
using _field_type = detail::text::_result_entry_t<Db, false>;
|
||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||
|
||||
bool _is_valid;
|
||||
|
@ -58,8 +58,8 @@ namespace sqlpp
|
||||
>
|
||||
struct select_helper_t
|
||||
{
|
||||
static_assert(is_noop_t<ColumnList>::value or sqlpp::is_select_column_list_t<ColumnList>::value, "Yikes");
|
||||
static_assert(is_noop_t<From>::value or sqlpp::is_from_t<From>::value, "Yikes");
|
||||
static_assert(is_noop_t<ColumnList>::value or sqlpp::is_select_column_list_t<ColumnList>::value, "column list of select is neither naught nor a valid column list");
|
||||
static_assert(is_noop_t<From>::value or sqlpp::is_from_t<From>::value, "from() part of select is neither naught nor a valid from()");
|
||||
using _value_type = typename std::conditional<
|
||||
sqlpp::is_from_t<From>::value,
|
||||
typename ColumnList::_value_type,
|
||||
@ -99,7 +99,8 @@ namespace sqlpp
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
using _column_list_t = ColumnList;
|
||||
using _result_row_t = typename _column_list_t::_result_row_t;
|
||||
template<typename Db>
|
||||
using _result_row_t = typename _column_list_t::template _result_row_t<Db>;
|
||||
using _dynamic_names_t = typename _column_list_t::_dynamic_names_t;
|
||||
|
||||
using _is_select = std::true_type;
|
||||
@ -490,13 +491,19 @@ namespace sqlpp
|
||||
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return _result_row_t::static_size() + get_dynamic_names().size();
|
||||
return _column_list_t::static_size() + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
struct can_run_t
|
||||
{
|
||||
//static_assert(is_where_t<Where>::value, "cannot select remove without having a where condition, use .where(true) to remove all rows");
|
||||
/*
|
||||
static_assert(column_list::_table_set::template is_subset_t<_from_t::_table_set>::value
|
||||
static_assert(detail::is_subset_of<column_list::_table_set, _from_t::_table_set>::value
|
||||
subset_of_t sollte ein eigenes template sein, das macht so etwas wie obiges sicher einfacher lesbar
|
||||
also: use any and all instead of and_t and or_t
|
||||
*/
|
||||
//static_assert(is_where_t<Where>::value, "cannot select select without having a where condition, use .where(true) to remove all rows");
|
||||
//static_assert(not vendor::is_noop<ColumnList>::value, "cannot run select without having selected anything");
|
||||
//static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
//static_assert(is_where_t<Where>::value, "cannot run select without having a where condition, use .where(true) to select all rows");
|
||||
@ -509,7 +516,7 @@ namespace sqlpp
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(*this)), _result_row_t>
|
||||
-> result_t<decltype(db.select(*this)), _result_row_t<Db>>
|
||||
{
|
||||
static_assert(can_run_t<Db>::value, "Cannot execute select statement");
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
@ -38,6 +38,18 @@ namespace sqlpp
|
||||
return vendor::serializer_t<Context, T>::_(t, context);
|
||||
}
|
||||
|
||||
/*
|
||||
namespace vendor // Required if you want to call serialize(sqlpp::value(7), printer), for instance
|
||||
{
|
||||
template<typename T, typename Context>
|
||||
auto serialize(const T& t, Context& context)
|
||||
-> decltype(vendor::serializer_t<Context, T>::_(t, context))
|
||||
{
|
||||
return vendor::serializer_t<Context, T>::_(t, context);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -42,14 +42,20 @@ namespace sqlpp
|
||||
return _os << t;
|
||||
}
|
||||
|
||||
void flush()
|
||||
static std::string escape(std::string arg)
|
||||
{
|
||||
_os << std::endl;
|
||||
if (arg.find('\''))
|
||||
{
|
||||
std::string retVal;
|
||||
for (const auto c : arg)
|
||||
{
|
||||
if (c == '\'')
|
||||
retVal.push_back(c);
|
||||
retVal.push_back(c);
|
||||
}
|
||||
|
||||
std::string escape(std::string arg)
|
||||
{
|
||||
// FIXME: Need to do better escaping
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ namespace sqlpp
|
||||
{
|
||||
using _table_set = detail::type_set<Table>; // Hint need a type_set here to be similar to a join (which always represents more than one table)
|
||||
static_assert(sizeof...(ColumnSpec), "at least one column required per table");
|
||||
using _required_insert_columns = typename detail::make_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
|
||||
using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
|
||||
using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>;
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#ifndef SQLPP_TEXT_H
|
||||
#define SQLPP_TEXT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -97,6 +98,7 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
@ -135,15 +137,28 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _value_ptr == nullptr;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
if (_value_ptr)
|
||||
return std::string(_value_ptr, _value_ptr + _len);
|
||||
else
|
||||
@ -195,7 +210,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e)
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct tvin_wrap_t
|
||||
struct maybe_tvin_t
|
||||
{
|
||||
using _table_set = typename T::_table_set;
|
||||
static constexpr bool _is_trivial()
|
||||
@ -82,20 +82,20 @@ namespace sqlpp
|
||||
return false;
|
||||
}
|
||||
|
||||
tvin_wrap_t(T t):
|
||||
maybe_tvin_t(T t):
|
||||
_value(t)
|
||||
{}
|
||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
||||
~tvin_wrap_t() = default;
|
||||
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||
~maybe_tvin_t() = default;
|
||||
|
||||
T _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct tvin_wrap_t<tvin_t<T>>
|
||||
struct maybe_tvin_t<tvin_t<T>>
|
||||
{
|
||||
using _table_set = typename T::_table_set;
|
||||
bool _is_trivial() const
|
||||
@ -103,14 +103,14 @@ namespace sqlpp
|
||||
return _value._is_trivial();
|
||||
};
|
||||
|
||||
tvin_wrap_t(tvin_t<T> t):
|
||||
maybe_tvin_t(tvin_t<T> t):
|
||||
_value(t._value)
|
||||
{}
|
||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
||||
~tvin_wrap_t() = default;
|
||||
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||
~maybe_tvin_t() = default;
|
||||
|
||||
typename tvin_t<T>::_operand_t _value;
|
||||
};
|
||||
@ -118,9 +118,9 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, tvin_wrap_t<Operand>>
|
||||
struct serializer_t<Context, maybe_tvin_t<Operand>>
|
||||
{
|
||||
using T = tvin_wrap_t<Operand>;
|
||||
using T = maybe_tvin_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
@ -92,6 +92,7 @@ namespace sqlpp
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(trivial_value_is_null);
|
||||
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_noop);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
||||
@ -123,7 +124,8 @@ namespace sqlpp
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_parameter);
|
||||
|
||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(has_empty_list_insert);
|
||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(null_result_is_trivial_value);
|
||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(assert_result_validity);
|
||||
|
||||
template<typename T, template<typename> class IsTag>
|
||||
using copy_type_trait = typename std::conditional<IsTag<T>::value, std::true_type, std::false_type>::type;
|
||||
|
@ -57,8 +57,8 @@ namespace sqlpp
|
||||
typename Where = vendor::no_where_t>
|
||||
struct update_t
|
||||
{
|
||||
static_assert(Table::_table_set::template is_superset_of<typename UpdateList::_table_set>::value, "updated columns do not match the table");
|
||||
static_assert(Table::_table_set::template is_superset_of<typename Where::_table_set>::value, "where condition does not match updated table");
|
||||
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename UpdateList::_table_set>::value, "updated columns do not match the table");
|
||||
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename Where::_table_set>::value, "where condition does not match updated table");
|
||||
|
||||
using _database_t = Database;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
39
include/sqlpp11/vendor/assignment.h
vendored
39
include/sqlpp11/vendor/assignment.h
vendored
@ -38,6 +38,30 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename T, typename Enable = void>
|
||||
struct is_trivial_t
|
||||
{
|
||||
static constexpr bool _(const T&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_trivial_t<T, typename std::enable_if<std::is_member_function_pointer<decltype(&T::_is_trivial)>::value, void>::type>
|
||||
{
|
||||
static bool _(const T& t)
|
||||
{
|
||||
return t._is_trivial();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool is_trivial(const T& t)
|
||||
{
|
||||
return is_trivial_t<typename T::value_type>::_(t);
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
{
|
||||
@ -45,9 +69,9 @@ namespace sqlpp
|
||||
using _column_t = Lhs;
|
||||
using value_type = Rhs;
|
||||
using _parameter_tuple_t = std::tuple<_column_t, Rhs>;
|
||||
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
static_assert(not std::is_same<Rhs, null_t>::value or can_be_null_t<_column_t>::value, "column cannot be null");
|
||||
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<Rhs, null_t>::value, "column must not be null");
|
||||
|
||||
assignment_t(_column_t lhs, value_type rhs):
|
||||
_lhs(lhs),
|
||||
@ -70,10 +94,20 @@ namespace sqlpp
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||
and is_trivial_t<typename T::value_type>::_(t._rhs))
|
||||
or (std::is_same<Rhs, null_t>::value))
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
@ -85,6 +119,7 @@ namespace sqlpp
|
||||
using _column_t = Lhs;
|
||||
using value_type = tvin_t<Rhs>;
|
||||
using _parameter_tuple_t = std::tuple<_column_t, Rhs>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
static_assert(can_be_null_t<_column_t>::value, "column cannot be null");
|
||||
|
||||
|
2
include/sqlpp11/vendor/concat.h
vendored
2
include/sqlpp11/vendor/concat.h
vendored
@ -39,7 +39,7 @@ namespace sqlpp
|
||||
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
|
||||
{
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
static_assert(sqlpp::detail::and_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
|
||||
static_assert(sqlpp::detail::all_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename First::_table_set, typename Args::_table_set...>::type;
|
||||
|
||||
struct _value_type: public First::_value_type::_base_value_type
|
||||
|
5
include/sqlpp11/vendor/expression.h
vendored
5
include/sqlpp11/vendor/expression.h
vendored
@ -58,7 +58,7 @@ namespace sqlpp
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
tvin_wrap_t<Rhs> _rhs;
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -103,7 +103,7 @@ namespace sqlpp
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
tvin_wrap_t<Rhs> _rhs;
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -209,6 +209,7 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
using _parameter_tuple_t = std::tuple<Rhs>;
|
||||
using _table_set = typename Rhs::_table_set;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
_rhs(rhs)
|
||||
|
7
include/sqlpp11/vendor/field.h
vendored
7
include/sqlpp11/vendor/field.h
vendored
@ -33,11 +33,12 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename NameType, typename ValueType>
|
||||
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
|
||||
struct field_t
|
||||
{
|
||||
using _name_t = NameType;
|
||||
using _value_type = ValueType;
|
||||
static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename FieldTuple>
|
||||
@ -50,7 +51,9 @@ namespace sqlpp
|
||||
template<typename NamedExpr>
|
||||
struct make_field_t_impl
|
||||
{
|
||||
using type = field_t<typename NamedExpr::_name_t, typename NamedExpr::_value_type::_base_value_type>;
|
||||
using type = field_t<typename NamedExpr::_name_t,
|
||||
typename NamedExpr::_value_type::_base_value_type,
|
||||
trivial_value_is_null_t<NamedExpr>::value>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename... NamedExpr>
|
||||
|
2
include/sqlpp11/vendor/from.h
vendored
2
include/sqlpp11/vendor/from.h
vendored
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in from()");
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in from()");
|
||||
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Tables::_table_set...>;
|
||||
|
||||
|
2
include/sqlpp11/vendor/group_by.h
vendored
2
include/sqlpp11/vendor/group_by.h
vendored
@ -51,7 +51,7 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
group_by_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
|
2
include/sqlpp11/vendor/having.h
vendored
2
include/sqlpp11/vendor/having.h
vendored
@ -47,7 +47,7 @@ namespace sqlpp
|
||||
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
|
||||
|
16
include/sqlpp11/vendor/insert_value_list.h
vendored
16
include/sqlpp11/vendor/insert_value_list.h
vendored
@ -61,15 +61,15 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
static_assert(sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
|
||||
static_assert(not sqlpp::detail::or_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(not sqlpp::detail::any_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||
|
||||
insert_list_t(Assignments... assignment):
|
||||
_assignments(assignment...),
|
||||
@ -90,8 +90,8 @@ namespace sqlpp
|
||||
static_assert(not must_not_insert_t<Assignment>::value, "add_set() argument must not be used in insert");
|
||||
using _column_table_set = typename Assignment::_column_t::_table_set;
|
||||
using _value_table_set = typename Assignment::value_type::_table_set;
|
||||
static_assert(_value_table_set::template is_subset_of<typename Insert::_table_set>::value, "add_set() contains a column from a foreign table");
|
||||
static_assert(_column_table_set::template is_subset_of<typename Insert::_table_set>::value, "add_set() contains a value from a foreign table");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, typename Insert::_table_set>::value, "add_set() contains a column from a foreign table");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_column_table_set, typename Insert::_table_set>::value, "add_set() contains a value from a foreign table");
|
||||
_dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
_dynamic_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
@ -114,9 +114,9 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
|
||||
static_assert(::sqlpp::detail::all_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::or_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
||||
static_assert(not ::sqlpp::detail::any_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
||||
|
||||
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Columns::_table_set...>::type;
|
||||
@ -136,7 +136,7 @@ namespace sqlpp
|
||||
template<typename... Assignments>
|
||||
void add_values(Assignments... assignments)
|
||||
{
|
||||
static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
|
||||
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||
|
12
include/sqlpp11/vendor/interpretable.h
vendored
12
include/sqlpp11/vendor/interpretable.h
vendored
@ -59,9 +59,13 @@ namespace sqlpp
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
_serializer_context_t& serialize(_serializer_context_t& context) const
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
auto serialize(Context& context) const
|
||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
{
|
||||
return _impl->serialize(context);
|
||||
return _impl->db_serialize(context);
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
@ -73,7 +77,7 @@ namespace sqlpp
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
};
|
||||
|
||||
@ -91,7 +95,7 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& serialize(_serializer_context_t& context) const
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
|
12
include/sqlpp11/vendor/named_interpretable.h
vendored
12
include/sqlpp11/vendor/named_interpretable.h
vendored
@ -57,9 +57,13 @@ namespace sqlpp
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
_serializer_context_t& serialize(_serializer_context_t& context) const
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
auto serialize(Context& context) const
|
||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
{
|
||||
return _impl->serialize(context);
|
||||
return _impl->db_serialize(context);
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
@ -76,7 +80,7 @@ namespace sqlpp
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
virtual std::string _get_name() const = 0;
|
||||
};
|
||||
@ -95,7 +99,7 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& serialize(_serializer_context_t& context) const
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
|
2
include/sqlpp11/vendor/order_by.h
vendored
2
include/sqlpp11/vendor/order_by.h
vendored
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
|
||||
static_assert(::sqlpp::detail::all_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
|
||||
|
||||
order_by_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
|
10
include/sqlpp11/vendor/select_column_list.h
vendored
10
include/sqlpp11/vendor/select_column_list.h
vendored
@ -143,7 +143,7 @@ namespace sqlpp
|
||||
|
||||
template<typename T>
|
||||
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
|
||||
static_assert(::sqlpp::detail::and_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
|
||||
static_assert(::sqlpp::detail::all_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
@ -156,9 +156,10 @@ namespace sqlpp
|
||||
};
|
||||
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<Columns...>::_name_t;
|
||||
|
||||
template<typename Db>
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<make_field_t<Columns>...>,
|
||||
result_row_t<make_field_t<Columns>...>>::type;
|
||||
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
@ -198,7 +199,8 @@ namespace sqlpp
|
||||
struct no_select_column_list_t
|
||||
{
|
||||
using _is_noop = std::true_type;
|
||||
using _result_row_t = ::sqlpp::result_row_t<>;
|
||||
template<typename Db>
|
||||
using _result_row_t = ::sqlpp::result_row_t<Db>;
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;
|
||||
using _value_type = no_value_t;
|
||||
struct _name_t {};
|
||||
|
2
include/sqlpp11/vendor/select_flag_list.h
vendored
2
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
|
||||
static_assert(::sqlpp::detail::all_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
|
||||
|
||||
select_flag_list_t(Flags... flags):
|
||||
_flags(flags...)
|
||||
|
6
include/sqlpp11/vendor/update_list.h
vendored
6
include/sqlpp11/vendor/update_list.h
vendored
@ -48,15 +48,15 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::or_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(not ::sqlpp::detail::any_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||
|
||||
update_list_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
|
2
include/sqlpp11/vendor/using.h
vendored
2
include/sqlpp11/vendor/using.h
vendored
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
|
||||
|
||||
static_assert(::sqlpp::detail::and_t<is_table_t, Tables...>::value, "at least one argument is not an table in using()");
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not an table in using()");
|
||||
|
||||
using_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
|
4
include/sqlpp11/vendor/where.h
vendored
4
include/sqlpp11/vendor/where.h
vendored
@ -47,8 +47,8 @@ namespace sqlpp
|
||||
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
||||
static_assert(not sqlpp::detail::or_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
|
||||
static_assert(not sqlpp::detail::any_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
|
||||
|
@ -11,6 +11,7 @@ build_and_run(InsertTest)
|
||||
build_and_run(RemoveTest)
|
||||
build_and_run(UpdateTest)
|
||||
build_and_run(SelectTest)
|
||||
build_and_run(SelectTypeTest)
|
||||
build_and_run(FunctionTest)
|
||||
build_and_run(PreparedTest)
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
MockDb db = {};
|
||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||
|
||||
int main()
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include <sqlpp11/insert.h>
|
||||
#include <iostream>
|
||||
|
||||
DbMock db;
|
||||
DbMock::_serializer_context_t printer(std::cerr);
|
||||
MockDb db;
|
||||
MockDb::_serializer_context_t printer;
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -58,16 +58,22 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
serialize(insert_into(t).default_values(), printer).flush();
|
||||
serialize(insert_into(t), printer).flush();
|
||||
serialize(insert_into(t).set(t.beta = "kirschauflauf"), printer).flush();
|
||||
serialize(insert_into(t).columns(t.beta), printer).flush();
|
||||
db(insert_into(t).default_values());
|
||||
db(insert_into(t).set(t.beta = "kirschauflauf"));
|
||||
|
||||
serialize(insert_into(t).default_values(), printer).str();
|
||||
|
||||
serialize(insert_into(t), printer).str();
|
||||
serialize(insert_into(t).set(t.beta = "kirschauflauf"), printer).str();
|
||||
serialize(insert_into(t).columns(t.beta), printer).str();
|
||||
auto multi_insert = insert_into(t).columns(t.beta, t.delta);
|
||||
multi_insert.add_values(t.beta = "cheesecake", t.delta = 1);
|
||||
multi_insert.add_values(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||
i.add_set(t.beta = "kirschauflauf");
|
||||
serialize(i, printer).flush();
|
||||
serialize(i, printer).str();
|
||||
|
||||
db(multi_insert);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
DbMock::_serializer_context_t printer(std::cerr);
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer;
|
||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||
|
||||
int main()
|
||||
@ -43,122 +43,123 @@ int main()
|
||||
test::TabFoo f;
|
||||
test::TabBar t;
|
||||
|
||||
serialize(insert_into(t).columns(t.beta, t.gamma), printer).flush();
|
||||
serialize(insert_into(t).columns(t.beta, t.gamma), printer).str();
|
||||
{
|
||||
auto i = insert_into(t).columns(t.gamma, t.beta);
|
||||
i.add_values(t.gamma = true, t.beta = "cheesecake");
|
||||
serialize(i, printer).flush();
|
||||
serialize(i, printer).str();
|
||||
i.add_values(t.gamma = false, t.beta = sqlpp::tvin("coffee"));
|
||||
i.add_values(t.gamma = false, t.beta = sqlpp::tvin(std::string()));
|
||||
serialize(i, printer).flush();
|
||||
serialize(i, printer).str();
|
||||
i.add_values(t.gamma = sqlpp::default_value, t.beta = sqlpp::null);
|
||||
serialize(i, printer).flush();
|
||||
serialize(i, printer).str();
|
||||
}
|
||||
|
||||
serialize(t.alpha = sqlpp::null, printer).flush();
|
||||
serialize(t.alpha = sqlpp::default_value, printer).flush();
|
||||
serialize(t.alpha, printer).flush();
|
||||
serialize(-t.alpha, printer).flush();
|
||||
serialize(+t.alpha, printer).flush();
|
||||
serialize(-(t.alpha + 7), printer).flush();
|
||||
serialize(t.alpha = 0, printer).flush();
|
||||
serialize(t.alpha = sqlpp::tvin(0), printer).flush();
|
||||
serialize(t.alpha == 0, printer).flush();
|
||||
serialize(t.alpha == sqlpp::tvin(0), printer).flush();
|
||||
serialize(t.alpha != 0, printer).flush();
|
||||
serialize(t.gamma != sqlpp::tvin(false), printer).flush();
|
||||
serialize(t.alpha == 7, printer).flush();
|
||||
serialize(t.beta + "kaesekuchen", printer).flush();
|
||||
serialize(t.alpha = sqlpp::null, printer).str();
|
||||
serialize(t.alpha = sqlpp::default_value, printer).str();
|
||||
serialize(t.alpha, printer).str();
|
||||
serialize(-t.alpha, printer).str();
|
||||
serialize(+t.alpha, printer).str();
|
||||
serialize(-(t.alpha + 7), printer).str();
|
||||
serialize(t.alpha = 0, printer).str();
|
||||
serialize(t.alpha = sqlpp::tvin(0), printer).str();
|
||||
serialize(t.alpha == 0, printer).str();
|
||||
serialize(t.alpha == sqlpp::tvin(0), printer).str();
|
||||
serialize(t.alpha != 0, printer).str();
|
||||
serialize(t.gamma != sqlpp::tvin(false), printer).str();
|
||||
serialize(t.alpha == 7, printer).str();
|
||||
serialize(t.beta + "kaesekuchen", printer).str();
|
||||
|
||||
serialize(sqlpp::select(), printer).flush();
|
||||
serialize(sqlpp::select().flags(sqlpp::distinct), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).flags(sqlpp::distinct), printer).flush();
|
||||
serialize(select(t.alpha, t.beta), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()), printer).flush();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()).limit(17).offset(3), printer).flush();
|
||||
serialize(sqlpp::select(), printer).str();
|
||||
serialize(sqlpp::select().flags(sqlpp::distinct), printer).str();
|
||||
serialize(select(t.alpha, t.beta).flags(sqlpp::distinct), printer).str();
|
||||
serialize(select(t.alpha, t.beta), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()), printer).str();
|
||||
serialize(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()).limit(17).offset(3), printer).str();
|
||||
|
||||
serialize(parameter(sqlpp::bigint(), t.alpha), printer).flush();
|
||||
serialize(parameter(t.alpha), printer).flush();
|
||||
serialize(t.alpha == parameter(t.alpha), printer).flush();
|
||||
serialize(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).flush();
|
||||
serialize(parameter(sqlpp::bigint(), t.alpha), printer).str();
|
||||
serialize(parameter(t.alpha), printer).str();
|
||||
serialize(t.alpha == parameter(t.alpha), printer).str();
|
||||
serialize(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).str();
|
||||
|
||||
serialize(insert_into(t), printer).flush();
|
||||
serialize(insert_into(f).default_values(), printer).flush();
|
||||
serialize(insert_into(t).set(t.gamma = true), printer).flush();
|
||||
//serialize(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush(); cannot test this since gamma cannot be null and a static assert is thrown
|
||||
serialize(insert_into(t), printer).str();
|
||||
serialize(insert_into(f).default_values(), printer).str();
|
||||
serialize(insert_into(t).set(t.gamma = true), printer).str();
|
||||
//serialize(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).str(); cannot test this since gamma cannot be null and a static assert is thrown
|
||||
|
||||
serialize(update(t), printer).flush();
|
||||
serialize(update(t).set(t.gamma = true), printer).flush();
|
||||
serialize(update(t).set(t.gamma = true).where(t.beta.in("kaesekuchen", "cheesecake")), printer).flush();
|
||||
serialize(update(t), printer).str();
|
||||
serialize(update(t).set(t.gamma = true), printer).str();
|
||||
serialize(update(t).set(t.gamma = true).where(t.beta.in("kaesekuchen", "cheesecake")), printer).str();
|
||||
|
||||
serialize(remove_from(t), printer).flush();
|
||||
serialize(remove_from(t).using_(t), printer).flush();
|
||||
serialize(remove_from(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
serialize(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
serialize(remove_from(t), printer).str();
|
||||
serialize(remove_from(t).using_(t), printer).str();
|
||||
serialize(remove_from(t).where(t.alpha == sqlpp::tvin(0)), printer).str();
|
||||
serialize(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).str();
|
||||
|
||||
// functions
|
||||
serialize(sqlpp::value(7), printer).flush();
|
||||
serialize(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).flush();
|
||||
serialize(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).flush();
|
||||
serialize(exists(select(t.alpha).from(t)), printer).flush();
|
||||
serialize(any(select(t.alpha).from(t)), printer).flush();
|
||||
serialize(some(select(t.alpha).from(t)), printer).flush();
|
||||
serialize(count(t.alpha), printer).flush();
|
||||
serialize(min(t.alpha), printer).flush();
|
||||
serialize(max(t.alpha), printer).flush();
|
||||
serialize(avg(t.alpha), printer).flush();
|
||||
serialize(sum(t.alpha), printer).flush();
|
||||
serialize(sqlpp::verbatim_table("whatever"), printer).flush();
|
||||
sqlpp::serialize(sqlpp::value(7), printer).str();// FIXME: Maybe the vendor namespace is not a good idea? argument lives in namespace vendor
|
||||
serialize(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).str();
|
||||
serialize(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).str();
|
||||
serialize(exists(select(t.alpha).from(t)), printer).str();
|
||||
serialize(any(select(t.alpha).from(t)), printer).str();
|
||||
serialize(some(select(t.alpha).from(t)), printer).str();
|
||||
serialize(count(t.alpha), printer).str();
|
||||
serialize(min(t.alpha), printer).str();
|
||||
serialize(max(t.alpha), printer).str();
|
||||
serialize(avg(t.alpha), printer).str();
|
||||
serialize(sum(t.alpha), printer).str();
|
||||
serialize(sqlpp::verbatim_table("whatever"), printer).str();
|
||||
|
||||
// alias
|
||||
serialize(t.as(t.alpha), printer).flush();
|
||||
serialize(t.as(t.alpha).beta, printer).flush();
|
||||
serialize(t.as(t.alpha), printer).str();
|
||||
serialize(t.as(t.alpha).beta, printer).str();
|
||||
|
||||
// select alias
|
||||
serialize(select(t.alpha).from(t).where(t.beta > "kaesekuchen").as(t.gamma), printer).flush();
|
||||
serialize(select(t.alpha).from(t).where(t.beta > "kaesekuchen").as(t.gamma), printer).str();
|
||||
|
||||
serialize(t.alpha.is_null(), printer).flush();
|
||||
serialize(t.alpha.is_null(), printer).str();
|
||||
|
||||
// join
|
||||
serialize(t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta), printer).flush();
|
||||
serialize(t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta), printer).str();
|
||||
|
||||
// multi_column
|
||||
serialize(multi_column(t.alpha, (t.beta + "cake").as(t.gamma)).as(t.alpha), printer).flush();
|
||||
serialize(multi_column(all_of(t)).as(t), printer).flush();
|
||||
serialize(all_of(t).as(t), printer).flush();
|
||||
serialize(multi_column(t.alpha, (t.beta + "cake").as(t.gamma)).as(t.alpha), printer).str();
|
||||
serialize(multi_column(all_of(t)).as(t), printer).str();
|
||||
serialize(all_of(t).as(t), printer).str();
|
||||
|
||||
// dynamic select
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
serialize(s, printer).flush();
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
||||
s.add_flag(sqlpp::distinct);
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
serialize(s, printer).flush();
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags(sqlpp::distinct).dynamic_columns(t.alpha);
|
||||
s.add_flag(sqlpp::all);
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
serialize(s, printer).flush();
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
|
||||
// distinct aggregate
|
||||
serialize(count(sqlpp::distinct, t.alpha % 7), printer).flush();
|
||||
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).flush();
|
||||
serialize(sum(sqlpp::distinct, t.alpha + 7), printer).flush();
|
||||
serialize(count(sqlpp::distinct, t.alpha % 7), printer).str();
|
||||
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).str();
|
||||
serialize(sum(sqlpp::distinct, t.alpha + 7), printer).str();
|
||||
|
||||
serialize(select(all_of(t)).from(t).where(true), printer).str();
|
||||
serialize(select(all_of(t)).from(t).where(false), printer).str();
|
||||
|
||||
serialize(select(all_of(t)).from(t).where(true), printer).flush();
|
||||
serialize(select(all_of(t)).from(t).where(false), printer).flush();
|
||||
return 0;
|
||||
}
|
||||
|
120
tests/MockDb.h
120
tests/MockDb.h
@ -26,15 +26,36 @@
|
||||
#ifndef SQLPP_MOCK_DB_H
|
||||
#define SQLPP_MOCK_DB_H
|
||||
|
||||
#include <sqlpp11/connection.h>
|
||||
#include <sstream>
|
||||
#include <sqlpp11/serializer_context.h>
|
||||
#include <sqlpp11/serialize.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
|
||||
struct DbMock: public sqlpp::connection
|
||||
struct MockDb: public sqlpp::connection
|
||||
{
|
||||
struct _serializer_context_t : public sqlpp::serializer_context_t
|
||||
struct _serializer_context_t
|
||||
{
|
||||
_serializer_context_t(std::ostream& os): sqlpp::serializer_context_t(os) {}
|
||||
std::ostringstream _os;
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
return _os.str();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
_os.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(T t)
|
||||
{
|
||||
return _os << t;
|
||||
}
|
||||
|
||||
static std::string escape(std::string arg)
|
||||
{
|
||||
return sqlpp::serializer_context_t::escape(arg);
|
||||
}
|
||||
};
|
||||
|
||||
using _interpreter_context_t = _serializer_context_t;
|
||||
@ -42,14 +63,97 @@ struct DbMock: public sqlpp::connection
|
||||
template<typename T>
|
||||
static _serializer_context_t& _serialize_interpretable(const T& t, _serializer_context_t& context)
|
||||
{
|
||||
return ::sqlpp::serialize(t, context);
|
||||
sqlpp::serialize(t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static _interpreter_context_t& _interpret_interpretable(const T& t, _interpreter_context_t& context)
|
||||
static _serializer_context_t& _interpret_interpretable(const T& t, _interpreter_context_t& context)
|
||||
{
|
||||
return ::sqlpp::serialize(t, context);
|
||||
sqlpp::serialize(t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
class result_t
|
||||
{
|
||||
public:
|
||||
constexpr bool operator==(const result_t& rhs) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename ResultRow>
|
||||
void next(ResultRow& result_row)
|
||||
{
|
||||
result_row.invalidate();
|
||||
};
|
||||
};
|
||||
|
||||
// Directly executed statements start here
|
||||
template<typename T>
|
||||
auto operator() (const T& t) -> decltype(t._run(*this))
|
||||
{
|
||||
return t._run(*this);
|
||||
}
|
||||
|
||||
template<typename Insert>
|
||||
size_t insert(const Insert& x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Update>
|
||||
size_t update(const Update& x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Remove>
|
||||
size_t remove(const Remove& x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Select>
|
||||
result_t select(const Select& s)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Prepared statements start here
|
||||
using _prepared_statement_t = std::nullptr_t;
|
||||
|
||||
template<typename T>
|
||||
auto prepare(const T& t) -> decltype(t._prepare(*this))
|
||||
{
|
||||
return t._prepare(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename Insert>
|
||||
_prepared_statement_t prepare_insert(Insert& x)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename PreparedInsert>
|
||||
size_t run_prepared_insert(const PreparedInsert& x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Select>
|
||||
_prepared_statement_t prepare_select(Select& x)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename PreparedSelect>
|
||||
result_t run_prepared_select(PreparedSelect& x)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
MockDb db = {};
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -88,6 +88,7 @@ int main()
|
||||
// Wonderful, now take a look at the parameter list of a select
|
||||
{
|
||||
auto s = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
auto p = db.prepare(s);
|
||||
using S = decltype(s);
|
||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||
T npl;
|
||||
|
@ -30,8 +30,8 @@
|
||||
#include "is_regular.h"
|
||||
|
||||
|
||||
DbMock db;
|
||||
DbMock::_serializer_context_t printer(std::cerr);
|
||||
MockDb db;
|
||||
MockDb::_serializer_context_t printer;
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -56,13 +56,15 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
serialize(remove_from(t), printer).flush();
|
||||
serialize(remove_from(t).where(t.beta != "transparent"), printer).flush();
|
||||
serialize(remove_from(t).using_(t), printer).flush();
|
||||
serialize(remove_from(t), printer).str();
|
||||
serialize(remove_from(t).where(t.beta != "transparent"), printer).str();
|
||||
serialize(remove_from(t).using_(t), printer).str();
|
||||
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
|
||||
r.add_using(t);
|
||||
r.add_where(t.beta != "transparent");
|
||||
serialize(r, printer).flush();
|
||||
serialize(r, printer).str();
|
||||
|
||||
db(r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,8 +33,8 @@
|
||||
#include <sqlpp11/connection.h>
|
||||
|
||||
|
||||
DbMock db = {};
|
||||
DbMock::_serializer_context_t printer(std::cerr);
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer;
|
||||
|
||||
namespace alias
|
||||
{
|
||||
@ -49,323 +49,26 @@ int main()
|
||||
test::TabFoo f;
|
||||
test::TabBar t;
|
||||
|
||||
// Test a table
|
||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
||||
{
|
||||
using T = decltype(t);
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
int64_t a = row.alpha;
|
||||
const std::string b = row.beta;
|
||||
}
|
||||
|
||||
// Test an alias of table
|
||||
for (const auto& row : db(select(all_of(t).as(t)).from(t).where(true)))
|
||||
{
|
||||
using T = decltype(t.as(alias::a));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
int64_t a = row.tabBar.alpha;
|
||||
const std::string b = row.tabBar.beta;
|
||||
}
|
||||
|
||||
// Test an integral column of an alias of table
|
||||
#warning this should fail because f is not in from()
|
||||
for (const auto& row : db(select(f.omega, all_of(t).as(t), t.gamma).from(t).where(true)))
|
||||
{
|
||||
using T = decltype(t.as(alias::a).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
int64_t a = row.tabBar.alpha;
|
||||
const std::string b = row.tabBar.beta;
|
||||
const bool g = row.gamma;
|
||||
const float o = row.omega;
|
||||
}
|
||||
|
||||
|
||||
// Test an integral table column
|
||||
{
|
||||
using T = decltype(t.alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a floating point table column
|
||||
{
|
||||
using T = decltype(f.omega);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a an alias of a numeric table column
|
||||
{
|
||||
using T = decltype(t.alpha.as(alias::a));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of a single column without a from
|
||||
{
|
||||
using T = decltype(select(t.alpha)); // Hint: The current rule is pretty crude (a from is required), but certainly better than nothing
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t));
|
||||
static_assert(sqlpp::is_select_column_list_t<decltype(T::_column_list)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_from_t<decltype(T::_from)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "red to not be boolean");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test the column of an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test the column of an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b).a);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test that select(all_of(tab)) is expanded in select
|
||||
{
|
||||
auto a = select(all_of(t));
|
||||
auto b = select(t.alpha, t.beta, t.gamma, t.delta);
|
||||
//auto c = select(t);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by select()");
|
||||
//static_assert(std::is_same<decltype(b), decltype(c)>::value, "t has to be expanded by select()");
|
||||
}
|
||||
|
||||
// Test that select(all_of(tab)) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(all_of(t)).as(alias::a);
|
||||
auto b = multi_column(t.alpha, t.beta, t.gamma, t.delta).as(alias::a);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
// Test that a multicolumn is not a value
|
||||
{
|
||||
auto m = multi_column(t.alpha, t.beta).as(alias::a);
|
||||
auto a = select(m).from(t).as(alias::b).a;
|
||||
static_assert(not sqlpp::is_value_t<decltype(a)>::value, "a multi_column is not a value");
|
||||
}
|
||||
// Test that result sets with identical name/value combinations have identical types
|
||||
{
|
||||
auto a = select(t.alpha);
|
||||
auto b = select(f.epsilon.as(t.alpha));
|
||||
using A = typename decltype(a)::_result_row_t;
|
||||
using B = typename decltype(b)::_result_row_t;
|
||||
static_assert(std::is_same<
|
||||
decltype(t.alpha)::_value_type::_base_value_type,
|
||||
decltype(f.epsilon)::_value_type::_base_value_type>::value, "Two bigint columns must have identical base_value_type");
|
||||
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = dynamic_select(db, all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
|
||||
s.add_from(t);
|
||||
s.add_where(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
||||
s.set_limit(30);
|
||||
s.set_limit(3);
|
||||
std::cerr << "------------------------\n";
|
||||
serialize(s, printer).flush();
|
||||
std::cerr << "------------------------\n";
|
||||
using T = decltype(s);
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test that select can be called with zero columns if it is used with dynamic columns.
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_columns();
|
||||
s.add_column(t.alpha);
|
||||
serialize(s, printer).flush();
|
||||
}
|
||||
|
||||
// Test that verbatim_table compiles
|
||||
{
|
||||
auto s = select(t.alpha).from(sqlpp::verbatim_table("my_unknown_table"));
|
||||
serialize(s, printer).flush();
|
||||
}
|
||||
|
||||
|
||||
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
||||
using T = sqlpp::vendor::wrap_operand<int>::type;
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
static_assert(T::_is_expression, "T has to be an expression");
|
||||
static_assert(std::is_same<typename T::_value_type::_is_numeric, std::true_type>::value, "T has to be a numeric");
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "T has to be a numeric");
|
||||
static_assert(sqlpp::is_numeric_t<decltype(t.alpha)>::value, "TabBar.alpha has to be a numeric");
|
||||
((t.alpha + 7) + 4).asc();
|
||||
static_assert(sqlpp::is_boolean_t<decltype(t.gamma == t.gamma)>::value, "Comparison expression have to be boolean");
|
||||
auto x = (t.gamma == true) and (t.alpha == 7);
|
||||
auto y = t.gamma and true and t.gamma;
|
||||
!t.gamma;
|
||||
t.beta < "kaesekuchen";
|
||||
serialize(t.beta + "hallenhalma", printer).flush();
|
||||
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
|
||||
serialize(t.alpha, printer).flush();
|
||||
std::cerr << "\n" << sizeof(test::TabBar) << std::endl;
|
||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_is_named_expression, std::true_type>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be a named expression");
|
||||
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be an alias");
|
||||
auto z = select(t.alpha).from(t) == 7;
|
||||
auto l = t.as(alias::left);
|
||||
auto r = select(t.gamma.as(alias::a)).from(t).where(t.gamma == true).as(alias::right);
|
||||
static_assert(sqlpp::is_boolean_t<decltype(select(t.gamma).from(t))>::value, "select(bool) has to be a bool");
|
||||
serialize(sqlpp::select().flags(sqlpp::distinct, sqlpp::straight_join).columns(l.alpha, l.beta, select(r.a).from(r))
|
||||
.from(l, r)
|
||||
.where(t.beta == "hello world" and select(t.gamma).from(t))// .as(alias::right))
|
||||
.group_by(l.gamma, r.a)
|
||||
.having(r.a != true)
|
||||
.order_by(l.beta.asc())
|
||||
.limit(17)
|
||||
.offset(3)
|
||||
.as(alias::a)
|
||||
, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
376
tests/SelectTypeTest.cpp
Normal file
376
tests/SelectTypeTest.cpp
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "Sample.h"
|
||||
#include "MockDb.h"
|
||||
#include "is_regular.h"
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <sqlpp11/select.h>
|
||||
#include <sqlpp11/functions.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
|
||||
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer;
|
||||
|
||||
namespace alias
|
||||
{
|
||||
SQLPP_ALIAS_PROVIDER(a);
|
||||
SQLPP_ALIAS_PROVIDER(b);
|
||||
SQLPP_ALIAS_PROVIDER(left);
|
||||
SQLPP_ALIAS_PROVIDER(right);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test::TabFoo f;
|
||||
test::TabBar t;
|
||||
|
||||
// Test a table
|
||||
{
|
||||
using T = decltype(t);
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an alias of table
|
||||
{
|
||||
using T = decltype(t.as(alias::a));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an integral column of an alias of table
|
||||
{
|
||||
using T = decltype(t.as(alias::a).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
|
||||
// Test an integral table column
|
||||
{
|
||||
using T = decltype(t.alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a floating point table column
|
||||
{
|
||||
using T = decltype(f.omega);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a an alias of a numeric table column
|
||||
{
|
||||
using T = decltype(t.alpha.as(alias::a));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of a single column without a from
|
||||
{
|
||||
using T = decltype(select(t.alpha)); // Hint: The current rule is pretty crude (a from is required), but certainly better than nothing
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t));
|
||||
static_assert(sqlpp::is_select_column_list_t<decltype(T::_column_list)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_from_t<decltype(T::_from)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "red to not be boolean");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test the column of an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test the column of an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b).a);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test that select(all_of(tab)) is expanded in select
|
||||
{
|
||||
auto a = select(all_of(t));
|
||||
auto b = select(t.alpha, t.beta, t.gamma, t.delta);
|
||||
//auto c = select(t);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by select()");
|
||||
//static_assert(std::is_same<decltype(b), decltype(c)>::value, "t has to be expanded by select()");
|
||||
}
|
||||
|
||||
// Test that select(all_of(tab)) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(all_of(t)).as(alias::a);
|
||||
auto b = multi_column(t.alpha, t.beta, t.gamma, t.delta).as(alias::a);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
// Test that a multicolumn is not a value
|
||||
{
|
||||
auto m = multi_column(t.alpha, t.beta).as(alias::a);
|
||||
auto a = select(m).from(t).as(alias::b).a;
|
||||
static_assert(not sqlpp::is_value_t<decltype(a)>::value, "a multi_column is not a value");
|
||||
}
|
||||
// Test that result sets with identical name/value combinations have identical types
|
||||
{
|
||||
auto a = select(t.alpha);
|
||||
auto b = select(f.epsilon.as(t.alpha));
|
||||
using A = typename decltype(a)::_result_row_t<MockDb>;
|
||||
using B = typename decltype(b)::_result_row_t<MockDb>;
|
||||
static_assert(std::is_same<
|
||||
decltype(t.alpha)::_value_type::_base_value_type,
|
||||
decltype(f.epsilon)::_value_type::_base_value_type>::value, "Two bigint columns must have identical base_value_type");
|
||||
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
||||
}
|
||||
|
||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
||||
{
|
||||
int64_t a = row.alpha;
|
||||
}
|
||||
|
||||
{
|
||||
auto s = dynamic_select(db, all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
|
||||
s.add_from(t);
|
||||
s.add_where(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
||||
s.set_limit(30);
|
||||
s.set_limit(3);
|
||||
std::cerr << "------------------------\n";
|
||||
serialize(s, printer).str();
|
||||
std::cerr << "------------------------\n";
|
||||
using T = decltype(s);
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
// Test that select can be called with zero columns if it is used with dynamic columns.
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_columns();
|
||||
s.add_column(t.alpha);
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
|
||||
// Test that verbatim_table compiles
|
||||
{
|
||||
auto s = select(t.alpha).from(sqlpp::verbatim_table("my_unknown_table"));
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
|
||||
|
||||
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
||||
using T = sqlpp::vendor::wrap_operand<int>::type;
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
static_assert(T::_is_expression, "T has to be an expression");
|
||||
static_assert(std::is_same<typename T::_value_type::_is_numeric, std::true_type>::value, "T has to be a numeric");
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "T has to be a numeric");
|
||||
static_assert(sqlpp::is_numeric_t<decltype(t.alpha)>::value, "TabBar.alpha has to be a numeric");
|
||||
((t.alpha + 7) + 4).asc();
|
||||
static_assert(sqlpp::is_boolean_t<decltype(t.gamma == t.gamma)>::value, "Comparison expression have to be boolean");
|
||||
auto x = (t.gamma == true) and (t.alpha == 7);
|
||||
auto y = t.gamma and true and t.gamma;
|
||||
!t.gamma;
|
||||
t.beta < "kaesekuchen";
|
||||
serialize(t.beta + "hallenhalma", printer).str();
|
||||
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
|
||||
serialize(t.alpha, printer).str();
|
||||
std::cerr << "\n" << sizeof(test::TabBar) << std::endl;
|
||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_is_named_expression, std::true_type>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be a named expression");
|
||||
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be an alias");
|
||||
auto z = select(t.alpha).from(t) == 7;
|
||||
auto l = t.as(alias::left);
|
||||
auto r = select(t.gamma.as(alias::a)).from(t).where(t.gamma == true).as(alias::right);
|
||||
static_assert(sqlpp::is_boolean_t<decltype(select(t.gamma).from(t))>::value, "select(bool) has to be a bool");
|
||||
serialize(sqlpp::select().flags(sqlpp::distinct, sqlpp::straight_join).columns(l.alpha, l.beta, select(r.a).from(r))
|
||||
.from(l, r)
|
||||
.where(t.beta == "hello world" and select(t.gamma).from(t))// .as(alias::right))
|
||||
.group_by(l.gamma, r.a)
|
||||
.having(r.a != true)
|
||||
.order_by(l.beta.asc())
|
||||
.limit(17)
|
||||
.offset(3)
|
||||
.as(alias::a)
|
||||
, printer).str();
|
||||
|
||||
return 0;
|
||||
}
|
@ -29,8 +29,8 @@
|
||||
#include "MockDb.h"
|
||||
#include "is_regular.h"
|
||||
|
||||
DbMock db;
|
||||
DbMock::_serializer_context_t printer(std::cerr);
|
||||
MockDb db;
|
||||
MockDb::_serializer_context_t printer;
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -56,13 +56,15 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
serialize(update(t), printer).flush();
|
||||
serialize(update(t).set(t.gamma = false), printer).flush();
|
||||
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).flush();
|
||||
serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).flush();
|
||||
serialize(update(t), printer).str();
|
||||
serialize(update(t).set(t.gamma = false), printer).str();
|
||||
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).str();
|
||||
serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).str();
|
||||
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||
u.add_set(t.gamma = false);
|
||||
serialize(u, printer).flush();
|
||||
serialize(u, printer).str();
|
||||
|
||||
db(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user