mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +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
|
#define SQLPP_BOOLEAN_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sqlpp11/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
@ -98,6 +99,7 @@ namespace sqlpp
|
|||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Db, bool NullIsTrivial = false>
|
||||||
struct _result_entry_t
|
struct _result_entry_t
|
||||||
{
|
{
|
||||||
_result_entry_t():
|
_result_entry_t():
|
||||||
@ -133,15 +135,28 @@ namespace sqlpp
|
|||||||
|
|
||||||
bool is_null() const
|
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");
|
throw exception("accessing is_null in non-existing row");
|
||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpp_value_type value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||||
throw exception("accessing value in non-existing row");
|
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;
|
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();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -34,52 +34,52 @@ namespace sqlpp
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<bool... b>
|
template<bool... b>
|
||||||
struct and_impl;
|
struct all_impl;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct and_impl<>
|
struct all_impl<>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool... Rest>
|
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>
|
template<bool... Rest>
|
||||||
struct and_impl<false, Rest...>
|
struct all_impl<false, Rest...>
|
||||||
{
|
{
|
||||||
static constexpr bool value = false;
|
static constexpr bool value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename> class Predicate, typename... T>
|
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>
|
template<bool... b>
|
||||||
struct or_impl;
|
struct any_impl;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct or_impl<>
|
struct any_impl<>
|
||||||
{
|
{
|
||||||
static constexpr bool value = false;
|
static constexpr bool value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool... Rest>
|
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>
|
template<bool... Rest>
|
||||||
struct or_impl<true, Rest...>
|
struct any_impl<true, Rest...>
|
||||||
{
|
{
|
||||||
static constexpr bool value = true;
|
static constexpr bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename> class Predicate, typename... T>
|
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
|
// some forward declarations and helpers
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
struct make_set;
|
struct make_type_set;
|
||||||
|
|
||||||
|
template<typename E, typename SET>
|
||||||
|
struct is_element_of;
|
||||||
|
|
||||||
// A type set
|
// A type set
|
||||||
template<typename... Elements>
|
template<typename... Elements>
|
||||||
@ -47,118 +50,126 @@ namespace sqlpp
|
|||||||
using size = std::integral_constant<size_t, sizeof...(Elements)>;
|
using size = std::integral_constant<size_t, sizeof...(Elements)>;
|
||||||
using _is_type_set = std::true_type;
|
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");
|
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 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct insert
|
struct insert
|
||||||
{
|
{
|
||||||
using type = typename std::conditional<count<T>::value,
|
using type = typename std::conditional<not is_element_of<T, type_set>::value,
|
||||||
type_set,
|
type_set<T, Elements...>,
|
||||||
type_set<T, Elements...>>::type;
|
type_set>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename A> class Predicate, typename T>
|
template<template<typename A> class Predicate, typename T>
|
||||||
struct insert_if
|
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<Elements..., T>,
|
||||||
type_set>::type;
|
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<>
|
template<>
|
||||||
struct make_set<>
|
struct make_type_set<>
|
||||||
{
|
{
|
||||||
using type = type_set<>;
|
using type = type_set<>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename... Rest>
|
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>
|
template<template<typename> class Predicate, typename... T>
|
||||||
struct make_set_if;
|
struct make_type_set_if;
|
||||||
|
|
||||||
template<template<typename> class Predicate>
|
template<template<typename> class Predicate>
|
||||||
struct make_set_if<Predicate>
|
struct make_type_set_if<Predicate>
|
||||||
{
|
{
|
||||||
using type = type_set<>;
|
using type = type_set<>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename> class Predicate, typename T, typename... Rest>
|
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>
|
template<template<typename> class Predicate, typename... T>
|
||||||
struct make_set_if_not
|
struct make_type_set_if_not
|
||||||
{
|
{
|
||||||
template<typename X>
|
template<typename X>
|
||||||
using InversePredicate = std::integral_constant<bool, not Predicate<X>::value>;
|
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>
|
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>
|
template<typename... T>
|
||||||
struct make_joined_set
|
struct make_joined_set
|
||||||
@ -172,20 +183,12 @@ namespace sqlpp
|
|||||||
using type = type_set<>;
|
using type = type_set<>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
template<typename... E>
|
|
||||||
struct make_joined_set<type_set<E...>>
|
|
||||||
{
|
|
||||||
using type = type_set<E...>;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename... E, typename... T>
|
template<typename... E, typename... T>
|
||||||
struct make_joined_set<type_set<E...>, T...>
|
struct make_joined_set<type_set<E...>, T...>
|
||||||
{
|
{
|
||||||
using _rest = typename make_joined_set<T...>::type;
|
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
|
#define SQLPP_FLOATING_POINT_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
#include <sqlpp11/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
@ -98,6 +99,7 @@ namespace sqlpp
|
|||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Db, bool NullIsTrivial = false>
|
||||||
struct _result_entry_t
|
struct _result_entry_t
|
||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
@ -135,15 +137,28 @@ namespace sqlpp
|
|||||||
|
|
||||||
bool is_null() const
|
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");
|
throw exception("accessing is_null in non-existing row");
|
||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpp_value_type value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||||
throw exception("accessing value in non-existing row");
|
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;
|
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();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace sqlpp
|
|||||||
>
|
>
|
||||||
struct insert_t
|
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 _database_t = Database;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
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
|
#define SQLPP_INTEGRAL_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
#include <sqlpp11/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
@ -98,6 +99,7 @@ namespace sqlpp
|
|||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Db, bool NullIsTrivial = false>
|
||||||
struct _result_entry_t
|
struct _result_entry_t
|
||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
@ -135,15 +137,28 @@ namespace sqlpp
|
|||||||
|
|
||||||
bool is_null() const
|
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");
|
throw exception("accessing is_null in non-existing row");
|
||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpp_value_type value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||||
throw exception("accessing value in non-existing row");
|
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;
|
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();
|
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(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(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_table = std::true_type;
|
||||||
using _is_join = 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>
|
template<typename OnT>
|
||||||
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
||||||
|
@ -40,7 +40,7 @@ namespace sqlpp
|
|||||||
template<typename Unused, typename... Columns>
|
template<typename Unused, typename... Columns>
|
||||||
struct multi_column_t
|
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):
|
multi_column_t(std::tuple<Columns...> columns):
|
||||||
_columns(columns)
|
_columns(columns)
|
||||||
@ -72,7 +72,7 @@ namespace sqlpp
|
|||||||
template<typename AliasProvider, typename... Columns>
|
template<typename AliasProvider, typename... Columns>
|
||||||
struct multi_column_alias_t
|
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;
|
using _name_t = typename AliasProvider::_name_t;
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@ namespace sqlpp
|
|||||||
static constexpr bool _is_expression = true;
|
static constexpr bool _is_expression = true;
|
||||||
using _value_type = no_value_t;
|
using _value_type = no_value_t;
|
||||||
using _table_set = ::sqlpp::detail::type_set<>;
|
using _table_set = ::sqlpp::detail::type_set<>;
|
||||||
|
|
||||||
static constexpr bool _is_trivial() { return false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
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;
|
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(_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>
|
template<typename E>
|
||||||
void add(E expr)
|
void add(E expr)
|
||||||
|
@ -32,15 +32,15 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename Db, typename Select>
|
template<typename Database, typename Select>
|
||||||
struct prepared_select_t
|
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 _parameter_list_t = typename Select::_parameter_list_t;
|
||||||
using _dynamic_names_t = typename Select::_dynamic_names_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>
|
-> result_t<decltype(db.run_prepared_select(*this)), _result_row_t>
|
||||||
{
|
{
|
||||||
return {db.run_prepared_select(*this), _dynamic_names};
|
return {db.run_prepared_select(*this), _dynamic_names};
|
||||||
|
@ -41,13 +41,13 @@ namespace sqlpp
|
|||||||
template<size_t level, size_t index, typename... NamedExpr>
|
template<size_t level, size_t index, typename... NamedExpr>
|
||||||
struct result_row_impl;
|
struct result_row_impl;
|
||||||
|
|
||||||
template<size_t level, size_t index, typename NamedExpr, typename... Rest>
|
template<size_t level, size_t index, typename Db, typename NamedExpr, typename... Rest>
|
||||||
struct result_row_impl<level, index, NamedExpr, Rest...>:
|
struct result_row_impl<level, index, Db, NamedExpr, Rest...>:
|
||||||
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::_result_entry_t>,
|
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, Rest...>
|
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 _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, Rest...>;
|
using _rest = result_row_impl<level, index + 1, Db, Rest...>;
|
||||||
static constexpr size_t _last_index = _rest::_last_index;
|
static constexpr size_t _last_index = _rest::_last_index;
|
||||||
|
|
||||||
result_row_impl() = default;
|
result_row_impl() = default;
|
||||||
@ -84,13 +84,13 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
template<size_t level, size_t index, typename AliasProvider, typename Db, typename... Col, typename... Rest>
|
||||||
struct result_row_impl<level, index, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, 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, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
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), Rest...>
|
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 _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), Rest...>;
|
using _rest = result_row_impl<level, index + sizeof...(Col), Db, Rest...>;
|
||||||
static constexpr size_t _last_index = _rest::_last_index;
|
static constexpr size_t _last_index = _rest::_last_index;
|
||||||
|
|
||||||
result_row_impl() = default;
|
result_row_impl() = default;
|
||||||
@ -126,8 +126,8 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t level, size_t index>
|
template<size_t level, size_t index, typename Db>
|
||||||
struct result_row_impl<level, index>
|
struct result_row_impl<level, index, Db>
|
||||||
{
|
{
|
||||||
static constexpr size_t _last_index = index;
|
static constexpr size_t _last_index = index;
|
||||||
result_row_impl() = default;
|
result_row_impl() = default;
|
||||||
@ -155,10 +155,10 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... NamedExpr>
|
template<typename Db, typename... NamedExpr>
|
||||||
struct result_row_t: public detail::result_row_impl<0, 0, 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;
|
bool _is_valid;
|
||||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||||
|
|
||||||
@ -221,11 +221,11 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... NamedExpr>
|
template<typename Db, typename... NamedExpr>
|
||||||
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, 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 _impl = detail::result_row_impl<0, 0, Db, NamedExpr...>;
|
||||||
using _field_type = detail::text::_result_entry_t;
|
using _field_type = detail::text::_result_entry_t<Db, false>;
|
||||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||||
|
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
|
@ -58,8 +58,8 @@ namespace sqlpp
|
|||||||
>
|
>
|
||||||
struct select_helper_t
|
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<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, "Yikes");
|
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<
|
using _value_type = typename std::conditional<
|
||||||
sqlpp::is_from_t<From>::value,
|
sqlpp::is_from_t<From>::value,
|
||||||
typename ColumnList::_value_type,
|
typename ColumnList::_value_type,
|
||||||
@ -99,7 +99,8 @@ namespace sqlpp
|
|||||||
using _table_set = ::sqlpp::detail::type_set<>;
|
using _table_set = ::sqlpp::detail::type_set<>;
|
||||||
|
|
||||||
using _column_list_t = ColumnList;
|
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 _dynamic_names_t = typename _column_list_t::_dynamic_names_t;
|
||||||
|
|
||||||
using _is_select = std::true_type;
|
using _is_select = std::true_type;
|
||||||
@ -490,13 +491,19 @@ namespace sqlpp
|
|||||||
|
|
||||||
size_t get_no_of_result_columns() const
|
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>
|
template<typename Db>
|
||||||
struct can_run_t
|
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(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_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");
|
//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
|
// Execute
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto _run(Db& db) const
|
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(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");
|
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);
|
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
|
#endif
|
||||||
|
@ -42,15 +42,21 @@ namespace sqlpp
|
|||||||
return _os << t;
|
return _os << t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush()
|
static std::string escape(std::string arg)
|
||||||
{
|
{
|
||||||
_os << std::endl;
|
if (arg.find('\''))
|
||||||
}
|
{
|
||||||
|
std::string retVal;
|
||||||
std::string escape(std::string arg)
|
for (const auto c : arg)
|
||||||
{
|
{
|
||||||
// FIXME: Need to do better escaping
|
if (c == '\'')
|
||||||
return arg;
|
retVal.push_back(c);
|
||||||
|
retVal.push_back(c);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& _os;
|
std::ostream& _os;
|
||||||
|
@ -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)
|
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");
|
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>...>;
|
using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>;
|
||||||
template<typename AliasProvider>
|
template<typename AliasProvider>
|
||||||
using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#ifndef SQLPP_TEXT_H
|
#ifndef SQLPP_TEXT_H
|
||||||
#define SQLPP_TEXT_H
|
#define SQLPP_TEXT_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <sqlpp11/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
@ -97,6 +98,7 @@ namespace sqlpp
|
|||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Db, bool NullIsTrivial = false>
|
||||||
struct _result_entry_t
|
struct _result_entry_t
|
||||||
{
|
{
|
||||||
_result_entry_t():
|
_result_entry_t():
|
||||||
@ -135,15 +137,28 @@ namespace sqlpp
|
|||||||
|
|
||||||
bool is_null() const
|
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");
|
throw exception("accessing is_null in non-existing row");
|
||||||
return _value_ptr == nullptr;
|
return _value_ptr == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpp_value_type value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||||
throw exception("accessing value in non-existing row");
|
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)
|
if (_value_ptr)
|
||||||
return std::string(_value_ptr, _value_ptr + _len);
|
return std::string(_value_ptr, _value_ptr + _len);
|
||||||
else
|
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();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct tvin_wrap_t
|
struct maybe_tvin_t
|
||||||
{
|
{
|
||||||
using _table_set = typename T::_table_set;
|
using _table_set = typename T::_table_set;
|
||||||
static constexpr bool _is_trivial()
|
static constexpr bool _is_trivial()
|
||||||
@ -82,20 +82,20 @@ namespace sqlpp
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tvin_wrap_t(T t):
|
maybe_tvin_t(T t):
|
||||||
_value(t)
|
_value(t)
|
||||||
{}
|
{}
|
||||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||||
~tvin_wrap_t() = default;
|
~maybe_tvin_t() = default;
|
||||||
|
|
||||||
T _value;
|
T _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct tvin_wrap_t<tvin_t<T>>
|
struct maybe_tvin_t<tvin_t<T>>
|
||||||
{
|
{
|
||||||
using _table_set = typename T::_table_set;
|
using _table_set = typename T::_table_set;
|
||||||
bool _is_trivial() const
|
bool _is_trivial() const
|
||||||
@ -103,14 +103,14 @@ namespace sqlpp
|
|||||||
return _value._is_trivial();
|
return _value._is_trivial();
|
||||||
};
|
};
|
||||||
|
|
||||||
tvin_wrap_t(tvin_t<T> t):
|
maybe_tvin_t(tvin_t<T> t):
|
||||||
_value(t._value)
|
_value(t._value)
|
||||||
{}
|
{}
|
||||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||||
~tvin_wrap_t() = default;
|
~maybe_tvin_t() = default;
|
||||||
|
|
||||||
typename tvin_t<T>::_operand_t _value;
|
typename tvin_t<T>::_operand_t _value;
|
||||||
};
|
};
|
||||||
@ -118,9 +118,9 @@ namespace sqlpp
|
|||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Context, typename Operand>
|
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)
|
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(must_not_update);
|
||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
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_noop);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
||||||
@ -123,7 +124,8 @@ namespace sqlpp
|
|||||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_parameter);
|
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>
|
template<typename T, template<typename> class IsTag>
|
||||||
using copy_type_trait = typename std::conditional<IsTag<T>::value, std::true_type, std::false_type>::type;
|
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>
|
typename Where = vendor::no_where_t>
|
||||||
struct update_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(::sqlpp::detail::is_superset_of<typename Table::_table_set, 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 Where::_table_set>::value, "where condition does not match updated table");
|
||||||
|
|
||||||
using _database_t = Database;
|
using _database_t = Database;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
45
include/sqlpp11/vendor/assignment.h
vendored
45
include/sqlpp11/vendor/assignment.h
vendored
@ -38,6 +38,30 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
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>
|
template<typename Lhs, typename Rhs>
|
||||||
struct assignment_t
|
struct assignment_t
|
||||||
{
|
{
|
||||||
@ -45,9 +69,9 @@ namespace sqlpp
|
|||||||
using _column_t = Lhs;
|
using _column_t = Lhs;
|
||||||
using value_type = Rhs;
|
using value_type = Rhs;
|
||||||
using _parameter_tuple_t = std::tuple<_column_t, 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):
|
assignment_t(_column_t lhs, value_type rhs):
|
||||||
_lhs(lhs),
|
_lhs(lhs),
|
||||||
@ -71,9 +95,19 @@ namespace sqlpp
|
|||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
serialize(simple_column(t._lhs), context);
|
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||||
context << "=";
|
and is_trivial_t<typename T::value_type>::_(t._rhs))
|
||||||
serialize(t._rhs, context);
|
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;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -85,6 +119,7 @@ namespace sqlpp
|
|||||||
using _column_t = Lhs;
|
using _column_t = Lhs;
|
||||||
using value_type = tvin_t<Rhs>;
|
using value_type = tvin_t<Rhs>;
|
||||||
using _parameter_tuple_t = std::tuple<_column_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");
|
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...>>
|
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(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;
|
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
|
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;
|
~binary_expression_t() = default;
|
||||||
|
|
||||||
Lhs _lhs;
|
Lhs _lhs;
|
||||||
tvin_wrap_t<Rhs> _rhs;
|
maybe_tvin_t<Rhs> _rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
@ -103,7 +103,7 @@ namespace sqlpp
|
|||||||
~binary_expression_t() = default;
|
~binary_expression_t() = default;
|
||||||
|
|
||||||
Lhs _lhs;
|
Lhs _lhs;
|
||||||
tvin_wrap_t<Rhs> _rhs;
|
maybe_tvin_t<Rhs> _rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
@ -209,6 +209,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _value_type = typename O::_value_type;
|
using _value_type = typename O::_value_type;
|
||||||
using _parameter_tuple_t = std::tuple<Rhs>;
|
using _parameter_tuple_t = std::tuple<Rhs>;
|
||||||
|
using _table_set = typename Rhs::_table_set;
|
||||||
|
|
||||||
unary_expression_t(Rhs rhs):
|
unary_expression_t(Rhs rhs):
|
||||||
_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
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename NameType, typename ValueType>
|
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
|
||||||
struct field_t
|
struct field_t
|
||||||
{
|
{
|
||||||
using _name_t = NameType;
|
using _name_t = NameType;
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
|
static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename AliasProvider, typename FieldTuple>
|
template<typename AliasProvider, typename FieldTuple>
|
||||||
@ -50,7 +51,9 @@ namespace sqlpp
|
|||||||
template<typename NamedExpr>
|
template<typename NamedExpr>
|
||||||
struct make_field_t_impl
|
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>
|
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
|
// 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(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...>;
|
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(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):
|
group_by_t(Expressions... expressions):
|
||||||
_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...>;
|
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(_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;
|
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(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 _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 _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;
|
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(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):
|
insert_list_t(Assignments... assignment):
|
||||||
_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");
|
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 _column_table_set = typename Assignment::_column_t::_table_set;
|
||||||
using _value_table_set = typename Assignment::value_type::_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(::sqlpp::detail::is_subset_of<_value_table_set, 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<_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_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||||
_dynamic_values.emplace_back(assignment._rhs);
|
_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(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 _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
|
||||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Columns::_table_set...>::type;
|
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Columns::_table_set...>::type;
|
||||||
@ -136,7 +136,7 @@ namespace sqlpp
|
|||||||
template<typename... Assignments>
|
template<typename... Assignments>
|
||||||
void add_values(Assignments... 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 _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>;
|
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");
|
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);
|
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
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
@ -73,7 +77,7 @@ namespace sqlpp
|
|||||||
struct _impl_base
|
struct _impl_base
|
||||||
{
|
{
|
||||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
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 _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,7 +95,7 @@ namespace sqlpp
|
|||||||
return context;
|
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);
|
Db::_serialize_interpretable(_t, context);
|
||||||
return 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);
|
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
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
@ -76,7 +80,7 @@ namespace sqlpp
|
|||||||
struct _impl_base
|
struct _impl_base
|
||||||
{
|
{
|
||||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
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 _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||||
virtual std::string _get_name() const = 0;
|
virtual std::string _get_name() const = 0;
|
||||||
};
|
};
|
||||||
@ -95,7 +99,7 @@ namespace sqlpp
|
|||||||
return context;
|
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);
|
Db::_serialize_interpretable(_t, context);
|
||||||
return 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(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):
|
order_by_t(Expressions... expressions):
|
||||||
_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>
|
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>;
|
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");
|
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;
|
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,
|
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||||
dynamic_result_row_t<make_field_t<Columns>...>,
|
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||||
result_row_t<make_field_t<Columns>...>>::type;
|
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||||
|
|
||||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||||
|
|
||||||
@ -198,7 +199,8 @@ namespace sqlpp
|
|||||||
struct no_select_column_list_t
|
struct no_select_column_list_t
|
||||||
{
|
{
|
||||||
using _is_noop = std::true_type;
|
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 _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;
|
||||||
using _value_type = no_value_t;
|
using _value_type = no_value_t;
|
||||||
struct _name_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(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):
|
select_flag_list_t(Flags... flags):
|
||||||
_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(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 _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 _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;
|
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(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):
|
update_list_t(Assignments... assignments):
|
||||||
_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(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):
|
using_t(Tables... tables):
|
||||||
_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...>;
|
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(_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(not sqlpp::detail::any_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(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;
|
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(RemoveTest)
|
||||||
build_and_run(UpdateTest)
|
build_and_run(UpdateTest)
|
||||||
build_and_run(SelectTest)
|
build_and_run(SelectTest)
|
||||||
|
build_and_run(SelectTypeTest)
|
||||||
build_and_run(FunctionTest)
|
build_and_run(FunctionTest)
|
||||||
build_and_run(PreparedTest)
|
build_and_run(PreparedTest)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
MockDb db = {};
|
||||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
#include <sqlpp11/insert.h>
|
#include <sqlpp11/insert.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db;
|
MockDb db;
|
||||||
DbMock::_serializer_context_t printer(std::cerr);
|
MockDb::_serializer_context_t printer;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -58,16 +58,22 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(insert_into(t).default_values(), printer).flush();
|
db(insert_into(t).default_values());
|
||||||
serialize(insert_into(t), printer).flush();
|
db(insert_into(t).set(t.beta = "kirschauflauf"));
|
||||||
serialize(insert_into(t).set(t.beta = "kirschauflauf"), printer).flush();
|
|
||||||
serialize(insert_into(t).columns(t.beta), printer).flush();
|
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);
|
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 = "cheesecake", t.delta = 1);
|
||||||
multi_insert.add_values(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
multi_insert.add_values(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
||||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||||
i.add_set(t.beta = "kirschauflauf");
|
i.add_set(t.beta = "kirschauflauf");
|
||||||
serialize(i, printer).flush();
|
serialize(i, printer).str();
|
||||||
|
|
||||||
|
db(multi_insert);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
MockDb db = {};
|
||||||
DbMock::_serializer_context_t printer(std::cerr);
|
MockDb::_serializer_context_t printer;
|
||||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -43,122 +43,123 @@ int main()
|
|||||||
test::TabFoo f;
|
test::TabFoo f;
|
||||||
test::TabBar t;
|
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);
|
auto i = insert_into(t).columns(t.gamma, t.beta);
|
||||||
i.add_values(t.gamma = true, t.beta = "cheesecake");
|
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("coffee"));
|
||||||
i.add_values(t.gamma = false, t.beta = sqlpp::tvin(std::string()));
|
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);
|
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::null, printer).str();
|
||||||
serialize(t.alpha = sqlpp::default_value, printer).flush();
|
serialize(t.alpha = sqlpp::default_value, printer).str();
|
||||||
serialize(t.alpha, printer).flush();
|
serialize(t.alpha, printer).str();
|
||||||
serialize(-t.alpha, printer).flush();
|
serialize(-t.alpha, printer).str();
|
||||||
serialize(+t.alpha, printer).flush();
|
serialize(+t.alpha, printer).str();
|
||||||
serialize(-(t.alpha + 7), printer).flush();
|
serialize(-(t.alpha + 7), printer).str();
|
||||||
serialize(t.alpha = 0, printer).flush();
|
serialize(t.alpha = 0, printer).str();
|
||||||
serialize(t.alpha = sqlpp::tvin(0), printer).flush();
|
serialize(t.alpha = sqlpp::tvin(0), printer).str();
|
||||||
serialize(t.alpha == 0, printer).flush();
|
serialize(t.alpha == 0, printer).str();
|
||||||
serialize(t.alpha == sqlpp::tvin(0), printer).flush();
|
serialize(t.alpha == sqlpp::tvin(0), printer).str();
|
||||||
serialize(t.alpha != 0, printer).flush();
|
serialize(t.alpha != 0, printer).str();
|
||||||
serialize(t.gamma != sqlpp::tvin(false), printer).flush();
|
serialize(t.gamma != sqlpp::tvin(false), printer).str();
|
||||||
serialize(t.alpha == 7, printer).flush();
|
serialize(t.alpha == 7, printer).str();
|
||||||
serialize(t.beta + "kaesekuchen", printer).flush();
|
serialize(t.beta + "kaesekuchen", printer).str();
|
||||||
|
|
||||||
serialize(sqlpp::select(), printer).flush();
|
serialize(sqlpp::select(), printer).str();
|
||||||
serialize(sqlpp::select().flags(sqlpp::distinct), printer).flush();
|
serialize(sqlpp::select().flags(sqlpp::distinct), printer).str();
|
||||||
serialize(select(t.alpha, t.beta).flags(sqlpp::distinct), printer).flush();
|
serialize(select(t.alpha, t.beta).flags(sqlpp::distinct), printer).str();
|
||||||
serialize(select(t.alpha, t.beta), printer).flush();
|
serialize(select(t.alpha, t.beta), printer).str();
|
||||||
serialize(select(t.alpha, t.beta).from(t), printer).flush();
|
serialize(select(t.alpha, t.beta).from(t), printer).str();
|
||||||
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), printer).str();
|
||||||
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), printer).str();
|
||||||
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")), 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).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).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).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).str();
|
||||||
|
|
||||||
serialize(parameter(sqlpp::bigint(), t.alpha), printer).flush();
|
serialize(parameter(sqlpp::bigint(), t.alpha), printer).str();
|
||||||
serialize(parameter(t.alpha), printer).flush();
|
serialize(parameter(t.alpha), printer).str();
|
||||||
serialize(t.alpha == parameter(t.alpha), printer).flush();
|
serialize(t.alpha == parameter(t.alpha), printer).str();
|
||||||
serialize(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).flush();
|
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(t), printer).str();
|
||||||
serialize(insert_into(f).default_values(), printer).flush();
|
serialize(insert_into(f).default_values(), printer).str();
|
||||||
serialize(insert_into(t).set(t.gamma = true), printer).flush();
|
serialize(insert_into(t).set(t.gamma = true), printer).str();
|
||||||
//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).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), printer).str();
|
||||||
serialize(update(t).set(t.gamma = true), printer).flush();
|
serialize(update(t).set(t.gamma = true), printer).str();
|
||||||
serialize(update(t).set(t.gamma = true).where(t.beta.in("kaesekuchen", "cheesecake")), printer).flush();
|
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), printer).str();
|
||||||
serialize(remove_from(t).using_(t), printer).flush();
|
serialize(remove_from(t).using_(t), printer).str();
|
||||||
serialize(remove_from(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
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).flush();
|
serialize(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).str();
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
serialize(sqlpp::value(7), 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).flush();
|
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).flush();
|
serialize(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).str();
|
||||||
serialize(exists(select(t.alpha).from(t)), printer).flush();
|
serialize(exists(select(t.alpha).from(t)), printer).str();
|
||||||
serialize(any(select(t.alpha).from(t)), printer).flush();
|
serialize(any(select(t.alpha).from(t)), printer).str();
|
||||||
serialize(some(select(t.alpha).from(t)), printer).flush();
|
serialize(some(select(t.alpha).from(t)), printer).str();
|
||||||
serialize(count(t.alpha), printer).flush();
|
serialize(count(t.alpha), printer).str();
|
||||||
serialize(min(t.alpha), printer).flush();
|
serialize(min(t.alpha), printer).str();
|
||||||
serialize(max(t.alpha), printer).flush();
|
serialize(max(t.alpha), printer).str();
|
||||||
serialize(avg(t.alpha), printer).flush();
|
serialize(avg(t.alpha), printer).str();
|
||||||
serialize(sum(t.alpha), printer).flush();
|
serialize(sum(t.alpha), printer).str();
|
||||||
serialize(sqlpp::verbatim_table("whatever"), printer).flush();
|
serialize(sqlpp::verbatim_table("whatever"), printer).str();
|
||||||
|
|
||||||
// alias
|
// alias
|
||||||
serialize(t.as(t.alpha), printer).flush();
|
serialize(t.as(t.alpha), printer).str();
|
||||||
serialize(t.as(t.alpha).beta, printer).flush();
|
serialize(t.as(t.alpha).beta, printer).str();
|
||||||
|
|
||||||
// select alias
|
// 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
|
// 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
|
// multi_column
|
||||||
serialize(multi_column(t.alpha, (t.beta + "cake").as(t.gamma)).as(t.alpha), 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).flush();
|
serialize(multi_column(all_of(t)).as(t), printer).str();
|
||||||
serialize(all_of(t).as(t), printer).flush();
|
serialize(all_of(t).as(t), printer).str();
|
||||||
|
|
||||||
// dynamic select
|
// dynamic select
|
||||||
{
|
{
|
||||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
||||||
s.add_column(t.beta);
|
s.add_column(t.beta);
|
||||||
s.add_column(t.gamma);
|
s.add_column(t.gamma);
|
||||||
serialize(s, printer).flush();
|
serialize(s, printer).str();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
auto s = dynamic_select(db).dynamic_flags().dynamic_columns();
|
||||||
s.add_flag(sqlpp::distinct);
|
s.add_flag(sqlpp::distinct);
|
||||||
s.add_column(t.beta);
|
s.add_column(t.beta);
|
||||||
s.add_column(t.gamma);
|
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);
|
auto s = dynamic_select(db).dynamic_flags(sqlpp::distinct).dynamic_columns(t.alpha);
|
||||||
s.add_flag(sqlpp::all);
|
s.add_flag(sqlpp::all);
|
||||||
s.add_column(t.beta);
|
s.add_column(t.beta);
|
||||||
s.add_column(t.gamma);
|
s.add_column(t.gamma);
|
||||||
serialize(s, printer).flush();
|
serialize(s, printer).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// distinct aggregate
|
// distinct aggregate
|
||||||
serialize(count(sqlpp::distinct, t.alpha % 7), printer).flush();
|
serialize(count(sqlpp::distinct, t.alpha % 7), printer).str();
|
||||||
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).flush();
|
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).str();
|
||||||
serialize(sum(sqlpp::distinct, t.alpha + 7), printer).flush();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
122
tests/MockDb.h
122
tests/MockDb.h
@ -24,17 +24,38 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_MOCK_DB_H
|
#ifndef SQLPP_MOCK_DB_H
|
||||||
#define SQLPP_MOCK_DB_H
|
#define SQLPP_MOCK_DB_H
|
||||||
|
|
||||||
#include <sqlpp11/connection.h>
|
#include <sstream>
|
||||||
#include <sqlpp11/serializer_context.h>
|
#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;
|
using _interpreter_context_t = _serializer_context_t;
|
||||||
@ -42,14 +63,97 @@ struct DbMock: public sqlpp::connection
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
static _serializer_context_t& _serialize_interpretable(const T& t, _serializer_context_t& context)
|
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>
|
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
|
#endif
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
MockDb db = {};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -88,6 +88,7 @@ int main()
|
|||||||
// Wonderful, now take a look at the parameter list of a select
|
// 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 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 S = decltype(s);
|
||||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||||
T npl;
|
T npl;
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
#include "is_regular.h"
|
#include "is_regular.h"
|
||||||
|
|
||||||
|
|
||||||
DbMock db;
|
MockDb db;
|
||||||
DbMock::_serializer_context_t printer(std::cerr);
|
MockDb::_serializer_context_t printer;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -56,13 +56,15 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(remove_from(t), printer).flush();
|
serialize(remove_from(t), printer).str();
|
||||||
serialize(remove_from(t).where(t.beta != "transparent"), printer).flush();
|
serialize(remove_from(t).where(t.beta != "transparent"), printer).str();
|
||||||
serialize(remove_from(t).using_(t), printer).flush();
|
serialize(remove_from(t).using_(t), printer).str();
|
||||||
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
|
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
|
||||||
r.add_using(t);
|
r.add_using(t);
|
||||||
r.add_where(t.beta != "transparent");
|
r.add_where(t.beta != "transparent");
|
||||||
serialize(r, printer).flush();
|
serialize(r, printer).str();
|
||||||
|
|
||||||
|
db(r);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
#include <sqlpp11/connection.h>
|
#include <sqlpp11/connection.h>
|
||||||
|
|
||||||
|
|
||||||
DbMock db = {};
|
MockDb db = {};
|
||||||
DbMock::_serializer_context_t printer(std::cerr);
|
MockDb::_serializer_context_t printer;
|
||||||
|
|
||||||
namespace alias
|
namespace alias
|
||||||
{
|
{
|
||||||
@ -49,323 +49,26 @@ int main()
|
|||||||
test::TabFoo f;
|
test::TabFoo f;
|
||||||
test::TabBar t;
|
test::TabBar t;
|
||||||
|
|
||||||
// Test a table
|
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
||||||
{
|
{
|
||||||
using T = decltype(t);
|
int64_t a = row.alpha;
|
||||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
const std::string b = row.beta;
|
||||||
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
|
for (const auto& row : db(select(all_of(t).as(t)).from(t).where(true)))
|
||||||
{
|
{
|
||||||
using T = decltype(t.as(alias::a));
|
int64_t a = row.tabBar.alpha;
|
||||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
const std::string b = row.tabBar.beta;
|
||||||
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
|
#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);
|
int64_t a = row.tabBar.alpha;
|
||||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
const std::string b = row.tabBar.beta;
|
||||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
const bool g = row.gamma;
|
||||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
const float o = row.omega;
|
||||||
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;
|
|
||||||
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;
|
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 "MockDb.h"
|
||||||
#include "is_regular.h"
|
#include "is_regular.h"
|
||||||
|
|
||||||
DbMock db;
|
MockDb db;
|
||||||
DbMock::_serializer_context_t printer(std::cerr);
|
MockDb::_serializer_context_t printer;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -56,13 +56,15 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(update(t), printer).flush();
|
serialize(update(t), printer).str();
|
||||||
serialize(update(t).set(t.gamma = false), printer).flush();
|
serialize(update(t).set(t.gamma = false), printer).str();
|
||||||
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).flush();
|
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).flush();
|
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();
|
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||||
u.add_set(t.gamma = false);
|
u.add_set(t.gamma = false);
|
||||||
serialize(u, printer).flush();
|
serialize(u, printer).str();
|
||||||
|
|
||||||
|
db(u);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user