mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'release/0.18'
This commit is contained in:
commit
229122b4db
@ -51,6 +51,10 @@ namespace sqlpp
|
||||
class connection: public sqlpp::connection // this inheritance helps with ADL for dynamic_select, for instance
|
||||
{
|
||||
public:
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::no_value_t,
|
||||
::sqlpp::tag::enforce_null_result_treatment // If that is what you really want, leave it out otherwise
|
||||
>;
|
||||
|
||||
using _prepared_statement_t = << handle to a prepared statement of the database >>;
|
||||
using _serializer_context_t = << This context is used to serialize a statement >>
|
||||
using _interpreter_context_t = << This context is used interpret a statement >>;
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
template<typename Expression, typename AliasProvider>
|
||||
struct expression_alias_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expression>, tag::named_expression, tag::alias>;
|
||||
using _traits = make_traits<value_type_of<Expression>, tag::is_named_expression, tag::is_alias>;
|
||||
using _recursive_traits = make_recursive_traits<Expression>;
|
||||
|
||||
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
template<typename Select>
|
||||
struct any_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::multi_expression>;
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::is_multi_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
||||
struct _name_t
|
||||
|
@ -30,48 +30,25 @@
|
||||
#include <sqlpp11/default_value.h>
|
||||
#include <sqlpp11/null.h>
|
||||
#include <sqlpp11/tvin.h>
|
||||
#include <sqlpp11/rhs_is_null.h>
|
||||
#include <sqlpp11/serialize.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/simple_column.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
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<T>::_(t);
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_assignment>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
using _column_t = Lhs;
|
||||
using _value_t = Rhs;
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = allow_tvin_t<Rhs>;
|
||||
|
||||
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<_value_t, null_t>::value, "column must not be null");
|
||||
static_assert(can_be_null_t<_lhs_t>::value ? true : not (std::is_same<_rhs_t, null_t>::value or is_tvin_t<_rhs_t>::value), "column must not be null");
|
||||
|
||||
assignment_t(_column_t lhs, _value_t rhs):
|
||||
assignment_t(_lhs_t lhs, _rhs_t rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
@ -82,8 +59,8 @@ namespace sqlpp
|
||||
assignment_t& operator=(assignment_t&&) = default;
|
||||
~assignment_t() = default;
|
||||
|
||||
_column_t _lhs;
|
||||
_value_t _rhs;
|
||||
_lhs_t _lhs;
|
||||
_rhs_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -93,7 +70,7 @@ namespace sqlpp
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||
if (((trivial_value_is_null_t<typename T::_lhs_t>::value or is_tvin_t<typename T::_rhs_t>::value)
|
||||
and is_trivial(t._rhs))
|
||||
or (std::is_same<Rhs, null_t>::value))
|
||||
{
|
||||
@ -110,52 +87,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t<Lhs, tvin_t<Rhs>>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
using _column_t = Lhs;
|
||||
using _value_t = tvin_t<Rhs>;
|
||||
|
||||
static_assert(can_be_null_t<_column_t>::value, "column cannot be null");
|
||||
|
||||
assignment_t(_column_t lhs, _value_t rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
assignment_t(const assignment_t&) = default;
|
||||
assignment_t(assignment_t&&) = default;
|
||||
assignment_t& operator=(const assignment_t&) = default;
|
||||
assignment_t& operator=(assignment_t&&) = default;
|
||||
~assignment_t() = default;
|
||||
|
||||
_column_t _lhs;
|
||||
_value_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, assignment_t<Lhs, tvin_t<Rhs>>>
|
||||
{
|
||||
using T = assignment_t<Lhs, tvin_t<Rhs>>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
if (t._rhs._value._is_trivial())
|
||||
{
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
serialize(t._rhs._value, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
|
||||
public alias_operators<avg_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<floating_point, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "avg() used with flag other than 'distinct'");
|
||||
|
@ -28,7 +28,6 @@
|
||||
#define SQLPP_BOOLEAN_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
@ -42,7 +41,8 @@ namespace sqlpp
|
||||
// boolean value type
|
||||
struct boolean
|
||||
{
|
||||
using _tag = ::sqlpp::tag::boolean;
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::is_boolean, ::sqlpp::tag::is_expression>;
|
||||
using _tag = ::sqlpp::tag::is_boolean;
|
||||
using _cpp_value_type = bool;
|
||||
|
||||
struct _parameter_t
|
||||
@ -96,10 +96,46 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t;
|
||||
|
||||
// I am SO waiting for concepts lite!
|
||||
template<typename Field, typename Enable = void>
|
||||
struct field_methods_t
|
||||
{
|
||||
_result_entry_t():
|
||||
static constexpr bool _null_is_trivial = true;
|
||||
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct field_methods_t<
|
||||
_result_field_t<Db, FieldSpec>,
|
||||
typename std::enable_if<enforce_null_result_treatment_t<Db>::value
|
||||
and column_spec_can_be_null_t<FieldSpec>::value
|
||||
and not null_is_trivial_value_t<FieldSpec>::value>::type>
|
||||
{
|
||||
static constexpr bool _null_is_trivial = false;
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
|
||||
{
|
||||
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
|
||||
|
||||
using _traits = make_traits<integral,
|
||||
tag_if<tag::null_is_trivial_value, _field_methods_t::_null_is_trivial>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
|
||||
};
|
||||
|
||||
_result_field_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(false)
|
||||
@ -119,33 +155,30 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
if (_is_null)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
@ -200,8 +233,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
template<typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_field_t<Db, FieldSpec>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -42,25 +42,31 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Table, typename ColumnSpec>
|
||||
struct column_t: public ColumnSpec::_value_type::template expression_operators<column_t<Table, ColumnSpec>>,
|
||||
public ColumnSpec::_value_type::template column_operators<column_t<Table, ColumnSpec>>
|
||||
struct column_t: public value_type_of<ColumnSpec>::template expression_operators<column_t<Table, ColumnSpec>>,
|
||||
public value_type_of<ColumnSpec>::template column_operators<column_t<Table, ColumnSpec>>
|
||||
{
|
||||
using _traits = make_traits<typename ColumnSpec::_value_type, tag::column, tag::expression, tag::named_expression>;
|
||||
struct _traits
|
||||
{
|
||||
using _value_type = value_type_of<ColumnSpec>;
|
||||
using _tags = detail::make_joined_set_t<detail::type_set<tag::is_column, tag::is_expression, tag::is_named_expression>, typename ColumnSpec::_traits::_tags>;
|
||||
};
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<Table>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = column_spec_can_be_null_t<ColumnSpec>;
|
||||
};
|
||||
|
||||
using _spec_t = ColumnSpec;
|
||||
using _table = Table;
|
||||
using _column_type = typename _spec_t::_column_type;
|
||||
using _name_t = typename _spec_t::_name_t;
|
||||
|
||||
template<typename T>
|
||||
using _is_valid_operand = typename ColumnSpec::_value_type::template _is_valid_operand<T>;
|
||||
using _is_valid_operand = typename value_type_of<ColumnSpec>::template _is_valid_operand<T>;
|
||||
|
||||
column_t() = default;
|
||||
column_t(const column_t&) = default;
|
||||
|
@ -39,7 +39,7 @@ namespace sqlpp
|
||||
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
|
||||
public alias_operators<concat_t<First, Args...>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<First, Args...>;
|
||||
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
|
@ -36,7 +36,7 @@ namespace sqlpp
|
||||
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>,
|
||||
public alias_operators<count_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "count() used with flag other than 'distinct'");
|
||||
|
@ -33,7 +33,7 @@ namespace sqlpp
|
||||
{
|
||||
struct default_value_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::expression>;
|
||||
using _traits = make_traits<no_value_t, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
|
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<std::size_t LastIndex, std::size_t... Ints, typename AliasProvider, typename... Fields, typename... Rest>
|
||||
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, multi_field_t<AliasProvider, Fields...>, Rest...>
|
||||
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, multi_field_spec_t<AliasProvider, Fields...>, Rest...>
|
||||
{
|
||||
using type = typename make_column_index_sequence_impl<column_index_sequence<LastIndex + sizeof...(Fields), Ints..., LastIndex + sizeof...(Fields)>, Rest...>::type;
|
||||
};
|
||||
|
@ -204,13 +204,30 @@ namespace sqlpp
|
||||
struct make_difference_set<type_set<Minuends...>, type_set<Subtrahends...>>
|
||||
{
|
||||
template<typename E>
|
||||
using is_subtrahend = is_element_of<E, type_set<Subtrahends...>>;
|
||||
using is_subtrahend = is_element_of<E, type_set<Subtrahends...>>;
|
||||
using type = typename make_type_set_if_not<is_subtrahend, Minuends...>::type;
|
||||
};
|
||||
|
||||
template<typename Minuend, typename Subtrahend>
|
||||
using make_difference_set_t = typename make_difference_set<Minuend, Subtrahend>::type;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct make_intersect_set
|
||||
{
|
||||
static_assert(::sqlpp::wrong_t<Lhs, Rhs>::value, "invalid argument for intersect set");
|
||||
};
|
||||
|
||||
template<typename... LhsElements, typename... RhsElements>
|
||||
struct make_intersect_set<type_set<LhsElements...>, type_set<RhsElements...>>
|
||||
{
|
||||
template<typename E>
|
||||
using is_in_both = is_element_of<E, make_type_set_t<LhsElements..., RhsElements...>>;
|
||||
using type = typename make_type_set_if<is_in_both, LhsElements...>::type;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using make_intersect_set_t = typename make_intersect_set<Lhs, Rhs>::type;
|
||||
|
||||
|
||||
template<template<typename> class Transformation, typename T>
|
||||
struct transform_set
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
|
||||
public alias_operators<exists_t<Select>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
||||
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");
|
||||
|
@ -41,10 +41,12 @@ namespace sqlpp
|
||||
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = allow_tvin_t<Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
binary_expression_t(_lhs_t lhs, _rhs_t rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
@ -55,8 +57,8 @@ namespace sqlpp
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
_lhs_t _lhs;
|
||||
_rhs_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -68,7 +70,7 @@ namespace sqlpp
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
if (rhs_is_null(t))
|
||||
{
|
||||
context << " IS NULL";
|
||||
}
|
||||
@ -86,10 +88,12 @@ namespace sqlpp
|
||||
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = allow_tvin_t<Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
binary_expression_t(Lhs lhs, _rhs_t rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
@ -100,8 +104,8 @@ namespace sqlpp
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
_lhs_t _lhs;
|
||||
_rhs_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -113,7 +117,7 @@ namespace sqlpp
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
if (rhs_is_null(t))
|
||||
{
|
||||
context << " IS NOT NULL";
|
||||
}
|
||||
@ -131,7 +135,7 @@ namespace sqlpp
|
||||
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<unary_expression_t<op::logical_not, Rhs>>,
|
||||
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
@ -155,10 +159,17 @@ namespace sqlpp
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << "NOT ";
|
||||
serialize(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Rhs>::value)
|
||||
{
|
||||
serialize(t._lhs, context);
|
||||
context << " IS NULL ";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "NOT ";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
@ -166,7 +177,7 @@ namespace sqlpp
|
||||
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
@ -204,7 +215,7 @@ namespace sqlpp
|
||||
struct unary_expression_t: public value_type_of<O>::template expression_operators<unary_expression_t<O, Rhs>>,
|
||||
public alias_operators<unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
|
@ -51,13 +51,15 @@ namespace sqlpp
|
||||
template<typename... Tables>
|
||||
struct extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::extra_tables>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_extra_tables>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||
using _provided_outer_tables = ::sqlpp::detail::type_set<>;
|
||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||
using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
|
||||
using _can_be_null = std::false_type;
|
||||
};
|
||||
|
||||
// FIXME: extra_tables must not require tables!
|
||||
@ -104,7 +106,7 @@ namespace sqlpp
|
||||
// NO EXTRA TABLES YET
|
||||
struct no_extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
77
include/sqlpp11/field_spec.h
Normal file
77
include/sqlpp11/field_spec.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, 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.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_FIELD_SPEC_H
|
||||
#define SQLPP_FIELD_SPEC_H
|
||||
|
||||
#include <sqlpp11/multi_column.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename NameType, typename ValueType, bool CanBeNull, bool NullIsTrivialValue>
|
||||
struct field_spec_t
|
||||
{
|
||||
using _traits = make_traits<ValueType, tag::is_noop,
|
||||
tag_if<tag::can_be_null, CanBeNull>,
|
||||
tag_if<tag::null_is_trivial_value, NullIsTrivialValue>
|
||||
>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _name_t = NameType;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename FieldSpecTuple>
|
||||
struct multi_field_spec_t
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Select, typename NamedExpr>
|
||||
struct make_field_spec_impl
|
||||
{
|
||||
static constexpr bool _can_be_null = can_be_null_t<NamedExpr>::value;
|
||||
static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t<required_tables_of<NamedExpr>, typename Select::_used_outer_tables>::size::value > 0;
|
||||
|
||||
using type = field_spec_t<typename NamedExpr::_name_t,
|
||||
value_type_of<NamedExpr>,
|
||||
detail::any_t<_can_be_null, _depends_on_outer_table>::value,
|
||||
null_is_trivial_value_t<NamedExpr>::value>;
|
||||
};
|
||||
|
||||
template<typename Select, typename AliasProvider, typename... NamedExprs>
|
||||
struct make_field_spec_impl<Select, multi_column_alias_t<AliasProvider, NamedExprs...>>
|
||||
{
|
||||
using type = multi_field_spec_t<AliasProvider, std::tuple<typename make_field_spec_impl<Select, NamedExprs>::type...>>;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Select, typename NamedExpr>
|
||||
using make_field_spec_t = typename detail::make_field_spec_impl<Select, NamedExpr>::type;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,7 +28,6 @@
|
||||
#define SQLPP_FLOATING_POINT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -41,7 +40,8 @@ namespace sqlpp
|
||||
// floating_point value type
|
||||
struct floating_point
|
||||
{
|
||||
using _tag = ::sqlpp::tag::floating_point;
|
||||
using _traits = make_traits<floating_point, ::sqlpp::tag::is_floating_point, ::sqlpp::tag::is_expression>;
|
||||
using _tag = ::sqlpp::tag::is_floating_point;
|
||||
using _cpp_value_type = double;
|
||||
|
||||
struct _parameter_t
|
||||
@ -95,12 +95,46 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t;
|
||||
|
||||
_result_entry_t():
|
||||
// I am SO waiting for concepts lite!
|
||||
template<typename Field, typename Enable = void>
|
||||
struct field_methods_t
|
||||
{
|
||||
static constexpr bool _null_is_trivial = true;
|
||||
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct field_methods_t<
|
||||
_result_field_t<Db, FieldSpec>,
|
||||
typename std::enable_if<enforce_null_result_treatment_t<Db>::value
|
||||
and column_spec_can_be_null_t<FieldSpec>::value
|
||||
and not null_is_trivial_value_t<FieldSpec>::value>::type>
|
||||
{
|
||||
static constexpr bool _null_is_trivial = false;
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
|
||||
{
|
||||
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
|
||||
|
||||
using _traits = make_traits<integral,
|
||||
tag_if<tag::null_is_trivial_value, _field_methods_t::_null_is_trivial>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
|
||||
};
|
||||
|
||||
_result_field_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
@ -120,33 +154,30 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
if (_is_null)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
@ -257,8 +288,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
template<typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_field_t<Db, FieldSpec>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_from>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
@ -125,7 +125,7 @@ namespace sqlpp
|
||||
|
||||
struct no_from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -56,8 +56,11 @@ namespace sqlpp
|
||||
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>,
|
||||
public alias_operators<verbatim_t<ValueType>>
|
||||
{
|
||||
using _traits = make_traits<ValueType, ::sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _traits = make_traits<ValueType, ::sqlpp::tag::is_expression>;
|
||||
struct _recursive_traits : public make_recursive_traits<>
|
||||
{
|
||||
using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null
|
||||
};
|
||||
|
||||
verbatim_t(std::string verbatim): _verbatim(verbatim) {}
|
||||
verbatim_t(const verbatim_t&) = default;
|
||||
@ -99,7 +102,7 @@ namespace sqlpp
|
||||
template<typename Container>
|
||||
struct value_list_t // to be used in .in() method
|
||||
{
|
||||
using _traits = make_traits<value_type_t<typename Container::value_type>, ::sqlpp::tag::expression>;
|
||||
using _traits = make_traits<value_type_t<typename Container::value_type>, ::sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _container_t = Container;
|
||||
|
@ -59,7 +59,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_group_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -135,7 +135,7 @@ namespace sqlpp
|
||||
// NO GROUP BY YET
|
||||
struct no_group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -58,7 +58,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::having>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_having>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -133,7 +133,7 @@ namespace sqlpp
|
||||
// NO HAVING YET
|
||||
struct no_having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -38,7 +38,7 @@ namespace sqlpp
|
||||
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
|
||||
public alias_operators<in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Args...>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
@ -42,7 +42,7 @@ namespace sqlpp
|
||||
|
||||
struct insert_t: public statement_name_t<insert_name_t>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||
using _traits = make_traits<no_value_t, tag::is_return_value>;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
|
@ -49,7 +49,7 @@ namespace sqlpp
|
||||
{
|
||||
struct type
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
};
|
||||
@ -61,7 +61,7 @@ namespace sqlpp
|
||||
using _is_insert_value = std::true_type;
|
||||
using _pure_value_t = typename value_type_of<Column>::_cpp_value_type;
|
||||
using _wrapped_value_t = typename wrap_operand<_pure_value_t>::type;
|
||||
using _tvin_t = typename detail::type_if<tvin_t<_wrapped_value_t>, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||
using _tvin_t = typename detail::type_if<tvin_arg_t<_wrapped_value_t>, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||
using _null_t = typename detail::type_if<null_t, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||
|
||||
insert_value_t(assignment_t<Column, _wrapped_value_t> assignment):
|
||||
|
@ -97,8 +97,8 @@ namespace sqlpp
|
||||
~insert_list_data_t() = default;
|
||||
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<simple_column_t<typename Assignments::_lhs_t>...> _columns;
|
||||
std::tuple<typename Assignments::_rhs_t...> _values;
|
||||
interpretable_list_t<Database> _dynamic_columns;
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
@ -106,8 +106,8 @@ namespace sqlpp
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::insert_list>;
|
||||
using _recursive_traits = make_recursive_traits<typename Assignments::_column_t..., typename Assignments::_value_t...>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_insert_list>;
|
||||
using _recursive_traits = make_recursive_traits<typename Assignments::_lhs_t..., typename Assignments::_rhs_t...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
@ -134,9 +134,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "add() arguments require to be assigments");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_column_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_column_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add() argument must not be used in insert");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_lhs_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_lhs_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_lhs_t>::value, "add() argument must not be used in insert");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
@ -150,7 +150,7 @@ namespace sqlpp
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_lhs_t>{assignment._lhs});
|
||||
_data._dynamic_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ namespace sqlpp
|
||||
template<typename... Columns>
|
||||
struct column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::column_list>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_column_list>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
||||
@ -233,7 +233,7 @@ namespace sqlpp
|
||||
void add(Assignments... assignments)
|
||||
{
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<insert_value_t<typename Assignments::_column_t>...>;
|
||||
using _arg_value_tuple = std::tuple<insert_value_t<typename Assignments::_lhs_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");
|
||||
|
||||
@ -248,7 +248,7 @@ namespace sqlpp
|
||||
template<typename... Assignments>
|
||||
void _add_impl(const std::true_type&, Assignments... assignments)
|
||||
{
|
||||
return _data._insert_values.emplace_back(insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||
return _data._insert_values.emplace_back(insert_value_t<typename Assignments::_lhs_t>{assignments}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
@ -285,7 +285,7 @@ namespace sqlpp
|
||||
// NO INSERT COLUMNS/VALUES YET
|
||||
struct no_insert_value_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
@ -359,9 +359,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
static_assert(sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_lhs_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<required_tables_of<typename Assignments::_column_t>...>::type;
|
||||
using _column_required_tables = ::sqlpp::detail::make_joined_set_t<required_tables_of<typename Assignments::_lhs_t>...>;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from several tables");
|
||||
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<Database, Assignments...>{assignments...} };
|
||||
|
@ -28,7 +28,6 @@
|
||||
#define SQLPP_INTEGRAL_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -43,8 +42,8 @@ namespace sqlpp
|
||||
// integral value type
|
||||
struct integral
|
||||
{
|
||||
using _traits = make_traits<integral, ::sqlpp::tag::expression>;
|
||||
using _tag = ::sqlpp::tag::integral;
|
||||
using _traits = make_traits<integral, ::sqlpp::tag::is_integral, ::sqlpp::tag::is_expression>;
|
||||
using _tag = ::sqlpp::tag::is_integral;
|
||||
using _cpp_value_type = int64_t;
|
||||
|
||||
struct _parameter_t
|
||||
@ -97,12 +96,46 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t;
|
||||
|
||||
_result_entry_t():
|
||||
// I am SO waiting for concepts lite!
|
||||
template<typename Field, typename Enable = void>
|
||||
struct field_methods_t
|
||||
{
|
||||
static constexpr bool _null_is_trivial = true;
|
||||
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct field_methods_t<
|
||||
_result_field_t<Db, FieldSpec>,
|
||||
typename std::enable_if<enforce_null_result_treatment_t<Db>::value
|
||||
and column_spec_can_be_null_t<FieldSpec>::value
|
||||
and not null_is_trivial_value_t<FieldSpec>::value>::type>
|
||||
{
|
||||
static constexpr bool _null_is_trivial = false;
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
|
||||
{
|
||||
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
|
||||
|
||||
using _traits = make_traits<integral,
|
||||
tag_if<tag::null_is_trivial_value, _field_methods_t::_null_is_trivial>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
|
||||
};
|
||||
|
||||
_result_field_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
@ -122,33 +155,30 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
if (_is_null)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
@ -270,8 +300,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial>
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, NullIsTrivial>& e)
|
||||
template<typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_field_t<Db, FieldSpec>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace sqlpp
|
||||
template<typename Database, typename Table>
|
||||
struct into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::into>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_into>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
@ -103,7 +103,7 @@ namespace sqlpp
|
||||
// NO INTO YET
|
||||
struct no_into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -37,7 +37,7 @@ namespace sqlpp
|
||||
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
|
||||
public alias_operators<is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
@ -35,41 +35,29 @@ namespace sqlpp
|
||||
{
|
||||
struct inner_join_t
|
||||
{
|
||||
template<typename Db>
|
||||
struct _is_supported
|
||||
{
|
||||
static constexpr bool value = Db::_supports_inner_join;
|
||||
};
|
||||
template<typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " INNER ";
|
||||
};
|
||||
struct outer_join_t
|
||||
{
|
||||
template<typename Db>
|
||||
struct _is_supported
|
||||
{
|
||||
static constexpr bool value = Db::_supports_outer_join;
|
||||
};
|
||||
template<typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " OUTER ";
|
||||
};
|
||||
struct left_outer_join_t
|
||||
{
|
||||
template<typename Db>
|
||||
struct _is_supported
|
||||
{
|
||||
static constexpr bool value = Db::_supports_left_outer_join;
|
||||
};
|
||||
template<typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " LEFT OUTER ";
|
||||
};
|
||||
struct right_outer_join_t
|
||||
{
|
||||
template<typename Db>
|
||||
struct _is_supported
|
||||
{
|
||||
static constexpr bool value = Db::_supports_right_outer_join;
|
||||
};
|
||||
template<typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " RIGHT OUTER ";
|
||||
};
|
||||
@ -77,8 +65,17 @@ namespace sqlpp
|
||||
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
||||
struct join_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::table, tag::join>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _traits = make_traits<no_value_t, tag::is_table, tag::is_join>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _required_tables = detail::make_joined_set_t<required_tables_of<Lhs>, required_tables_of<Rhs>>;
|
||||
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
using _provided_outer_tables = typename JoinType::template _provided_outer_tables<Lhs, Rhs>;
|
||||
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Lhs>, extra_tables_of<Rhs>>;
|
||||
using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
|
||||
using _can_be_null = std::false_type;
|
||||
};
|
||||
|
||||
|
||||
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
|
||||
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
|
||||
|
@ -37,7 +37,7 @@ namespace sqlpp
|
||||
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
|
||||
public alias_operators<like_t<Operand, Pattern>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Pattern>;
|
||||
|
||||
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
||||
|
@ -54,7 +54,7 @@ namespace sqlpp
|
||||
template<typename Limit>
|
||||
struct limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_limit>;
|
||||
using _recursive_traits = make_recursive_traits<Limit>;
|
||||
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
@ -123,7 +123,7 @@ namespace sqlpp
|
||||
template<typename Database>
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_limit>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
@ -172,7 +172,7 @@ namespace sqlpp
|
||||
|
||||
struct no_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
|
||||
public alias_operators<max_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "max() requires a value expression as argument");
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
|
||||
public alias_operators<min_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "min() requires a value expression as argument");
|
||||
|
@ -76,7 +76,7 @@ namespace sqlpp
|
||||
template<typename AliasProvider, typename... Columns>
|
||||
struct multi_column_alias_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::alias, tag::multi_column, tag::named_expression>;
|
||||
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_multi_column, tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
{
|
||||
struct noop
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
|
@ -33,7 +33,7 @@ namespace sqlpp
|
||||
{
|
||||
struct null_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::expression>;
|
||||
using _traits = make_traits<no_value_t, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace sqlpp
|
||||
template<typename Offset>
|
||||
struct offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_offset>;
|
||||
using _recursive_traits = make_recursive_traits<Offset>;
|
||||
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
@ -123,7 +123,7 @@ namespace sqlpp
|
||||
template<typename Database>
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_offset>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
@ -183,7 +183,7 @@ namespace sqlpp
|
||||
|
||||
struct no_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -37,7 +37,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Expr>
|
||||
struct on_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::on>;
|
||||
using _traits = make_traits<no_value_t, tag::is_on>;
|
||||
using _recursive_traits = make_recursive_traits<Expr...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
@ -59,7 +59,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_order_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -135,7 +135,7 @@ namespace sqlpp
|
||||
// NO ORDER BY YET
|
||||
struct no_order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -36,13 +36,15 @@ namespace sqlpp
|
||||
template<typename ValueType, typename NameType>
|
||||
struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using _traits = make_traits<ValueType, tag::parameter, tag::expression>;
|
||||
using _traits = make_traits<ValueType, tag::is_parameter, tag::is_expression>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<parameter_t>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
|
||||
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
||||
|
@ -42,7 +42,7 @@ namespace sqlpp
|
||||
struct remove_name_t {};
|
||||
struct remove_t: public statement_name_t<remove_name_t>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||
using _traits = make_traits<no_value_t, tag::is_return_value>;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define SQLPP_RESULT_ROW_H
|
||||
|
||||
#include <map>
|
||||
#include <sqlpp11/field.h>
|
||||
#include <sqlpp11/field_spec.h>
|
||||
#include <sqlpp11/text.h>
|
||||
#include <sqlpp11/detail/column_index_sequence.h>
|
||||
|
||||
@ -36,14 +36,14 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db, typename IndexSequence, typename... NamedExprs>
|
||||
template<typename Db, typename IndexSequence, typename... FieldSpecs>
|
||||
struct result_row_impl;
|
||||
|
||||
template<typename Db, std::size_t index, typename NamedExpr>
|
||||
template<typename Db, std::size_t index, typename FieldSpec>
|
||||
struct result_field:
|
||||
public NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>
|
||||
public FieldSpec::_name_t::template _member_t<typename value_type_of<FieldSpec>::template _result_field_t<Db, FieldSpec>>
|
||||
{
|
||||
using _field = typename NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
|
||||
using _field = typename FieldSpec::_name_t::template _member_t<typename value_type_of<FieldSpec>::template _result_field_t<Db, FieldSpec>>;
|
||||
|
||||
result_field() = default;
|
||||
|
||||
@ -64,11 +64,11 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<std::size_t index, typename AliasProvider, typename Db, typename... NamedExprs>
|
||||
struct result_field<Db, index, multi_field_t<AliasProvider, std::tuple<NamedExprs...>>>:
|
||||
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>
|
||||
template<std::size_t index, typename AliasProvider, typename Db, typename... FieldSpecs>
|
||||
struct result_field<Db, index, multi_field_spec_t<AliasProvider, std::tuple<FieldSpecs...>>>:
|
||||
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, FieldSpecs...>, FieldSpecs...>>
|
||||
{
|
||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>;
|
||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, FieldSpecs...>, FieldSpecs...>>;
|
||||
|
||||
result_field() = default;
|
||||
|
||||
@ -89,9 +89,9 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db, std::size_t LastIndex, std::size_t... Is, typename... NamedExprs>
|
||||
struct result_row_impl<Db, detail::column_index_sequence<LastIndex, Is...>, NamedExprs...>:
|
||||
public result_field<Db, Is, NamedExprs>...
|
||||
template<typename Db, std::size_t LastIndex, std::size_t... Is, typename... FieldSpecs>
|
||||
struct result_row_impl<Db, detail::column_index_sequence<LastIndex, Is...>, FieldSpecs...>:
|
||||
public result_field<Db, Is, FieldSpecs>...
|
||||
{
|
||||
static constexpr std::size_t _last_index = LastIndex;
|
||||
|
||||
@ -100,29 +100,29 @@ namespace sqlpp
|
||||
void _validate()
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(result_field<Db, Is, NamedExprs>::_validate(), 0)...};
|
||||
(void) swallow{(result_field<Db, Is, FieldSpecs>::_validate(), 0)...};
|
||||
}
|
||||
|
||||
void _invalidate()
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(result_field<Db, Is, NamedExprs>::_invalidate(), 0)...};
|
||||
(void) swallow{(result_field<Db, Is, FieldSpecs>::_invalidate(), 0)...};
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(result_field<Db, Is, NamedExprs>::_bind(target), 0)...};
|
||||
(void) swallow{(result_field<Db, Is, FieldSpecs>::_bind(target), 0)...};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename Db, typename... NamedExprs>
|
||||
struct result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
|
||||
template<typename Db, typename... FieldSpecs>
|
||||
struct result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>
|
||||
{
|
||||
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
|
||||
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>;
|
||||
bool _is_valid;
|
||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||
|
||||
@ -178,11 +178,18 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db, typename... NamedExprs>
|
||||
struct dynamic_result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
|
||||
template<typename Db, typename... FieldSpecs>
|
||||
struct dynamic_result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>
|
||||
{
|
||||
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
|
||||
using _field_type = detail::text::_result_entry_t<Db, false>;
|
||||
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>;
|
||||
struct _field_spec_t
|
||||
{
|
||||
using _traits = make_traits<detail::text, tag::is_noop, tag::can_be_null, tag::null_is_trivial_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
};
|
||||
using _field_type = detail::text::_result_field_t<Db, _field_spec_t>;
|
||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||
|
||||
bool _is_valid;
|
||||
|
@ -24,48 +24,44 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_FIELD_H
|
||||
#define SQLPP_FIELD_H
|
||||
#ifndef SQLPP_RHS_IS_NULL_H
|
||||
#define SQLPP_RHS_IS_NULL_H
|
||||
|
||||
#include <sqlpp11/multi_column.h>
|
||||
#include <sqlpp11/tvin.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
|
||||
struct field_t
|
||||
{
|
||||
using _traits = make_traits<ValueType, tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _name_t = NameType;
|
||||
static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename FieldTuple>
|
||||
struct multi_field_t
|
||||
template<typename T, typename Enable = void>
|
||||
struct is_trivial_t
|
||||
{
|
||||
static constexpr bool _(const T&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename NamedExpr>
|
||||
struct make_field_t_impl
|
||||
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)
|
||||
{
|
||||
using type = field_t<typename NamedExpr::_name_t,
|
||||
value_type_of<NamedExpr>,
|
||||
trivial_value_is_null_t<NamedExpr>::value>;
|
||||
};
|
||||
return t._is_trivial();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename... NamedExpr>
|
||||
struct make_field_t_impl<multi_column_alias_t<AliasProvider, NamedExpr...>>
|
||||
{
|
||||
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename NamedExpr>
|
||||
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
||||
template<typename T>
|
||||
bool is_trivial(const T& t)
|
||||
{
|
||||
return is_trivial_t<T>::_(t);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
constexpr bool rhs_is_null(const Expression& e)
|
||||
{
|
||||
return (((trivial_value_is_null_t<typename Expression::_lhs_t>::value or is_tvin_t<typename Expression::_rhs_t>::value)
|
||||
and is_trivial(e._rhs))
|
||||
or (std::is_same<typename Expression::_rhs_t, null_t>::value));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -31,7 +31,7 @@
|
||||
#include <sqlpp11/result_row.h>
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/field.h>
|
||||
#include <sqlpp11/field_spec.h>
|
||||
#include <sqlpp11/expression_fwd.h>
|
||||
#include <sqlpp11/select_pseudo_table.h>
|
||||
#include <sqlpp11/named_interpretable.h>
|
||||
@ -47,14 +47,14 @@ namespace sqlpp
|
||||
template<typename... Columns>
|
||||
struct select_traits
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::select_column_list, tag::return_value>;
|
||||
using _traits = make_traits<no_value_t, tag::is_select_column_list, tag::is_return_value>;
|
||||
struct _name_t {};
|
||||
};
|
||||
|
||||
template<typename Column>
|
||||
struct select_traits<Column>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Column>, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>;
|
||||
using _traits = make_traits<value_type_of<Column>, tag::is_select_column_list, tag::is_return_value, tag::is_expression, tag::is_named_expression>;
|
||||
using _name_t = typename Column::_name_t;
|
||||
};
|
||||
}
|
||||
@ -245,10 +245,19 @@ namespace sqlpp
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
template<typename Db, typename Column>
|
||||
struct _deferred_field_t
|
||||
{
|
||||
using type = make_field_spec_t<_statement_t, Column>;
|
||||
};
|
||||
|
||||
template<typename Db, typename Column>
|
||||
using _field_t = typename _deferred_field_t<Db, Column>::type;
|
||||
|
||||
template<typename Db>
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||
dynamic_result_row_t<Db, _field_t<Db, Columns>...>,
|
||||
result_row_t<Db, _field_t<Db, Columns>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
@ -317,7 +326,7 @@ namespace sqlpp
|
||||
|
||||
struct no_select_column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop, ::sqlpp::tag::is_missing>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
|
@ -59,7 +59,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::select_flag_list>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_select_flag_list>;
|
||||
using _recursive_traits = make_recursive_traits<Flags...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -134,7 +134,7 @@ namespace sqlpp
|
||||
|
||||
struct no_select_flag_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -37,7 +37,7 @@ namespace sqlpp
|
||||
// standard select flags
|
||||
struct all_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::select_flag>;
|
||||
using _traits = make_traits<no_value_t, tag::is_select_flag>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
static constexpr all_t all = {};
|
||||
@ -54,7 +54,7 @@ namespace sqlpp
|
||||
|
||||
struct distinct_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::select_flag>;
|
||||
using _traits = make_traits<no_value_t, tag::is_select_flag>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
static constexpr distinct_t distinct = {};
|
||||
@ -71,7 +71,7 @@ namespace sqlpp
|
||||
|
||||
struct straight_join_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::select_flag>;
|
||||
using _traits = make_traits<no_value_t, tag::is_select_flag>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
static constexpr straight_join_t straight_join = {};
|
||||
|
@ -32,19 +32,19 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
// provide type information for sub-selects that are used as named expressions or tables
|
||||
template<typename ValueType, typename NameType>
|
||||
template<typename Select, typename NamedExpr>
|
||||
struct select_column_spec_t
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _value_type = ValueType; // FIXME: column specs probably should use _traits, too
|
||||
using _name_t = typename NamedExpr::_name_t;
|
||||
|
||||
using _name_t = NameType;
|
||||
struct _column_type
|
||||
{
|
||||
using _must_not_insert = std::true_type;
|
||||
using _must_not_update = std::true_type;
|
||||
};
|
||||
static constexpr bool _can_be_null = can_be_null_t<NamedExpr>::value;
|
||||
static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t<required_tables_of<NamedExpr>, typename Select::_used_outer_tables>::size::value > 0;
|
||||
|
||||
using _traits = make_traits<value_type_of<NamedExpr>,
|
||||
tag::must_not_insert,
|
||||
tag::must_not_update,
|
||||
tag_if<tag::can_be_null, _can_be_null or _depends_on_outer_table>
|
||||
>;
|
||||
};
|
||||
|
||||
template<
|
||||
@ -53,9 +53,9 @@ namespace sqlpp
|
||||
>
|
||||
struct select_pseudo_table_t: public sqlpp::table_t<select_pseudo_table_t<
|
||||
Select,
|
||||
NamedExpr...>, select_column_spec_t<value_type_of<NamedExpr>, typename NamedExpr::_name_t>...>
|
||||
NamedExpr...>, select_column_spec_t<Select, NamedExpr>...>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::table, tag::pseudo_table>;
|
||||
using _traits = make_traits<no_value_t, tag::is_table, tag::is_pseudo_table>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
select_pseudo_table_t(Select select):
|
||||
|
@ -37,7 +37,7 @@ namespace sqlpp
|
||||
{
|
||||
Column _column;
|
||||
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace sqlpp
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_single_table>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
@ -103,7 +103,7 @@ namespace sqlpp
|
||||
// NO INTO YET
|
||||
struct no_single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
template<typename Select>
|
||||
struct some_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::multi_expression>;
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::is_multi_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
||||
struct _name_t
|
||||
|
@ -41,7 +41,7 @@ namespace sqlpp
|
||||
template<typename Expression, sort_type SortType>
|
||||
struct sort_order_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::sort_order, sqlpp::tag::expression>;
|
||||
using _traits = make_traits<no_value_t, tag::is_sort_order, sqlpp::tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expression>;
|
||||
|
||||
Expression _expression;
|
||||
|
@ -63,6 +63,7 @@ namespace sqlpp
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
@ -97,19 +98,21 @@ namespace sqlpp
|
||||
no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value
|
||||
>::type;
|
||||
|
||||
using _is_expression = typename std::conditional<
|
||||
std::is_same<_value_type, no_value_t>::value,
|
||||
std::false_type,
|
||||
std::true_type>::type;
|
||||
|
||||
using _traits = make_traits<_value_type>;
|
||||
using _traits = make_traits<_value_type, tag_if<tag::is_expression, not std::is_same<_value_type, no_value_t>::value>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _required_tables = statement_policies_t::_required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _parameters = detail::make_parameter_tuple_t<parameters_of<Policies>...>;
|
||||
using _can_be_null = detail::any_t<
|
||||
can_be_null_t<_result_type_provider>::value,
|
||||
::sqlpp::detail::make_intersect_set_t<
|
||||
required_tables_of<_result_type_provider>,
|
||||
provided_outer_tables_of<statement_policies_t>
|
||||
>::size::value>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -125,13 +128,16 @@ namespace sqlpp
|
||||
{
|
||||
using _policies_t = typename detail::statement_policies_t<Db, Policies...>;
|
||||
|
||||
using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>;
|
||||
using _traits = make_traits<value_type_of<_policies_t>,
|
||||
::sqlpp::tag::is_select,
|
||||
tag_if<tag::is_expression, is_expression_t<_policies_t>::value>,
|
||||
tag_if<tag::is_named_expression, is_expression_t<_policies_t>::value>,
|
||||
tag::requires_braces>;
|
||||
using _recursive_traits = typename _policies_t::_recursive_traits;
|
||||
using _used_outer_tables = typename _policies_t::_all_provided_outer_tables;
|
||||
|
||||
using _result_type_provider = typename _policies_t::_result_type_provider;
|
||||
|
||||
using _requires_braces = std::true_type;
|
||||
|
||||
using _name_t = typename _result_type_provider::_name_t;
|
||||
|
||||
// Constructors
|
||||
@ -192,7 +198,7 @@ namespace sqlpp
|
||||
template<typename NameData>
|
||||
struct statement_name_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -35,7 +35,7 @@ namespace sqlpp
|
||||
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
|
||||
public alias_operators<sum_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "sum() used with flag other than 'distinct'");
|
||||
|
@ -42,14 +42,16 @@ namespace sqlpp
|
||||
template<typename Table, typename... ColumnSpec>
|
||||
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::table>;
|
||||
using _traits = make_traits<no_value_t, tag::is_table>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _provided_tables = detail::type_set<Table>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = std::false_type;
|
||||
};
|
||||
|
||||
static_assert(sizeof...(ColumnSpec), "at least one column required per table");
|
||||
|
@ -39,14 +39,16 @@ namespace sqlpp
|
||||
struct table_alias_t: public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
//FIXME: Need to add join functionality
|
||||
using _traits = make_traits<value_type_of<Table>, tag::table, tag::alias, tag::named_expression_if<is_expression_t<Table>>>;
|
||||
using _traits = make_traits<value_type_of<Table>, tag::is_table, tag::is_alias, tag_if<tag::is_named_expression, is_expression_t<Table>::value>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _provided_tables = detail::type_set<AliasProvider>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = std::false_type;
|
||||
};
|
||||
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table aliases must not depend on external tables");
|
||||
|
@ -27,7 +27,6 @@
|
||||
#ifndef SQLPP_TEXT_H
|
||||
#define SQLPP_TEXT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
@ -41,7 +40,8 @@ namespace sqlpp
|
||||
// text value type
|
||||
struct text
|
||||
{
|
||||
using _tag = ::sqlpp::tag::text;
|
||||
using _traits = make_traits<text, ::sqlpp::tag::is_text, ::sqlpp::tag::is_expression>;
|
||||
using _tag = ::sqlpp::tag::is_text;
|
||||
using _cpp_value_type = std::string;
|
||||
|
||||
struct _parameter_t
|
||||
@ -95,10 +95,46 @@ namespace sqlpp
|
||||
bool _is_null;
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t;
|
||||
|
||||
// I am SO waiting for concepts lite!
|
||||
template<typename Field, typename Enable = void>
|
||||
struct field_methods_t
|
||||
{
|
||||
_result_entry_t():
|
||||
static constexpr bool _null_is_trivial = true;
|
||||
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct field_methods_t<
|
||||
_result_field_t<Db, FieldSpec>,
|
||||
typename std::enable_if<enforce_null_result_treatment_t<Db>::value
|
||||
and column_spec_can_be_null_t<FieldSpec>::value
|
||||
and not null_is_trivial_value_t<FieldSpec>::value>::type>
|
||||
{
|
||||
static constexpr bool _null_is_trivial = false;
|
||||
};
|
||||
|
||||
template<typename Db, typename FieldSpec>
|
||||
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
|
||||
{
|
||||
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
|
||||
|
||||
using _traits = make_traits<integral,
|
||||
tag_if<tag::null_is_trivial_value, _field_methods_t::_null_is_trivial>>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
|
||||
};
|
||||
|
||||
_result_field_t():
|
||||
_is_valid(false),
|
||||
_value_ptr(nullptr),
|
||||
_len(0)
|
||||
@ -121,35 +157,29 @@ namespace sqlpp
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _value_ptr == nullptr;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
if (_value_ptr)
|
||||
return std::string(_value_ptr, _value_ptr + _len);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
if (not _value_ptr)
|
||||
{
|
||||
if (enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
|
||||
{
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return std::string(_value_ptr, _value_ptr + _len);
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
@ -208,8 +238,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
template<typename Db, typename FieldSpec>
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_field_t<Db, FieldSpec>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
|
@ -37,16 +37,66 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Operand>
|
||||
struct tvin_t
|
||||
struct tvin_arg_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
using _operand_t = Operand;
|
||||
|
||||
tvin_t(Operand operand):
|
||||
tvin_arg_t(_operand_t operand):
|
||||
_value(operand)
|
||||
{}
|
||||
tvin_arg_t(const tvin_arg_t&) = default;
|
||||
tvin_arg_t(tvin_arg_t&&) = default;
|
||||
tvin_arg_t& operator=(const tvin_arg_t&) = default;
|
||||
tvin_arg_t& operator=(tvin_arg_t&&) = default;
|
||||
~tvin_arg_t() = default;
|
||||
|
||||
_operand_t _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, tvin_arg_t<Operand>>
|
||||
{
|
||||
using T = tvin_arg_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<Context, Operand>::value, "tvin may only be used with operators =, == and !=");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct tvin_t;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
struct allow_tvin_impl
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
template <typename T>
|
||||
struct allow_tvin_impl<tvin_arg_t<T>>
|
||||
{
|
||||
using type = tvin_t<T>;
|
||||
};
|
||||
}
|
||||
template<typename T>
|
||||
using allow_tvin_t = typename detail::allow_tvin_impl<T>::type;
|
||||
|
||||
template<typename Operand>
|
||||
struct tvin_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
using _operand_t = Operand;
|
||||
|
||||
tvin_t(tvin_arg_t<Operand> arg):
|
||||
_value(arg._value)
|
||||
{}
|
||||
tvin_t(const tvin_t&) = default;
|
||||
tvin_t(tvin_t&&) = default;
|
||||
tvin_t& operator=(const tvin_t&) = default;
|
||||
@ -58,71 +108,30 @@ namespace sqlpp
|
||||
return _value._is_trivial();
|
||||
}
|
||||
|
||||
Operand _value;
|
||||
_operand_t _value;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
struct is_tvin_impl
|
||||
{
|
||||
using type = std::false_type;
|
||||
};
|
||||
template<typename T>
|
||||
struct is_tvin_impl<tvin_t<T>>
|
||||
{
|
||||
using type = std::true_type;
|
||||
};
|
||||
}
|
||||
template<typename T>
|
||||
using is_tvin_t = typename detail::is_tvin_impl<T>::type;
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, tvin_t<Operand>>
|
||||
{
|
||||
using T = tvin_t<Operand>;
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "tvin() must not be used with anything but =, ==, != and !");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Operand>
|
||||
struct maybe_tvin_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
static constexpr bool _is_trivial()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
maybe_tvin_t(Operand operand):
|
||||
_value(operand)
|
||||
{}
|
||||
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||
~maybe_tvin_t() = default;
|
||||
|
||||
Operand _value;
|
||||
};
|
||||
|
||||
template<typename Operand>
|
||||
struct maybe_tvin_t<tvin_t<Operand>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _value._is_trivial();
|
||||
};
|
||||
|
||||
maybe_tvin_t(tvin_t<Operand> operand):
|
||||
_value(operand._value)
|
||||
{}
|
||||
maybe_tvin_t(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t(maybe_tvin_t&&) = default;
|
||||
maybe_tvin_t& operator=(const maybe_tvin_t&) = default;
|
||||
maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
|
||||
~maybe_tvin_t() = default;
|
||||
|
||||
typename tvin_t<Operand>::_operand_t _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, maybe_tvin_t<Operand>>
|
||||
{
|
||||
using T = maybe_tvin_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
@ -138,7 +147,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Operand>
|
||||
auto tvin(Operand operand) -> tvin_t<typename wrap_operand<Operand>::type>
|
||||
auto tvin(Operand operand) -> tvin_arg_t<typename wrap_operand<Operand>::type>
|
||||
{
|
||||
using _operand_t = typename wrap_operand<Operand>::type;
|
||||
static_assert(std::is_same<_operand_t, text_operand>::value
|
||||
|
@ -32,129 +32,109 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
#define SQLPP_IS_VALUE_TRAIT_GENERATOR(name) \
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, typename Enable = void>
|
||||
struct can_be_null_impl { using type = std::false_type; };
|
||||
template<typename T>
|
||||
struct can_be_null_impl<T, typename std::enable_if<T::_recursive_traits::_can_be_null::value>::type> { using type = std::true_type; };
|
||||
}
|
||||
template<typename T>
|
||||
using can_be_null_t = typename detail::can_be_null_impl<T>::type;
|
||||
|
||||
namespace tag\
|
||||
{\
|
||||
struct can_be_null{};\
|
||||
};\
|
||||
namespace detail\
|
||||
{\
|
||||
template<typename T, typename Enable = void>\
|
||||
struct is_##name##_impl: std::false_type {};\
|
||||
struct column_spec_can_be_null_impl { using type = std::false_type; };\
|
||||
template<typename T>\
|
||||
struct is_##name##_impl<T, typename std::enable_if<std::is_same<typename T::_value_type::_is_##name, std::true_type>::value>::type>: std::true_type {};\
|
||||
struct column_spec_can_be_null_impl<T, typename std::enable_if<detail::is_element_of<tag::can_be_null, typename T::_traits::_tags>::value>::type> { using type = std::true_type; };\
|
||||
}\
|
||||
template<typename T>\
|
||||
using column_spec_can_be_null_t = typename detail::column_spec_can_be_null_impl<T>::type;
|
||||
|
||||
#define SQLPP_VALUE_TRAIT_GENERATOR(name) \
|
||||
namespace tag\
|
||||
{\
|
||||
struct name{};\
|
||||
};\
|
||||
template<typename T>\
|
||||
using is_##name##_t = detail::is_element_of<tag::name, typename T::_traits::_tags>;
|
||||
|
||||
#define SQLPP_IS_COLUMN_TRAIT_GENERATOR(name) \
|
||||
namespace detail\
|
||||
{\
|
||||
template<typename T, typename Enable = void>\
|
||||
struct name##_impl { using type = std::false_type; };\
|
||||
template<typename T>\
|
||||
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_column_type::_##name, std::true_type>::value>::type> { using type = std::true_type; };\
|
||||
struct name##_impl<T, typename std::enable_if<detail::is_element_of<tag::name, typename T::_traits::_tags>::value>::type> { using type = std::true_type; };\
|
||||
}\
|
||||
template<typename T>\
|
||||
using name##_t = typename detail::name##_impl<T>::type;
|
||||
|
||||
#define SQLPP_TYPE_TRAIT_GENERATOR(name) \
|
||||
namespace detail\
|
||||
{\
|
||||
template<typename T, typename Enable = void>\
|
||||
struct name##_impl: std::false_type {};\
|
||||
template<typename T>\
|
||||
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_##name, std::true_type>::value>::type>: std::true_type {};\
|
||||
}\
|
||||
template<typename T>\
|
||||
struct name##_t: detail::name##_impl<T> {};
|
||||
|
||||
#define SQLPP_CONNECTOR_TRAIT_GENERATOR(name) \
|
||||
namespace detail\
|
||||
{\
|
||||
template<typename T, typename Enable = void>\
|
||||
struct connector_##name##_impl: std::false_type {};\
|
||||
template<typename T>\
|
||||
struct connector_##name##_impl<T, typename std::enable_if<std::is_same<typename T::_tags::_##name, std::true_type>::value>::type>: std::true_type {};\
|
||||
}\
|
||||
template<typename T>\
|
||||
struct connector_##name##_t: detail::connector_##name##_impl<T> {};
|
||||
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(boolean);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(integral);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(floating_point);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_boolean);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_integral);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_floating_point);
|
||||
template<typename T>
|
||||
using is_numeric_t = detail::any_t<
|
||||
detail::is_element_of<tag::integral, typename T::_traits::_tags>::value,
|
||||
detail::is_element_of<tag::floating_point, typename T::_traits::_tags>::value>;
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(text);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(wrapped_value);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(expression);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(named_expression);
|
||||
namespace tag
|
||||
{
|
||||
template<typename C>
|
||||
using named_expression_if = typename std::conditional<C::value, tag::named_expression, void>::type;
|
||||
}
|
||||
namespace tag
|
||||
{
|
||||
template<typename C>
|
||||
using expression_if = typename std::conditional<C::value, tag::expression, void>::type;
|
||||
}
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(multi_expression);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(alias);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_flag);
|
||||
detail::is_element_of<tag::is_integral, typename T::_traits::_tags>::value,
|
||||
detail::is_element_of<tag::is_floating_point, typename T::_traits::_tags>::value>;
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_text);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_expression);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_named_expression);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_alias);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_select_flag);
|
||||
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_insert);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(trivial_value_is_null);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(must_not_insert);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(must_not_update);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(require_insert);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(trivial_value_is_null);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(null_is_trivial_value);
|
||||
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(noop);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(missing);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(return_value);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(table);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(join);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(pseudo_table);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(column);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(select);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_flag_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_column_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(from);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(single_table);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(into);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(extra_tables);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(on);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(where);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(group_by);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(having);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(order_by);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(limit);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(offset);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(using_);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(column_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(multi_column);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(value_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(assignment);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(update_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(insert_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(insert_value);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(insert_value_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(sort_order);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(parameter);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_noop);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_missing);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_return_value);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_table);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_join);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_pseudo_table);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_column);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_select);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_select_flag_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_select_column_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_from);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_single_table);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_into);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_extra_tables);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_on);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_where);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_group_by);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_having);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_order_by);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_limit);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_offset);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_using_);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_column_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_multi_column);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_value_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_assignment);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_update_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_insert_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_insert_value);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_insert_value_list);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_sort_order);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_parameter);
|
||||
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(requires_braces);
|
||||
|
||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(null_result_is_trivial_value);
|
||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(assert_result_validity);
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(enforce_null_result_treatment);
|
||||
|
||||
template<typename Tag, bool Condition>
|
||||
using tag_if = typename std::conditional<Condition, Tag, void>::type;
|
||||
|
||||
template<typename Database>
|
||||
using is_database = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
template<typename T, template<typename> class IsTag>
|
||||
using copy_type_trait = typename std::conditional<IsTag<T>::value, std::true_type, std::false_type>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
@ -175,6 +155,12 @@ namespace sqlpp
|
||||
using type = typename T::_recursive_traits::_provided_tables;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct provided_outer_table_of_impl
|
||||
{
|
||||
using type = typename T::_recursive_traits::_provided_outer_tables;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct extra_table_of_impl
|
||||
{
|
||||
@ -211,6 +197,9 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
using provided_tables_of = typename detail::provided_table_of_impl<T>::type;
|
||||
|
||||
template<typename T>
|
||||
using provided_outer_tables_of = typename detail::provided_outer_table_of_impl<T>::type;
|
||||
|
||||
template<typename T>
|
||||
using extra_tables_of = typename detail::extra_table_of_impl<T>::type;
|
||||
|
||||
@ -231,8 +220,10 @@ namespace sqlpp
|
||||
{
|
||||
using _required_tables = detail::make_joined_set_t<required_tables_of<Arguments>...>;
|
||||
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Arguments>...>;
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Arguments>...>;
|
||||
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Arguments>...>;
|
||||
using _parameters = detail::make_parameter_tuple_t<parameters_of<Arguments>...>;
|
||||
using _can_be_null = detail::any_t<can_be_null_t<Arguments>::value...>;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ namespace sqlpp
|
||||
|
||||
struct update_t: public statement_name_t<update_name_t>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||
using _traits = make_traits<no_value_t, tag::is_return_value>;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
|
@ -56,7 +56,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::update_list>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_update_list>;
|
||||
using _recursive_traits = make_recursive_traits<Assignments...>;
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
@ -78,9 +78,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_column_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_column_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_lhs_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_lhs_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_lhs_t>::value, "add() argument must not be updated");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
@ -130,7 +130,7 @@ namespace sqlpp
|
||||
|
||||
struct no_update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
@ -192,9 +192,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_lhs_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<required_tables_of<typename Assignments::_column_t>...>::type;
|
||||
using _column_required_tables = ::sqlpp::detail::make_joined_set_t<required_tables_of<typename Assignments::_lhs_t>...>;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from more than one table");
|
||||
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<Database, Assignments...>{assignments...} };
|
||||
|
@ -57,7 +57,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::using_>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_using_>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -128,7 +128,7 @@ namespace sqlpp
|
||||
// NO USING YET
|
||||
struct no_using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -42,13 +42,17 @@ namespace sqlpp
|
||||
{
|
||||
};
|
||||
};
|
||||
using _value_type = no_value_t;
|
||||
struct _column_type {};
|
||||
using _traits = make_traits<no_value_t>;
|
||||
};
|
||||
}
|
||||
|
||||
struct verbatim_table_t: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t>
|
||||
{
|
||||
struct _recursive_traits: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t>::_recursive_traits
|
||||
{
|
||||
using _provided_outer_tables = detail::type_set<verbatim_table_t>;
|
||||
};
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
verbatim_table_t(std::string representation):
|
||||
|
@ -58,7 +58,7 @@ namespace sqlpp
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_where>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
@ -141,7 +141,7 @@ namespace sqlpp
|
||||
template<>
|
||||
struct where_t<void, bool>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
@ -184,7 +184,7 @@ namespace sqlpp
|
||||
template<bool Required>
|
||||
struct no_where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::is_where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
|
@ -43,7 +43,7 @@ namespace sqlpp
|
||||
|
||||
struct boolean_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = bool;
|
||||
@ -81,7 +81,7 @@ namespace sqlpp
|
||||
|
||||
struct integral_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = int64_t;
|
||||
@ -120,7 +120,7 @@ namespace sqlpp
|
||||
|
||||
struct floating_point_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = double;
|
||||
@ -158,7 +158,7 @@ namespace sqlpp
|
||||
|
||||
struct text_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = std::string;
|
||||
|
@ -155,22 +155,20 @@ for tableCreation in tableCreations:
|
||||
print(' };', file=header)
|
||||
print(' };', file=header)
|
||||
#print(sqlColumnType)
|
||||
print(' using _value_type = ' + NAMESPACE + '::' + types[sqlColumnType] + ';', file=header)
|
||||
print(' struct _column_type', file=header)
|
||||
print(' {', file=header)
|
||||
traitslist = [NAMESPACE + '::' + types[sqlColumnType]];
|
||||
requireInsert = True
|
||||
if column.hasAutoValue:
|
||||
print(' using _must_not_insert = std::true_type;', file=header)
|
||||
print(' using _must_not_update = std::true_type;', file=header)
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_insert');
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_update');
|
||||
requireInsert = False
|
||||
if not column.notNull:
|
||||
print(' using _can_be_null = std::true_type;', file=header)
|
||||
traitslist.append(NAMESPACE + '::tag::can_be_null');
|
||||
requireInsert = False
|
||||
if column.hasDefaultValue:
|
||||
requireInsert = False
|
||||
if requireInsert:
|
||||
print(' using _require_insert = std::true_type;', file=header)
|
||||
print(' };', file=header)
|
||||
traitslist.append(NAMESPACE + '::tag::require_insert');
|
||||
print(' using _traits = ' + NAMESPACE + '::make_traits<' + ', '.join(traitslist) + '>;', file=header)
|
||||
print(' };', file=header)
|
||||
print(' }', file=header)
|
||||
print('', file=header)
|
||||
|
@ -15,6 +15,7 @@ build_and_run(SelectTypeTest)
|
||||
build_and_run(FunctionTest)
|
||||
build_and_run(PreparedTest)
|
||||
build_and_run(Minimalistic)
|
||||
build_and_run(ResultTest)
|
||||
|
||||
# if you want to use the generator, you can do something like this:
|
||||
#find_package(PythonInterp REQUIRED)
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer;
|
||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -125,6 +124,10 @@ int main()
|
||||
|
||||
// join
|
||||
serialize(t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta), printer).str();
|
||||
{
|
||||
auto inner = t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta);
|
||||
serialize(select(t.alpha).from(inner), printer).str();
|
||||
}
|
||||
|
||||
// multi_column
|
||||
serialize(multi_column(t.alpha, (t.beta + "cake").as(t.gamma)).as(t.alpha), printer).str();
|
||||
|
@ -30,8 +30,13 @@
|
||||
#include <sqlpp11/serializer_context.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
|
||||
struct MockDb: public sqlpp::connection
|
||||
template<bool enforceNullResultTreatment>
|
||||
struct MockDbT: public sqlpp::connection
|
||||
{
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::no_value_t,
|
||||
::sqlpp::tag_if<::sqlpp::tag::enforce_null_result_treatment, enforceNullResultTreatment>
|
||||
>;
|
||||
|
||||
struct _serializer_context_t
|
||||
{
|
||||
std::ostringstream _os;
|
||||
@ -156,5 +161,8 @@ struct MockDb: public sqlpp::connection
|
||||
|
||||
};
|
||||
|
||||
using MockDb = MockDbT<false>;
|
||||
using EnforceDb = MockDbT<true>;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -21,11 +21,7 @@ namespace test
|
||||
const T& operator()() const { return delta; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::varchar;
|
||||
struct _column_type
|
||||
{
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::varchar, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct Epsilon
|
||||
{
|
||||
@ -40,11 +36,7 @@ namespace test
|
||||
const T& operator()() const { return epsilon; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::bigint;
|
||||
struct _column_type
|
||||
{
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::bigint, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct Omega
|
||||
{
|
||||
@ -59,11 +51,7 @@ namespace test
|
||||
const T& operator()() const { return omega; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::floating_point;
|
||||
struct _column_type
|
||||
{
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::floating_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
}
|
||||
|
||||
@ -100,13 +88,7 @@ namespace test
|
||||
const T& operator()() const { return alpha; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::bigint;
|
||||
struct _column_type
|
||||
{
|
||||
using _must_not_insert = std::true_type;
|
||||
using _must_not_update = std::true_type;
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::bigint, sqlpp::tag::must_not_insert, sqlpp::tag::must_not_update, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct Beta
|
||||
{
|
||||
@ -121,11 +103,7 @@ namespace test
|
||||
const T& operator()() const { return beta; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::varchar;
|
||||
struct _column_type
|
||||
{
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::varchar, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
struct Gamma
|
||||
{
|
||||
@ -140,11 +118,7 @@ namespace test
|
||||
const T& operator()() const { return gamma; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::boolean;
|
||||
struct _column_type
|
||||
{
|
||||
using _require_insert = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::boolean, sqlpp::tag::require_insert>;
|
||||
};
|
||||
struct Delta
|
||||
{
|
||||
@ -159,11 +133,7 @@ namespace test
|
||||
const T& operator()() const { return delta; }
|
||||
};
|
||||
};
|
||||
using _value_type = sqlpp::integer;
|
||||
struct _column_type
|
||||
{
|
||||
using _can_be_null = std::true_type;
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -36,14 +36,6 @@
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user