mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-10 15:11:02 -06:00
Fixed indentations
This commit is contained in:
@@ -46,20 +46,20 @@ namespace sqlpp
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
template<typename Context, typename Expression, typename AliasProvider>
|
||||
struct serializer_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||
{
|
||||
using T = expression_alias_t<Expression, AliasProvider>;
|
||||
template<typename Context, typename Expression, typename AliasProvider>
|
||||
struct serializer_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||
{
|
||||
using T = expression_alias_t<Expression, AliasProvider>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << '(';
|
||||
serialize(t._expression, context);
|
||||
context << ") AS ";
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << '(';
|
||||
serialize(t._expression, context);
|
||||
context << ") AS ";
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,20 +31,20 @@
|
||||
|
||||
#define SQLPP_ALIAS_PROVIDER(name) \
|
||||
struct name##_t\
|
||||
{\
|
||||
struct _name_t\
|
||||
{\
|
||||
struct _name_t\
|
||||
static constexpr const char* _get_name() { return #name; }\
|
||||
template<typename T>\
|
||||
struct _member_t\
|
||||
{\
|
||||
static constexpr const char* _get_name() { return #name; }\
|
||||
template<typename T>\
|
||||
struct _member_t\
|
||||
{\
|
||||
T name;\
|
||||
T& operator()() { return name; }\
|
||||
const T& operator()() const { return name; }\
|
||||
};\
|
||||
T name;\
|
||||
T& operator()() { return name; }\
|
||||
const T& operator()() const { return name; }\
|
||||
};\
|
||||
};\
|
||||
constexpr name##_t name = {};
|
||||
};\
|
||||
constexpr name##_t name = {};
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
|
||||
@@ -34,33 +34,33 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Table>
|
||||
struct all_of_t
|
||||
{
|
||||
using _column_tuple_t = typename Table::_column_tuple_t;
|
||||
struct all_of_t
|
||||
{
|
||||
using _column_tuple_t = typename Table::_column_tuple_t;
|
||||
|
||||
template<typename AliasProvider>
|
||||
detail::copy_tuple_args_t<multi_column_alias_t, AliasProvider, _column_tuple_t> as(const AliasProvider& alias)
|
||||
{
|
||||
return ::sqlpp::multi_column(_column_tuple_t{}).as(alias);
|
||||
}
|
||||
};
|
||||
template<typename AliasProvider>
|
||||
detail::copy_tuple_args_t<multi_column_alias_t, AliasProvider, _column_tuple_t> as(const AliasProvider& alias)
|
||||
{
|
||||
return ::sqlpp::multi_column(_column_tuple_t{}).as(alias);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Table>
|
||||
auto all_of(Table t) -> all_of_t<Table>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto all_of(Table t) -> all_of_t<Table>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename Context, typename Table>
|
||||
struct serializer_t<Context, all_of_t<Table>>
|
||||
template<typename Context, typename Table>
|
||||
struct serializer_t<Context, all_of_t<Table>>
|
||||
{
|
||||
using T = all_of_t<Table>;
|
||||
|
||||
static Context& _(const T& t, const Context&)
|
||||
{
|
||||
using T = all_of_t<Table>;
|
||||
|
||||
static Context& _(const T& t, const Context&)
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "all_of(table) does not seem to be used in select");
|
||||
}
|
||||
};
|
||||
static_assert(wrong_t<T>::value, "all_of(table) does not seem to be used in select");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Select>
|
||||
template<typename Select>
|
||||
struct any_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::multi_expression>;
|
||||
@@ -63,28 +63,28 @@ namespace sqlpp
|
||||
Select _select;
|
||||
};
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, any_t<Select>>
|
||||
{
|
||||
using T = any_t<Select>;
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, any_t<Select>>
|
||||
{
|
||||
using T = any_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "ANY(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto any(T t) -> typename any_t<wrap_operand_t<T>>
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(is_select_t<wrap_operand_t<T>>::value, "any() requires a select expression as argument");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "any() requires a single column select expression as argument");
|
||||
// FIXME: can we accept non-values like NULL here?
|
||||
return { t };
|
||||
context << "ANY(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto any(T t) -> typename any_t<wrap_operand_t<T>>
|
||||
{
|
||||
static_assert(is_select_t<wrap_operand_t<T>>::value, "any() requires a select expression as argument");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "any() requires a single column select expression as argument");
|
||||
// FIXME: can we accept non-values like NULL here?
|
||||
return { t };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T, typename Enable = void>
|
||||
template<typename T, typename Enable = void>
|
||||
struct is_trivial_t
|
||||
{
|
||||
static constexpr bool _(const T&)
|
||||
@@ -45,7 +45,7 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
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)
|
||||
@@ -54,108 +54,108 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
bool is_trivial(const T& t)
|
||||
{
|
||||
return is_trivial_t<T>::_(t);
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
{
|
||||
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 = 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");
|
||||
|
||||
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, Rhs>>
|
||||
{
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
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 = 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");
|
||||
|
||||
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, Rhs>>
|
||||
{
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||
and is_trivial(t._rhs))
|
||||
or (std::is_same<Rhs, null_t>::value))
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||
and is_trivial(t._rhs))
|
||||
or (std::is_same<Rhs, null_t>::value))
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
if (t._rhs._value._is_trivial())
|
||||
{
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
serialize(t._rhs._value, context);
|
||||
}
|
||||
return context;
|
||||
context << "=NULL";
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@@ -31,59 +31,59 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
template<typename Flag, typename Expr>
|
||||
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
|
||||
public alias_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 _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'");
|
||||
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::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'");
|
||||
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "AVG"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T avg;
|
||||
T& operator()() { return avg; }
|
||||
const T& operator()() const { return avg; }
|
||||
};
|
||||
};
|
||||
|
||||
avg_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
avg_t(const avg_t&) = default;
|
||||
avg_t(avg_t&&) = default;
|
||||
avg_t& operator=(const avg_t&) = default;
|
||||
avg_t& operator=(avg_t&&) = default;
|
||||
~avg_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
static constexpr const char* _get_name() { return "AVG"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T avg;
|
||||
T& operator()() { return avg; }
|
||||
const T& operator()() const { return avg; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, avg_t<Flag, Expr>>
|
||||
{
|
||||
using T = avg_t<Flag, Expr>;
|
||||
avg_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
avg_t(const avg_t&) = default;
|
||||
avg_t(avg_t&&) = default;
|
||||
avg_t& operator=(const avg_t&) = default;
|
||||
avg_t& operator=(avg_t&&) = default;
|
||||
~avg_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, avg_t<Flag, Expr>>
|
||||
{
|
||||
using T = avg_t<Flag, Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "AVG(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
context << "AVG(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
};
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto avg(T t) -> typename avg_t<noop, wrap_operand_t<T>>
|
||||
|
||||
@@ -43,13 +43,13 @@ namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
struct _is_valid_comparison_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
(is_expression_t<T>::value // expressions are OK
|
||||
or is_multi_expression_t<T>::value) // multi-expressions like ANY are OK for comparisons, too
|
||||
and IsCorrectValueType<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
{
|
||||
static constexpr bool value =
|
||||
(is_expression_t<T>::value // expressions are OK
|
||||
or is_multi_expression_t<T>::value) // multi-expressions like ANY are OK for comparisons, too
|
||||
and IsCorrectValueType<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
equal_to_t<Base, wrap_operand_t<T>> operator==(T t) const
|
||||
|
||||
@@ -52,12 +52,12 @@ namespace sqlpp
|
||||
_parameter_t():
|
||||
_value(false),
|
||||
_is_null(true)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(false)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
@@ -97,88 +97,88 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(false)
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(false)
|
||||
{}
|
||||
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? false : (data[0] == 't' or data[0] == '1'))
|
||||
{}
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? false : (data[0] == 't' or data[0] == '1'))
|
||||
{}
|
||||
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? false : (data[0] == 't' or data[0] == '1');
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_boolean_result(i, &_value, &_is_null);
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? false : (data[0] == 't' or data[0] == '1');
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
signed char _value;
|
||||
};
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_boolean_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
signed char _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _is_valid_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_boolean_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_boolean_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template<typename Base>
|
||||
struct expression_operators: public basic_expression_operators<Base, is_boolean_t>
|
||||
@@ -209,15 +209,15 @@ namespace sqlpp
|
||||
|
||||
template<typename Base>
|
||||
struct column_operators
|
||||
{
|
||||
};
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using boolean = detail::boolean;
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
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 ColumnSpec::_value_type::template expression_operators<column_t<Table, ColumnSpec>>,
|
||||
public ColumnSpec::_value_type::template column_operators<column_t<Table, ColumnSpec>>
|
||||
{
|
||||
using _traits = make_traits<typename ColumnSpec::_value_type, tag::column, tag::expression, tag::named_expression>;
|
||||
struct _recursive_traits
|
||||
@@ -103,17 +103,17 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename... Args>
|
||||
struct serializer_t<Context, column_t<Args...>>
|
||||
{
|
||||
using T = column_t<Args...>;
|
||||
template<typename Context, typename... Args>
|
||||
struct serializer_t<Context, column_t<Args...>>
|
||||
{
|
||||
using T = column_t<Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,52 +33,52 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// FIXME: Remove First, inherit from text_t
|
||||
template<typename First, typename... Args>
|
||||
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
|
||||
public alias_operators<concat_t<First, Args...>>
|
||||
// FIXME: Remove First, inherit from text_t
|
||||
template<typename First, typename... Args>
|
||||
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 _recursive_traits = make_recursive_traits<First, Args...>;
|
||||
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<First, Args...>;
|
||||
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "CONCAT"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T concat;
|
||||
};
|
||||
};
|
||||
|
||||
concat_t(First first, Args... args):
|
||||
_args(first, args...)
|
||||
{}
|
||||
|
||||
concat_t(const concat_t&) = default;
|
||||
concat_t(concat_t&&) = default;
|
||||
concat_t& operator=(const concat_t&) = default;
|
||||
concat_t& operator=(concat_t&&) = default;
|
||||
~concat_t() = default;
|
||||
|
||||
std::tuple<First, Args...> _args;
|
||||
static constexpr const char* _get_name() { return "CONCAT"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T concat;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename First, typename... Args>
|
||||
struct serializer_t<Context, concat_t<First, Args...>>
|
||||
{
|
||||
using T = concat_t<First, Args...>;
|
||||
concat_t(First first, Args... args):
|
||||
_args(first, args...)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
concat_t(const concat_t&) = default;
|
||||
concat_t(concat_t&&) = default;
|
||||
concat_t& operator=(const concat_t&) = default;
|
||||
concat_t& operator=(concat_t&&) = default;
|
||||
~concat_t() = default;
|
||||
|
||||
std::tuple<First, Args...> _args;
|
||||
};
|
||||
|
||||
template<typename Context, typename First, typename... Args>
|
||||
struct serializer_t<Context, concat_t<First, Args...>>
|
||||
{
|
||||
using T = concat_t<First, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,59 +32,59 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
template<typename Flag, typename Expr>
|
||||
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>,
|
||||
public alias_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 _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'");
|
||||
static_assert(is_expression_t<Expr>::value, "count() requires a sql expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::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'");
|
||||
static_assert(is_expression_t<Expr>::value, "count() requires a sql expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "COUNT"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T count;
|
||||
T& operator()() { return count; }
|
||||
const T& operator()() const { return count; }
|
||||
};
|
||||
};
|
||||
|
||||
count_t(const Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
count_t(const count_t&) = default;
|
||||
count_t(count_t&&) = default;
|
||||
count_t& operator=(const count_t&) = default;
|
||||
count_t& operator=(count_t&&) = default;
|
||||
~count_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
static constexpr const char* _get_name() { return "COUNT"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T count;
|
||||
T& operator()() { return count; }
|
||||
const T& operator()() const { return count; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, count_t<Flag, Expr>>
|
||||
{
|
||||
using T = count_t<Flag, Expr>;
|
||||
count_t(const Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
count_t(const count_t&) = default;
|
||||
count_t(count_t&&) = default;
|
||||
count_t& operator=(const count_t&) = default;
|
||||
count_t& operator=(count_t&&) = default;
|
||||
~count_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, count_t<Flag, Expr>>
|
||||
{
|
||||
using T = count_t<Flag, Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "COUNT(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
context << "COUNT(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
};
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto count(T t) -> typename count_t<noop, wrap_operand_t<T>>
|
||||
|
||||
@@ -39,17 +39,17 @@ namespace sqlpp
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, default_value_t>
|
||||
{
|
||||
using Operand = default_value_t;
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, default_value_t>
|
||||
{
|
||||
using Operand = default_value_t;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << "DEFAULT";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << "DEFAULT";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr default_value_t default_value = {};
|
||||
|
||||
|
||||
@@ -31,53 +31,53 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Select>
|
||||
template<typename Select>
|
||||
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
|
||||
public alias_operators<exists_t<Select>>
|
||||
public alias_operators<exists_t<Select>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
||||
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
||||
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "EXISTS"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T exists;
|
||||
T& operator()() { return exists; }
|
||||
const T& operator()() const { return exists; }
|
||||
};
|
||||
};
|
||||
|
||||
exists_t(Select select):
|
||||
_select(select)
|
||||
{}
|
||||
|
||||
exists_t(const exists_t&) = default;
|
||||
exists_t(exists_t&&) = default;
|
||||
exists_t& operator=(const exists_t&) = default;
|
||||
exists_t& operator=(exists_t&&) = default;
|
||||
~exists_t() = default;
|
||||
|
||||
Select _select;
|
||||
static constexpr const char* _get_name() { return "EXISTS"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T exists;
|
||||
T& operator()() { return exists; }
|
||||
const T& operator()() const { return exists; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, exists_t<Select>>
|
||||
{
|
||||
using T = exists_t<Select>;
|
||||
exists_t(Select select):
|
||||
_select(select)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "EXISTS(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
exists_t(const exists_t&) = default;
|
||||
exists_t(exists_t&&) = default;
|
||||
exists_t& operator=(const exists_t&) = default;
|
||||
exists_t& operator=(exists_t&&) = default;
|
||||
~exists_t() = default;
|
||||
|
||||
Select _select;
|
||||
};
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, exists_t<Select>>
|
||||
{
|
||||
using T = exists_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "EXISTS(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
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>>
|
||||
template<typename Lhs, typename Rhs>
|
||||
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 _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
@@ -59,32 +59,32 @@ namespace sqlpp
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, equal_to_t<Lhs, Rhs>>
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, equal_to_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << " IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
context << " IS NULL";
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
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>>
|
||||
template<typename Lhs, typename Rhs>
|
||||
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 _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
@@ -104,32 +104,32 @@ namespace sqlpp
|
||||
maybe_tvin_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, not_equal_to_t<Lhs, Rhs>>
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, not_equal_to_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = not_equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = not_equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << " IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
context << " IS NOT NULL";
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rhs>
|
||||
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>>
|
||||
template<typename Rhs>
|
||||
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 _recursive_traits = make_recursive_traits<Rhs>;
|
||||
@@ -147,93 +147,93 @@ namespace sqlpp
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Rhs>
|
||||
struct serializer_t<Context, logical_not_t<Rhs>>
|
||||
{
|
||||
using T = logical_not_t<Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << "NOT ";
|
||||
serialize(t._lhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
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>>
|
||||
template<typename Context, typename Rhs>
|
||||
struct serializer_t<Context, logical_not_t<Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using T = logical_not_t<Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
binary_expression_t(const binary_expression_t&) = default;
|
||||
binary_expression_t(binary_expression_t&&) = default;
|
||||
binary_expression_t& operator=(const binary_expression_t&) = default;
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << "NOT ";
|
||||
serialize(t._lhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename O, typename Rhs>
|
||||
struct serializer_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
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 _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
template<typename O, typename Rhs>
|
||||
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>>
|
||||
binary_expression_t(const binary_expression_t&) = default;
|
||||
binary_expression_t(binary_expression_t&&) = default;
|
||||
binary_expression_t& operator=(const binary_expression_t&) = default;
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename O, typename Rhs>
|
||||
struct serializer_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
unary_expression_t(const unary_expression_t&) = default;
|
||||
unary_expression_t(unary_expression_t&&) = default;
|
||||
unary_expression_t& operator=(const unary_expression_t&) = default;
|
||||
unary_expression_t& operator=(unary_expression_t&&) = default;
|
||||
~unary_expression_t() = default;
|
||||
|
||||
Rhs _rhs;
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename O, typename Rhs>
|
||||
struct serializer_t<Context, unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using T = unary_expression_t<O, Rhs>;
|
||||
template<typename O, typename Rhs>
|
||||
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 _recursive_traits = make_recursive_traits<Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
unary_expression_t(Rhs rhs):
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
unary_expression_t(const unary_expression_t&) = default;
|
||||
unary_expression_t(unary_expression_t&&) = default;
|
||||
unary_expression_t& operator=(const unary_expression_t&) = default;
|
||||
unary_expression_t& operator=(unary_expression_t&&) = default;
|
||||
~unary_expression_t() = default;
|
||||
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename O, typename Rhs>
|
||||
struct serializer_t<Context, unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using T = unary_expression_t<O, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,160 +36,160 @@ namespace sqlpp
|
||||
struct floating_point;
|
||||
}
|
||||
|
||||
namespace op
|
||||
namespace op
|
||||
{
|
||||
struct less
|
||||
{
|
||||
struct less
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = "<";
|
||||
};
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = "<";
|
||||
};
|
||||
|
||||
struct less_equal
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = "<=";
|
||||
};
|
||||
struct less_equal
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = "<=";
|
||||
};
|
||||
|
||||
struct equal_to
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
struct equal_to
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
|
||||
struct not_equal_to
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
struct not_equal_to
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
|
||||
struct greater_equal
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = ">=";
|
||||
};
|
||||
struct greater_equal
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = ">=";
|
||||
};
|
||||
|
||||
struct greater
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = ">";
|
||||
};
|
||||
struct greater
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = ">";
|
||||
};
|
||||
|
||||
struct logical_or
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = " OR ";
|
||||
};
|
||||
struct logical_or
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = " OR ";
|
||||
};
|
||||
|
||||
struct logical_and
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = " AND ";
|
||||
};
|
||||
struct logical_and
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
static constexpr const char* _name = " AND ";
|
||||
};
|
||||
|
||||
struct logical_not
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
struct logical_not
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType>
|
||||
struct plus
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType>
|
||||
struct minus
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType>
|
||||
struct multiplies
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point>;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
struct divides
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point>;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
struct modulus
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral>;
|
||||
static constexpr const char* _name = "%";
|
||||
};
|
||||
struct modulus
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral>;
|
||||
static constexpr const char* _name = "%";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType>
|
||||
struct unary_minus
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType>
|
||||
struct unary_plus
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t;
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t;
|
||||
|
||||
template<typename O, typename Rhs>
|
||||
struct unary_expression_t;
|
||||
template<typename O, typename Rhs>
|
||||
struct unary_expression_t;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using less_than_t = binary_expression_t<Lhs, op::less, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using less_than_t = binary_expression_t<Lhs, op::less, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using less_equal_t = binary_expression_t<Lhs, op::less_equal, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using less_equal_t = binary_expression_t<Lhs, op::less_equal, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using equal_to_t = binary_expression_t<Lhs, op::equal_to, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using equal_to_t = binary_expression_t<Lhs, op::equal_to, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using not_equal_to_t = binary_expression_t<Lhs, op::not_equal_to, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using not_equal_to_t = binary_expression_t<Lhs, op::not_equal_to, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_than_t = binary_expression_t<Lhs, op::greater, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_than_t = binary_expression_t<Lhs, op::greater, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_equal_t = binary_expression_t<Lhs, op::greater_equal, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_equal_t = binary_expression_t<Lhs, op::greater_equal, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_and_t = binary_expression_t<Lhs, op::logical_and, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_and_t = binary_expression_t<Lhs, op::logical_and, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_or_t = binary_expression_t<Lhs, op::logical_or, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_or_t = binary_expression_t<Lhs, op::logical_or, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using plus_t = binary_expression_t<Lhs, op::plus<ValueType>, Rhs>;
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using plus_t = binary_expression_t<Lhs, op::plus<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using minus_t = binary_expression_t<Lhs, op::minus<ValueType>, Rhs>;
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using minus_t = binary_expression_t<Lhs, op::minus<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using multiplies_t = binary_expression_t<Lhs, op::multiplies<ValueType>, Rhs>;
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using multiplies_t = binary_expression_t<Lhs, op::multiplies<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using divides_t = binary_expression_t<Lhs, op::divides, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using divides_t = binary_expression_t<Lhs, op::divides, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using modulus_t = binary_expression_t<Lhs, op::modulus, Rhs>;
|
||||
template<typename Lhs, typename Rhs>
|
||||
using modulus_t = binary_expression_t<Lhs, op::modulus, Rhs>;
|
||||
|
||||
template<typename Rhs>
|
||||
using logical_not_t = unary_expression_t<op::logical_not, Rhs>;
|
||||
template<typename Rhs>
|
||||
using logical_not_t = unary_expression_t<op::logical_not, Rhs>;
|
||||
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_plus_t = unary_expression_t<op::unary_plus<ValueType>, Rhs>;
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_plus_t = unary_expression_t<op::unary_plus<ValueType>, Rhs>;
|
||||
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_minus_t = unary_expression_t<op::unary_minus<ValueType>, Rhs>;
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_minus_t = unary_expression_t<op::unary_minus<ValueType>, Rhs>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,86 +33,46 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename... Tables>
|
||||
struct extra_tables_data_t
|
||||
{
|
||||
extra_tables_data_t()
|
||||
{}
|
||||
|
||||
extra_tables_data_t(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t(extra_tables_data_t&&) = default;
|
||||
extra_tables_data_t& operator=(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t& operator=(extra_tables_data_t&&) = default;
|
||||
~extra_tables_data_t() = default;
|
||||
|
||||
};
|
||||
|
||||
// EXTRA_TABLES
|
||||
template<typename... Tables>
|
||||
struct extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::extra_tables>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||
using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
|
||||
};
|
||||
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
// FIXME: extra_tables must not require tables!
|
||||
|
||||
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||
|
||||
// Data
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
_impl_t<Policies> extra_tables;
|
||||
_impl_t<Policies>& operator()() { return extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.extra_tables)
|
||||
{
|
||||
return t.extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO EXTRA TABLES YET
|
||||
struct no_extra_tables_t
|
||||
template<typename... Tables>
|
||||
struct extra_tables_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
extra_tables_data_t()
|
||||
{}
|
||||
|
||||
extra_tables_data_t(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t(extra_tables_data_t&&) = default;
|
||||
extra_tables_data_t& operator=(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t& operator=(extra_tables_data_t&&) = default;
|
||||
~extra_tables_data_t() = default;
|
||||
|
||||
};
|
||||
|
||||
// EXTRA_TABLES
|
||||
template<typename... Tables>
|
||||
struct extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::extra_tables>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||
using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
|
||||
};
|
||||
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
// FIXME: extra_tables must not require tables!
|
||||
|
||||
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
@@ -122,46 +82,86 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
_impl_t<Policies> no_extra_tables;
|
||||
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
||||
_impl_t<Policies> extra_tables;
|
||||
_impl_t<Policies>& operator()() { return extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
||||
static auto _get_member(T t) -> decltype(t.extra_tables)
|
||||
{
|
||||
return t.no_extra_tables;
|
||||
return t.extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_extra_tables_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto extra_tables(Args...)
|
||||
-> _new_statement_t<extra_tables_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_data_t<Args...>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = extra_tables_data_t<Database, Tables...>;
|
||||
// NO EXTRA TABLES YET
|
||||
struct no_extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_extra_tables;
|
||||
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
||||
{
|
||||
return t.no_extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_extra_tables_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto extra_tables(Args...)
|
||||
-> _new_statement_t<extra_tables_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_data_t<Args...>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = extra_tables_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,40 +31,40 @@
|
||||
|
||||
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<>;
|
||||
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;
|
||||
};
|
||||
using _name_t = NameType;
|
||||
static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename FieldTuple>
|
||||
struct multi_field_t
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
template<typename AliasProvider, typename FieldTuple>
|
||||
struct multi_field_t
|
||||
{
|
||||
template<typename NamedExpr>
|
||||
struct make_field_t_impl
|
||||
{
|
||||
using type = field_t<typename NamedExpr::_name_t,
|
||||
value_type_of<NamedExpr>,
|
||||
trivial_value_is_null_t<NamedExpr>::value>;
|
||||
};
|
||||
|
||||
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...>>;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename NamedExpr>
|
||||
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
||||
struct make_field_t_impl
|
||||
{
|
||||
using type = field_t<typename NamedExpr::_name_t,
|
||||
value_type_of<NamedExpr>,
|
||||
trivial_value_is_null_t<NamedExpr>::value>;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace sqlpp
|
||||
{
|
||||
using _tag = ::sqlpp::tag::floating_point;
|
||||
using _cpp_value_type = double;
|
||||
|
||||
|
||||
struct _parameter_t
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
@@ -51,12 +51,12 @@ namespace sqlpp
|
||||
_parameter_t():
|
||||
_value(0),
|
||||
_is_null(true)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(false)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
@@ -96,90 +96,90 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
{}
|
||||
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||
{}
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||
{}
|
||||
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_floating_point_result(i, &_value, &_is_null);
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_floating_point_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _is_valid_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_numeric_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_numeric_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template<typename Base>
|
||||
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
||||
@@ -231,50 +231,50 @@ namespace sqlpp
|
||||
|
||||
template<typename Base>
|
||||
struct column_operators
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, floating_point, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using floating_point = detail::floating_point;
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// FROM DATA
|
||||
template<typename Database, typename... Tables>
|
||||
// FROM DATA
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_data_t
|
||||
{
|
||||
from_data_t(Tables... tables):
|
||||
@@ -53,93 +53,54 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
// FROM
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||
|
||||
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
||||
|
||||
// Data
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||
#warning need to check if table is already known
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_from_t
|
||||
// FROM
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||
|
||||
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||
#warning need to check if table is already known
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -147,16 +108,16 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.no_from;
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -164,46 +125,85 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_from_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<from_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_from(Args... args)
|
||||
-> _new_statement_t<from_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = from_data_t<Database, Tables...>;
|
||||
struct no_from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " FROM ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
{
|
||||
return t.no_from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_from_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<from_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_from(Args... args)
|
||||
-> _new_statement_t<from_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = from_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " FROM ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,8 +55,8 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>,
|
||||
public alias_operators<verbatim_t<ValueType>>
|
||||
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<>;
|
||||
@@ -71,17 +71,17 @@ namespace sqlpp
|
||||
std::string _verbatim;
|
||||
};
|
||||
|
||||
template<typename Context, typename ValueType>
|
||||
struct serializer_t<Context, verbatim_t<ValueType>>
|
||||
{
|
||||
using T = verbatim_t<ValueType>;
|
||||
template<typename Context, typename ValueType>
|
||||
struct serializer_t<Context, verbatim_t<ValueType>>
|
||||
{
|
||||
using T = verbatim_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._verbatim;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._verbatim;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ValueType, typename StringType>
|
||||
auto verbatim(StringType s) -> verbatim_t<ValueType>
|
||||
@@ -119,26 +119,26 @@ namespace sqlpp
|
||||
_container_t _container;
|
||||
};
|
||||
|
||||
template<typename Context, typename Container>
|
||||
struct serializer_t<Context, value_list_t<Container>>
|
||||
template<typename Context, typename Container>
|
||||
struct serializer_t<Context, value_list_t<Container>>
|
||||
{
|
||||
using T = value_list_t<Container>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = value_list_t<Container>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
bool first = true;
|
||||
for (const auto& entry: t._container)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& entry: t._container)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
context << ',';
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
context << ',';
|
||||
|
||||
serialize(value(entry), context);
|
||||
}
|
||||
return context;
|
||||
serialize(value(entry), context);
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
auto value_list(Container c) -> value_list_t<Container>
|
||||
|
||||
@@ -37,113 +37,74 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// GROUP BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_data_t
|
||||
{
|
||||
group_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
group_by_data_t(const group_by_data_t&) = default;
|
||||
group_by_data_t(group_by_data_t&&) = default;
|
||||
group_by_data_t& operator=(const group_by_data_t&) = default;
|
||||
group_by_data_t& operator=(group_by_data_t&&) = default;
|
||||
~group_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// GROUP BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> group_by;
|
||||
_impl_t<Policies>& operator()() { return group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return group_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.group_by)
|
||||
{
|
||||
return t.group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO GROUP BY YET
|
||||
struct no_group_by_t
|
||||
// GROUP BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
group_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
group_by_data_t(const group_by_data_t&) = default;
|
||||
group_by_data_t(group_by_data_t&&) = default;
|
||||
group_by_data_t& operator=(const group_by_data_t&) = default;
|
||||
group_by_data_t& operator=(group_by_data_t&&) = default;
|
||||
~group_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// GROUP BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -151,61 +112,100 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> no_group_by;
|
||||
_impl_t<Policies>& operator()() { return no_group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
||||
_impl_t<Policies> group_by;
|
||||
_impl_t<Policies>& operator()() { return group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return group_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_group_by)
|
||||
static auto _get_member(T t) -> decltype(t.group_by)
|
||||
{
|
||||
return t.no_group_by;
|
||||
return t.group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_group_by_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto group_by(Args... args)
|
||||
-> _new_statement_t<group_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_group_by(Args... args)
|
||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = group_by_data_t<Database, Expressions...>;
|
||||
// NO GROUP BY YET
|
||||
struct no_group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " GROUP BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_group_by;
|
||||
_impl_t<Policies>& operator()() { return no_group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_group_by)
|
||||
{
|
||||
return t.no_group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_group_by_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto group_by(Args... args)
|
||||
-> _new_statement_t<group_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_group_by(Args... args)
|
||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " GROUP BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,112 +36,72 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// HAVING DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_data_t
|
||||
{
|
||||
having_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
having_data_t(const having_data_t&) = default;
|
||||
having_data_t(having_data_t&&) = default;
|
||||
having_data_t& operator=(const having_data_t&) = default;
|
||||
having_data_t& operator=(having_data_t&&) = default;
|
||||
~having_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// HAVING
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::having>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||
|
||||
// Data
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> having;
|
||||
_impl_t<Policies>& operator()() { return having; }
|
||||
const _impl_t<Policies>& operator()() const { return having; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.having)
|
||||
{
|
||||
return t.having;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO HAVING YET
|
||||
struct no_having_t
|
||||
// HAVING DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
having_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
having_data_t(const having_data_t&) = default;
|
||||
having_data_t(having_data_t&&) = default;
|
||||
having_data_t& operator=(const having_data_t&) = default;
|
||||
having_data_t& operator=(having_data_t&&) = default;
|
||||
~having_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// HAVING
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::having>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -149,61 +109,101 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> no_having;
|
||||
_impl_t<Policies>& operator()() { return no_having; }
|
||||
const _impl_t<Policies>& operator()() const { return no_having; }
|
||||
_impl_t<Policies> having;
|
||||
_impl_t<Policies>& operator()() { return having; }
|
||||
const _impl_t<Policies>& operator()() const { return having; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_having)
|
||||
static auto _get_member(T t) -> decltype(t.having)
|
||||
{
|
||||
return t.no_having;
|
||||
return t.having;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_having_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto having(Args... args)
|
||||
-> _new_statement_t<having_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_having(Args... args)
|
||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = having_data_t<Database, Expressions...>;
|
||||
// NO HAVING YET
|
||||
struct no_having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " HAVING ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_having;
|
||||
_impl_t<Policies>& operator()() { return no_having; }
|
||||
const _impl_t<Policies>& operator()() const { return no_having; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_having)
|
||||
{
|
||||
return t.no_having;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_having_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto having(Args... args)
|
||||
-> _new_statement_t<having_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_having(Args... args)
|
||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = having_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " HAVING ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,55 +34,55 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
|
||||
public alias_operators<in_t<NotInverted, Operand, Args...>>
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
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 _recursive_traits = make_recursive_traits<Operand, Args...>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Args...>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return _inverted ? "NOT IN" : "IN"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T in;
|
||||
};
|
||||
};
|
||||
|
||||
in_t(Operand operand, Args... args):
|
||||
_operand(operand),
|
||||
_args(args...)
|
||||
{}
|
||||
|
||||
in_t(const in_t&) = default;
|
||||
in_t(in_t&&) = default;
|
||||
in_t& operator=(const in_t&) = default;
|
||||
in_t& operator=(in_t&&) = default;
|
||||
~in_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
std::tuple<Args...> _args;
|
||||
static constexpr const char* _get_name() { return _inverted ? "NOT IN" : "IN"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T in;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
||||
struct serializer_t<Context, in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
using T = in_t<NotInverted, Operand, Args...>;
|
||||
in_t(Operand operand, Args... args):
|
||||
_operand(operand),
|
||||
_args(args...)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " NOT IN(" : " IN(");
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
in_t(const in_t&) = default;
|
||||
in_t(in_t&&) = default;
|
||||
in_t& operator=(const in_t&) = default;
|
||||
in_t& operator=(in_t&&) = default;
|
||||
~in_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
std::tuple<Args...> _args;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
||||
struct serializer_t<Context, in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
using T = in_t<NotInverted, Operand, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " NOT IN(" : " IN(");
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
struct in_t;
|
||||
|
||||
}
|
||||
|
||||
@@ -43,24 +43,24 @@ namespace sqlpp
|
||||
struct insert_t: public statement_name_t<insert_name_t>
|
||||
{};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_name_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_name_t>
|
||||
{
|
||||
using T = insert_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = insert_name_t;
|
||||
context << "INSERT ";
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "INSERT ";
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Database>
|
||||
using blank_insert_t = statement_t<Database,
|
||||
insert_t,
|
||||
no_into_t,
|
||||
no_insert_value_list_t>;
|
||||
insert_t,
|
||||
no_into_t,
|
||||
no_insert_value_list_t>;
|
||||
|
||||
auto insert()
|
||||
-> blank_insert_t<void>
|
||||
|
||||
@@ -36,85 +36,85 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace detail
|
||||
{
|
||||
template<typename Type, bool>
|
||||
struct type_if
|
||||
{
|
||||
using type = Type;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct type_if<Type, false>
|
||||
{
|
||||
struct type
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Column>
|
||||
struct insert_value_t
|
||||
{
|
||||
template<typename Type, bool>
|
||||
struct type_if
|
||||
{
|
||||
using type = Type;
|
||||
};
|
||||
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 _null_t = typename detail::type_if<null_t, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||
|
||||
template<typename Type>
|
||||
struct type_if<Type, false>
|
||||
{
|
||||
struct type
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
insert_value_t(assignment_t<Column, _wrapped_value_t> assignment):
|
||||
_is_null(false),
|
||||
_is_default(false),
|
||||
_value(assignment._rhs)
|
||||
{}
|
||||
|
||||
template<typename Column>
|
||||
struct insert_value_t
|
||||
insert_value_t(assignment_t<Column, _tvin_t> assignment):
|
||||
_is_null(assignment._rhs._is_trivial()),
|
||||
_is_default(false),
|
||||
_value(assignment._rhs._value)
|
||||
{}
|
||||
|
||||
insert_value_t(const assignment_t<Column, _null_t>&):
|
||||
_is_null(true),
|
||||
_is_default(false),
|
||||
_value()
|
||||
{}
|
||||
|
||||
insert_value_t(const assignment_t<Column, ::sqlpp::default_value_t>&):
|
||||
_is_null(false),
|
||||
_is_default(true),
|
||||
_value()
|
||||
{}
|
||||
|
||||
insert_value_t(const insert_value_t&) = default;
|
||||
insert_value_t(insert_value_t&&) = default;
|
||||
insert_value_t& operator=(const insert_value_t&) = default;
|
||||
insert_value_t& operator=(insert_value_t&&) = default;
|
||||
~insert_value_t() = default;
|
||||
|
||||
bool _is_null;
|
||||
bool _is_default;
|
||||
_wrapped_value_t _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename ValueType>
|
||||
struct serializer_t<Context, insert_value_t<ValueType>>
|
||||
{
|
||||
using T = insert_value_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
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 _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):
|
||||
_is_null(false),
|
||||
_is_default(false),
|
||||
_value(assignment._rhs)
|
||||
{}
|
||||
|
||||
insert_value_t(assignment_t<Column, _tvin_t> assignment):
|
||||
_is_null(assignment._rhs._is_trivial()),
|
||||
_is_default(false),
|
||||
_value(assignment._rhs._value)
|
||||
{}
|
||||
|
||||
insert_value_t(const assignment_t<Column, _null_t>&):
|
||||
_is_null(true),
|
||||
_is_default(false),
|
||||
_value()
|
||||
{}
|
||||
|
||||
insert_value_t(const assignment_t<Column, ::sqlpp::default_value_t>&):
|
||||
_is_null(false),
|
||||
_is_default(true),
|
||||
_value()
|
||||
{}
|
||||
|
||||
insert_value_t(const insert_value_t&) = default;
|
||||
insert_value_t(insert_value_t&&) = default;
|
||||
insert_value_t& operator=(const insert_value_t&) = default;
|
||||
insert_value_t& operator=(insert_value_t&&) = default;
|
||||
~insert_value_t() = default;
|
||||
|
||||
bool _is_null;
|
||||
bool _is_default;
|
||||
_wrapped_value_t _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename ValueType>
|
||||
struct serializer_t<Context, insert_value_t<ValueType>>
|
||||
{
|
||||
using T = insert_value_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._is_null)
|
||||
context << "NULL";
|
||||
else if (t._is_default)
|
||||
context << "DEFAULT";
|
||||
else
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
if (t._is_null)
|
||||
context << "NULL";
|
||||
else if (t._is_default)
|
||||
context << "DEFAULT";
|
||||
else
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,288 +37,141 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct insert_default_values_data_t
|
||||
{};
|
||||
struct insert_default_values_data_t
|
||||
{};
|
||||
|
||||
// COLUMN AND VALUE LIST
|
||||
struct insert_default_values_t
|
||||
// COLUMN AND VALUE LIST
|
||||
struct insert_default_values_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
_impl_t<Policies> default_values;
|
||||
_impl_t<Policies>& operator()() { return default_values; }
|
||||
const _impl_t<Policies>& operator()() const { return default_values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.default_values)
|
||||
{
|
||||
return t.default_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
_impl_t<Policies> default_values;
|
||||
_impl_t<Policies>& operator()() { return default_values; }
|
||||
const _impl_t<Policies>& operator()() const { return default_values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.default_values)
|
||||
{
|
||||
return t.default_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_data_t
|
||||
{
|
||||
insert_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...),
|
||||
_columns({assignments._lhs}...),
|
||||
_values(assignments._rhs...)
|
||||
{}
|
||||
|
||||
insert_list_data_t(const insert_list_data_t&) = default;
|
||||
insert_list_data_t(insert_list_data_t&&) = default;
|
||||
insert_list_data_t& operator=(const insert_list_data_t&) = default;
|
||||
insert_list_data_t& operator=(insert_list_data_t&&) = default;
|
||||
~insert_list_data_t() = default;
|
||||
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
interpretable_list_t<Database> _dynamic_columns;
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
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 _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
template<template<typename...> class Target>
|
||||
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
|
||||
template<template<typename...> class Target, template<typename> class Wrap>
|
||||
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()");
|
||||
|
||||
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()");
|
||||
|
||||
#warning: Need to reactivate these checks
|
||||
/*
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_required_tables...>::type;
|
||||
using _value_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_required_tables...>::type;
|
||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||
using _required_tables = typename ::sqlpp::detail::make_joined_set<_column_required_tables, _value_required_tables>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
// Data
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
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");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_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<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value,
|
||||
not must_not_insert_t<typename Assignment::_column_t>::value,
|
||||
(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value)>;
|
||||
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
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_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
_impl_t<Policies> insert_list;
|
||||
_impl_t<Policies>& operator()() { return insert_list; }
|
||||
const _impl_t<Policies>& operator()() const { return insert_list; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.insert_list)
|
||||
{
|
||||
return t.insert_list;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
struct column_list_data_t
|
||||
{
|
||||
column_list_data_t(Columns... columns):
|
||||
_columns(simple_column_t<Columns>{columns}...)
|
||||
insert_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...),
|
||||
_columns({assignments._lhs}...),
|
||||
_values(assignments._rhs...)
|
||||
{}
|
||||
|
||||
column_list_data_t(const column_list_data_t&) = default;
|
||||
column_list_data_t(column_list_data_t&&) = default;
|
||||
column_list_data_t& operator=(const column_list_data_t&) = default;
|
||||
column_list_data_t& operator=(column_list_data_t&&) = default;
|
||||
~column_list_data_t() = default;
|
||||
insert_list_data_t(const insert_list_data_t&) = default;
|
||||
insert_list_data_t(insert_list_data_t&&) = default;
|
||||
insert_list_data_t& operator=(const insert_list_data_t&) = default;
|
||||
insert_list_data_t& operator=(insert_list_data_t&&) = default;
|
||||
~insert_list_data_t() = default;
|
||||
|
||||
#warning need to define just one version of value_tuple_t
|
||||
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||
std::tuple<simple_column_t<Columns>...> _columns;
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
};
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
interpretable_list_t<Database> _dynamic_columns;
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
struct column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::column_list>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
||||
|
||||
static_assert(::sqlpp::detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
||||
|
||||
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||
|
||||
static_assert(required_tables_of<column_list_t>::size::value == 1, "columns from multiple tables in columns()");
|
||||
|
||||
// Data
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename... Assignments>
|
||||
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 _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||
_args_correct::value>;
|
||||
|
||||
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
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}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
void _add_impl(const std::false_type&, Assignments... assignments);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
_impl_t<Policies> values;
|
||||
_impl_t<Policies>& operator()() { return values; }
|
||||
const _impl_t<Policies>& operator()() const { return values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.values)
|
||||
{
|
||||
return t.values;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
bool empty() const
|
||||
{
|
||||
return _insert_values.empty();
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
// NO HAVING YET
|
||||
struct no_insert_value_list_t
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
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 _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
template<template<typename...> class Target>
|
||||
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
|
||||
template<template<typename...> class Target, template<typename> class Wrap>
|
||||
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()");
|
||||
|
||||
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()");
|
||||
|
||||
#warning: Need to reactivate these checks
|
||||
/*
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_required_tables...>::type;
|
||||
using _value_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_required_tables...>::type;
|
||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||
using _required_tables = typename ::sqlpp::detail::make_joined_set<_column_required_tables, _value_required_tables>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
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");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_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<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value,
|
||||
not must_not_insert_t<typename Assignment::_column_t>::value,
|
||||
(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value)>;
|
||||
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
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_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -326,124 +179,271 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
_impl_t<Policies> no_insert_values;
|
||||
_impl_t<Policies>& operator()() { return no_insert_values; }
|
||||
const _impl_t<Policies>& operator()() const { return no_insert_values; }
|
||||
_impl_t<Policies> insert_list;
|
||||
_impl_t<Policies>& operator()() { return insert_list; }
|
||||
const _impl_t<Policies>& operator()() const { return insert_list; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_insert_values)
|
||||
static auto _get_member(T t) -> decltype(t.insert_list)
|
||||
{
|
||||
return t.no_insert_values;
|
||||
return t.insert_list;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_insert_value_list_t, T>;
|
||||
|
||||
auto default_values()
|
||||
-> _new_statement_t<insert_default_values_t>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_data_t{} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<column_list_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), column_list_data_t<Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<insert_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _new_statement_t<insert_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_default_values_data_t>
|
||||
{
|
||||
using T = insert_default_values_data_t;
|
||||
template<typename... Columns>
|
||||
struct column_list_data_t
|
||||
{
|
||||
column_list_data_t(Columns... columns):
|
||||
_columns(simple_column_t<Columns>{columns}...)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
column_list_data_t(const column_list_data_t&) = default;
|
||||
column_list_data_t(column_list_data_t&&) = default;
|
||||
column_list_data_t& operator=(const column_list_data_t&) = default;
|
||||
column_list_data_t& operator=(column_list_data_t&&) = default;
|
||||
~column_list_data_t() = default;
|
||||
|
||||
#warning need to define just one version of value_tuple_t
|
||||
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||
std::tuple<simple_column_t<Columns>...> _columns;
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
struct column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::column_list>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
||||
|
||||
static_assert(::sqlpp::detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
||||
|
||||
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||
|
||||
static_assert(required_tables_of<column_list_t>::size::value == 1, "columns from multiple tables in columns()");
|
||||
|
||||
// Data
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
context << " DEFAULT VALUES";
|
||||
return context;
|
||||
}
|
||||
template<typename... Assignments>
|
||||
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 _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||
_args_correct::value>;
|
||||
|
||||
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
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}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
void _add_impl(const std::false_type&, Assignments... assignments);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
_impl_t<Policies> values;
|
||||
_impl_t<Policies>& operator()() { return values; }
|
||||
const _impl_t<Policies>& operator()() const { return values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.values)
|
||||
{
|
||||
return t.values;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
bool empty() const
|
||||
{
|
||||
return _insert_values.empty();
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
// NO HAVING YET
|
||||
struct no_insert_value_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, column_list_data_t<Columns...>>
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using T = column_list_data_t<Columns...>;
|
||||
using _data_t = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
_impl_t<Policies> no_insert_values;
|
||||
_impl_t<Policies>& operator()() { return no_insert_values; }
|
||||
const _impl_t<Policies>& operator()() const { return no_insert_values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_insert_values)
|
||||
{
|
||||
return t.no_insert_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_insert_value_list_t, T>;
|
||||
|
||||
auto default_values()
|
||||
-> _new_statement_t<insert_default_values_t>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_data_t{} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<column_list_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), column_list_data_t<Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<insert_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _new_statement_t<insert_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_default_values_data_t>
|
||||
{
|
||||
using T = insert_default_values_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " DEFAULT VALUES";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, column_list_data_t<Columns...>>
|
||||
{
|
||||
using T = column_list_data_t<Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " (";
|
||||
interpret_tuple(t._columns, ",", context);
|
||||
context << ")";
|
||||
context << " VALUES ";
|
||||
bool first = true;
|
||||
for (const auto& row : t._insert_values)
|
||||
{
|
||||
if (not first)
|
||||
context << ',';
|
||||
else
|
||||
first = false;
|
||||
context << '(';
|
||||
interpret_tuple(row, ",", context);
|
||||
context << ')';
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
||||
{
|
||||
serialize(insert_default_values_data_t(), context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context << " (";
|
||||
interpret_tuple(t._columns, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_columns, ',', context);
|
||||
context << ") VALUES(";
|
||||
interpret_tuple(t._values, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_values.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_values, ',', context);
|
||||
context << ")";
|
||||
context << " VALUES ";
|
||||
bool first = true;
|
||||
for (const auto& row : t._insert_values)
|
||||
{
|
||||
if (not first)
|
||||
context << ',';
|
||||
else
|
||||
first = false;
|
||||
context << '(';
|
||||
interpret_tuple(row, ",", context);
|
||||
context << ')';
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
||||
{
|
||||
serialize(insert_default_values_data_t(), context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context << " (";
|
||||
interpret_tuple(t._columns, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_columns, ',', context);
|
||||
context << ") VALUES(";
|
||||
interpret_tuple(t._values, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_values.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_values, ',', context);
|
||||
context << ")";
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace sqlpp
|
||||
using _traits = make_traits<integral, ::sqlpp::tag::expression>;
|
||||
using _tag = ::sqlpp::tag::integral;
|
||||
using _cpp_value_type = int64_t;
|
||||
|
||||
|
||||
struct _parameter_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
@@ -53,12 +53,12 @@ namespace sqlpp
|
||||
_parameter_t():
|
||||
_value(0),
|
||||
_is_null(true)
|
||||
{}
|
||||
{}
|
||||
|
||||
explicit _parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(false)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
@@ -97,90 +97,90 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
struct _result_entry_t
|
||||
{
|
||||
using _value_type = integral;
|
||||
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_is_null(true),
|
||||
_value(0)
|
||||
{}
|
||||
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||
{}
|
||||
_result_entry_t(const char* data, size_t):
|
||||
_is_valid(true),
|
||||
_is_null(data == nullptr),
|
||||
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||
{}
|
||||
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
void assign(const char* data, size_t)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_integral_result(i, &_value, &_is_null);
|
||||
_is_valid = true;
|
||||
_is_null = data == nullptr;
|
||||
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_is_null = true;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_integral_result(i, &_value, &_is_null);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
bool _is_null;
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _is_valid_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_numeric_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_numeric_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template<typename Base>
|
||||
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
||||
@@ -243,50 +243,50 @@ namespace sqlpp
|
||||
|
||||
template<typename Base>
|
||||
struct column_operators
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
template<typename T>
|
||||
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial>
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, NullIsTrivial>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, NullIsTrivial>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using tinyint = detail::integral;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace sqlpp
|
||||
auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const ::sqlpp::detail::index_sequence<Is...>&)
|
||||
-> Context&
|
||||
{
|
||||
// Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4.
|
||||
// Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4.
|
||||
// See for example: "http://en.cppreference.com/w/cpp/utility/integer_sequence"
|
||||
// See also: "http://stackoverflow.com/questions/6245735/pretty-print-stdtuple/6245777#6245777"
|
||||
// Beware of gcc-bug: "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253", otherwise an empty swallow struct could be used
|
||||
|
||||
@@ -35,94 +35,94 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db>
|
||||
struct interpretable_t
|
||||
template<typename Db>
|
||||
struct interpretable_t
|
||||
{
|
||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||
|
||||
template<typename T>
|
||||
interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
interpretable_t(const interpretable_t&) = default;
|
||||
interpretable_t(interpretable_t&&) = default;
|
||||
interpretable_t& operator=(const interpretable_t&) = default;
|
||||
interpretable_t& operator=(interpretable_t&&) = default;
|
||||
~interpretable_t() = default;
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
interpretable_t(const interpretable_t&) = default;
|
||||
interpretable_t(interpretable_t&&) = default;
|
||||
interpretable_t& operator=(const interpretable_t&) = default;
|
||||
interpretable_t& operator=(interpretable_t&&) = default;
|
||||
~interpretable_t() = default;
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
auto serialize(Context& context) const
|
||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
{
|
||||
return _impl->db_serialize(context);
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _impl_t: public _impl_base
|
||||
{
|
||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||
_impl_t(T t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
sqlpp::serialize(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
Db::_interpret_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, interpretable_t<Database>>
|
||||
template<typename T>
|
||||
struct _impl_t: public _impl_base
|
||||
{
|
||||
using T = interpretable_t<Database>;
|
||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||
_impl_t(T t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
t.serialize(context);
|
||||
sqlpp::serialize(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
Db::_interpret_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, interpretable_t<Database>>
|
||||
{
|
||||
using T = interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
t.serialize(context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,85 +32,85 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db>
|
||||
struct interpretable_list_t
|
||||
template<typename Db>
|
||||
struct interpretable_list_t
|
||||
{
|
||||
std::vector<interpretable_t<Db>> _serializables;
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
std::vector<interpretable_t<Db>> _serializables;
|
||||
return _serializables.size();
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _serializables.size();
|
||||
}
|
||||
bool empty() const
|
||||
{
|
||||
return _serializables.empty();
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return _serializables.empty();
|
||||
}
|
||||
|
||||
template<typename Expr>
|
||||
template<typename Expr>
|
||||
void emplace_back(Expr expr)
|
||||
{
|
||||
_serializables.emplace_back(expr);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct interpretable_list_t<void>
|
||||
template<>
|
||||
struct interpretable_list_t<void>
|
||||
{
|
||||
static constexpr std::size_t size()
|
||||
{
|
||||
static constexpr std::size_t size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr bool empty()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename List>
|
||||
struct serializable_list_interpreter_t
|
||||
{
|
||||
using T = List;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto entry : t._serializables)
|
||||
{
|
||||
if (not first)
|
||||
{
|
||||
context << separator;
|
||||
first = false;
|
||||
}
|
||||
serialize(entry, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializable_list_interpreter_t<Context, interpretable_list_t<void>>
|
||||
{
|
||||
using T = interpretable_list_t<void>;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Separator, typename Context>
|
||||
auto interpret_list(const T& t, const Separator& separator, Context& context)
|
||||
-> decltype(serializable_list_interpreter_t<Context, T>::_(t, separator, context))
|
||||
{
|
||||
return serializable_list_interpreter_t<Context, T>::_(t, separator, context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr bool empty()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename List>
|
||||
struct serializable_list_interpreter_t
|
||||
{
|
||||
using T = List;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto entry : t._serializables)
|
||||
{
|
||||
if (not first)
|
||||
{
|
||||
context << separator;
|
||||
first = false;
|
||||
}
|
||||
serialize(entry, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializable_list_interpreter_t<Context, interpretable_list_t<void>>
|
||||
{
|
||||
using T = interpretable_list_t<void>;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Separator, typename Context>
|
||||
auto interpret_list(const T& t, const Separator& separator, Context& context)
|
||||
-> decltype(serializable_list_interpreter_t<Context, T>::_(t, separator, context))
|
||||
{
|
||||
return serializable_list_interpreter_t<Context, T>::_(t, separator, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Context, typename T, typename Enable = void>
|
||||
struct interpreter_t
|
||||
template<typename Context, typename T, typename Enable = void>
|
||||
struct interpreter_t
|
||||
{
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<Context, T>::value, "missing interpreter specialization");
|
||||
}
|
||||
};
|
||||
static_assert(wrong_t<Context, T>::value, "missing interpreter specialization");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,110 +34,39 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct into_data_t
|
||||
{
|
||||
into_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
into_data_t(const into_data_t&) = default;
|
||||
into_data_t(into_data_t&&) = default;
|
||||
into_data_t& operator=(const into_data_t&) = default;
|
||||
into_data_t& operator=(into_data_t&&) = default;
|
||||
~into_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::into, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> into;
|
||||
_impl_t<Policies>& operator()() { return into; }
|
||||
const _impl_t<Policies>& operator()() const { return into; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.into)
|
||||
{
|
||||
return t.into;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// NO INTO YET
|
||||
struct no_into_t
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct into_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
into_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
into_data_t(const into_data_t&) = default;
|
||||
into_data_t(into_data_t&&) = default;
|
||||
into_data_t& operator=(const into_data_t&) = default;
|
||||
into_data_t& operator=(into_data_t&&) = default;
|
||||
~into_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::into, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
@@ -147,49 +76,120 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> no_into;
|
||||
_impl_t<Policies>& operator()() { return no_into; }
|
||||
const _impl_t<Policies>& operator()() const { return no_into; }
|
||||
_impl_t<Policies> into;
|
||||
_impl_t<Policies>& operator()() { return into; }
|
||||
const _impl_t<Policies>& operator()() const { return into; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_into)
|
||||
static auto _get_member(T t) -> decltype(t.into)
|
||||
{
|
||||
return t.no_into;
|
||||
return t.into;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_into_t, T>;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
auto into(Args... args)
|
||||
-> _new_statement_t<into_t<void, Args...>>
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), into_data_t<void, Args...>{args...} };
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, into_data_t<Database, Table>>
|
||||
{
|
||||
using T = into_data_t<Database, Table>;
|
||||
// NO INTO YET
|
||||
struct no_into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " INTO ";
|
||||
serialize(t._table, context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_into;
|
||||
_impl_t<Policies>& operator()() { return no_into; }
|
||||
const _impl_t<Policies>& operator()() const { return no_into; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_into)
|
||||
{
|
||||
return t.no_into;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_into_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto into(Args... args)
|
||||
-> _new_statement_t<into_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), into_data_t<void, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, into_data_t<Database, Table>>
|
||||
{
|
||||
using T = into_data_t<Database, Table>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " INTO ";
|
||||
serialize(t._table, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,55 +33,55 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
|
||||
public alias_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 _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return _inverted ? "IS NOT NULL" : "IS NULL"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T in;
|
||||
};
|
||||
};
|
||||
|
||||
is_null_t(Operand operand):
|
||||
_operand(operand)
|
||||
{}
|
||||
|
||||
is_null_t(const is_null_t&) = default;
|
||||
is_null_t(is_null_t&&) = default;
|
||||
is_null_t& operator=(const is_null_t&) = default;
|
||||
is_null_t& operator=(is_null_t&&) = default;
|
||||
~is_null_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand>
|
||||
struct serializer_t<Context, ::sqlpp::is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using T = ::sqlpp::is_null_t<NotInverted, Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return _inverted ? "IS NOT NULL" : "IS NULL"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
|
||||
return context;
|
||||
}
|
||||
};
|
||||
T in;
|
||||
};
|
||||
};
|
||||
|
||||
is_null_t(Operand operand):
|
||||
_operand(operand)
|
||||
{}
|
||||
|
||||
is_null_t(const is_null_t&) = default;
|
||||
is_null_t(is_null_t&&) = default;
|
||||
is_null_t& operator=(const is_null_t&) = default;
|
||||
is_null_t& operator=(is_null_t&&) = default;
|
||||
~is_null_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand>
|
||||
struct serializer_t<Context, ::sqlpp::is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using T = ::sqlpp::is_null_t<NotInverted, Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,22 +143,22 @@ namespace sqlpp
|
||||
On _on;
|
||||
};
|
||||
|
||||
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||
struct serializer_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||
{
|
||||
using T = join_t<JoinType, Lhs, Rhs, On>;
|
||||
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||
struct serializer_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||
{
|
||||
using T = join_t<JoinType, Lhs, Rhs, On>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "joined tables require on()");
|
||||
serialize(t._lhs, context);
|
||||
context << JoinType::_name;
|
||||
context << " JOIN ";
|
||||
serialize(t._rhs, context);
|
||||
serialize(t._on, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "joined tables require on()");
|
||||
serialize(t._lhs, context);
|
||||
context << JoinType::_name;
|
||||
context << " JOIN ";
|
||||
serialize(t._rhs, context);
|
||||
serialize(t._on, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,55 +33,55 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Operand, typename Pattern>
|
||||
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
|
||||
public alias_operators<like_t<Operand, Pattern>>
|
||||
template<typename Operand, typename Pattern>
|
||||
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 _recursive_traits = make_recursive_traits<Operand, Pattern>;
|
||||
|
||||
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::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");
|
||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "LIKE"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T like;
|
||||
};
|
||||
};
|
||||
|
||||
like_t(Operand operand, Pattern pattern):
|
||||
_operand(operand),
|
||||
_pattern(pattern)
|
||||
{}
|
||||
|
||||
like_t(const like_t&) = default;
|
||||
like_t(like_t&&) = default;
|
||||
like_t& operator=(const like_t&) = default;
|
||||
like_t& operator=(like_t&&) = default;
|
||||
~like_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
Pattern _pattern;
|
||||
static constexpr const char* _get_name() { return "LIKE"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T like;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand, typename Pattern>
|
||||
struct serializer_t<Context, like_t<Operand, Pattern>>
|
||||
{
|
||||
using T = like_t<Operand, Pattern>;
|
||||
like_t(Operand operand, Pattern pattern):
|
||||
_operand(operand),
|
||||
_pattern(pattern)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << " LIKE(";
|
||||
serialize(t._pattern, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
like_t(const like_t&) = default;
|
||||
like_t(like_t&&) = default;
|
||||
like_t& operator=(const like_t&) = default;
|
||||
like_t& operator=(like_t&&) = default;
|
||||
~like_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
Pattern _pattern;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand, typename Pattern>
|
||||
struct serializer_t<Context, like_t<Operand, Pattern>>
|
||||
{
|
||||
using T = like_t<Operand, Pattern>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << " LIKE(";
|
||||
serialize(t._pattern, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,151 +33,37 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// LIMIT DATA
|
||||
template<typename Limit>
|
||||
struct limit_data_t
|
||||
{
|
||||
limit_data_t(Limit value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
limit_data_t(const limit_data_t&) = default;
|
||||
limit_data_t(limit_data_t&&) = default;
|
||||
limit_data_t& operator=(const limit_data_t&) = default;
|
||||
limit_data_t& operator=(limit_data_t&&) = default;
|
||||
~limit_data_t() = default;
|
||||
|
||||
Limit _value;
|
||||
};
|
||||
|
||||
// LIMIT
|
||||
template<typename Limit>
|
||||
struct limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _recursive_traits = make_recursive_traits<Limit>;
|
||||
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
|
||||
// Data
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// DYNAMIC LIMIT DATA
|
||||
template<typename Database>
|
||||
struct dynamic_limit_data_t
|
||||
{
|
||||
dynamic_limit_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Limit>
|
||||
dynamic_limit_data_t(Limit value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Limit>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
||||
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
||||
~dynamic_limit_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC LIMIT
|
||||
template<typename Database>
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Limit>
|
||||
void set(Limit value)
|
||||
{
|
||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Limit>::type;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_limit_t
|
||||
// LIMIT DATA
|
||||
template<typename Limit>
|
||||
struct limit_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
limit_data_t(Limit value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
limit_data_t(const limit_data_t&) = default;
|
||||
limit_data_t(limit_data_t&&) = default;
|
||||
limit_data_t& operator=(const limit_data_t&) = default;
|
||||
limit_data_t& operator=(limit_data_t&&) = default;
|
||||
~limit_data_t() = default;
|
||||
|
||||
Limit _value;
|
||||
};
|
||||
|
||||
// LIMIT
|
||||
template<typename Limit>
|
||||
struct limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _recursive_traits = make_recursive_traits<Limit>;
|
||||
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
@@ -187,71 +73,185 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
_impl_t<Policies> no_limit;
|
||||
_impl_t<Policies>& operator()() { return no_limit; }
|
||||
const _impl_t<Policies>& operator()() const { return no_limit; }
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_limit)
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.no_limit;
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_limit_t, T>;
|
||||
|
||||
template<typename Arg>
|
||||
auto limit(Arg arg)
|
||||
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_limit()
|
||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||
// DYNAMIC LIMIT DATA
|
||||
template<typename Database>
|
||||
struct dynamic_limit_data_t
|
||||
{
|
||||
dynamic_limit_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
using T = dynamic_limit_data_t<Database>;
|
||||
}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
template<typename Limit>
|
||||
dynamic_limit_data_t(Limit value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Limit>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
||||
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
||||
~dynamic_limit_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC LIMIT
|
||||
template<typename Database>
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
if (t._initialized)
|
||||
{
|
||||
context << " LIMIT ";
|
||||
serialize(t._value, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
template<typename Limit>
|
||||
void set(Limit value)
|
||||
{
|
||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Limit>::type;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
template<typename Context, typename Limit>
|
||||
struct serializer_t<Context, limit_data_t<Limit>>
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using T = limit_data_t<Limit>;
|
||||
using _data_t = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
_impl_t<Policies> no_limit;
|
||||
_impl_t<Policies>& operator()() { return no_limit; }
|
||||
const _impl_t<Policies>& operator()() const { return no_limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_limit)
|
||||
{
|
||||
return t.no_limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_limit_t, T>;
|
||||
|
||||
template<typename Arg>
|
||||
auto limit(Arg arg)
|
||||
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_limit()
|
||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||
{
|
||||
using T = dynamic_limit_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._initialized)
|
||||
{
|
||||
context << " LIMIT ";
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Limit>
|
||||
struct serializer_t<Context, limit_data_t<Limit>>
|
||||
{
|
||||
using T = limit_data_t<Limit>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " LIMIT ";
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,53 +31,53 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Expr>
|
||||
template<typename Expr>
|
||||
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
|
||||
public alias_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 _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "max() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "max() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "MAX"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T max;
|
||||
T& operator()() { return max; }
|
||||
const T& operator()() const { return max; }
|
||||
};
|
||||
};
|
||||
|
||||
max_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
max_t(const max_t&) = default;
|
||||
max_t(max_t&&) = default;
|
||||
max_t& operator=(const max_t&) = default;
|
||||
max_t& operator=(max_t&&) = default;
|
||||
~max_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
static constexpr const char* _get_name() { return "MAX"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T max;
|
||||
T& operator()() { return max; }
|
||||
const T& operator()() const { return max; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, max_t<Expr>>
|
||||
{
|
||||
using T = max_t<Expr>;
|
||||
max_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MAX(";
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
max_t(const max_t&) = default;
|
||||
max_t(max_t&&) = default;
|
||||
max_t& operator=(const max_t&) = default;
|
||||
max_t& operator=(max_t&&) = default;
|
||||
~max_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, max_t<Expr>>
|
||||
{
|
||||
using T = max_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MAX(";
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto max(T t) -> typename max_t<wrap_operand_t<T>>
|
||||
|
||||
@@ -31,53 +31,53 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Expr>
|
||||
template<typename Expr>
|
||||
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
|
||||
public alias_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 _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "min() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
||||
static_assert(is_expression_t<Expr>::value, "min() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "MIN"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T min;
|
||||
T& operator()() { return min; }
|
||||
const T& operator()() const { return min; }
|
||||
};
|
||||
};
|
||||
|
||||
min_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
min_t(const min_t&) = default;
|
||||
min_t(min_t&&) = default;
|
||||
min_t& operator=(const min_t&) = default;
|
||||
min_t& operator=(min_t&&) = default;
|
||||
~min_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
static constexpr const char* _get_name() { return "MIN"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T min;
|
||||
T& operator()() { return min; }
|
||||
const T& operator()() const { return min; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, min_t<Expr>>
|
||||
{
|
||||
using T = min_t<Expr>;
|
||||
min_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MIN(";
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
min_t(const min_t&) = default;
|
||||
min_t(min_t&&) = default;
|
||||
min_t& operator=(const min_t&) = default;
|
||||
min_t& operator=(min_t&&) = default;
|
||||
~min_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, min_t<Expr>>
|
||||
{
|
||||
using T = min_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MIN(";
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto min(T t) -> typename min_t<wrap_operand_t<T>>
|
||||
|
||||
@@ -110,28 +110,28 @@ namespace sqlpp
|
||||
std::tuple<Columns...> _columns;
|
||||
};
|
||||
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_t<void, Columns...>>
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_t<void, Columns...>>
|
||||
{
|
||||
using T = multi_column_t<void, Columns...>;
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
using T = multi_column_t<void, Columns...>;
|
||||
static_assert(wrong_t<Columns...>::value, "multi_column must be used with an alias");
|
||||
}
|
||||
};
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<Columns...>::value, "multi_column must be used with an alias");
|
||||
}
|
||||
};
|
||||
template<typename Context, typename AliasProvider, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_alias_t<AliasProvider, Columns...>>
|
||||
{
|
||||
using T = multi_column_alias_t<AliasProvider, Columns...>;
|
||||
|
||||
template<typename Context, typename AliasProvider, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_alias_t<AliasProvider, Columns...>>
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = multi_column_alias_t<AliasProvider, Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -33,104 +33,104 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db>
|
||||
struct named_interpretable_t
|
||||
template<typename Db>
|
||||
struct named_interpretable_t
|
||||
{
|
||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||
|
||||
template<typename T>
|
||||
named_interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
named_interpretable_t(const named_interpretable_t&) = default;
|
||||
named_interpretable_t(named_interpretable_t&&) = default;
|
||||
named_interpretable_t& operator=(const named_interpretable_t&) = default;
|
||||
named_interpretable_t& operator=(named_interpretable_t&&) = default;
|
||||
~named_interpretable_t() = default;
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
named_interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
named_interpretable_t(const named_interpretable_t&) = default;
|
||||
named_interpretable_t(named_interpretable_t&&) = default;
|
||||
named_interpretable_t& operator=(const named_interpretable_t&) = default;
|
||||
named_interpretable_t& operator=(named_interpretable_t&&) = default;
|
||||
~named_interpretable_t() = default;
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
return _impl->serialize(context);
|
||||
}
|
||||
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||
template<typename Context>
|
||||
auto serialize(Context& context) const
|
||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||
{
|
||||
return _impl->db_serialize(context);
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
std::string _get_name() const
|
||||
{
|
||||
_impl->_get_name();
|
||||
}
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
virtual std::string _get_name() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _impl_t: public _impl_base
|
||||
{
|
||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||
_impl_t(T t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
sqlpp::serialize(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
Db::_interpret_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
std::string _get_name() const
|
||||
{
|
||||
_impl->_get_name();
|
||||
return T::_name_t::_get_name();
|
||||
}
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||
virtual std::string _get_name() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _impl_t: public _impl_base
|
||||
{
|
||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||
_impl_t(T t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||
{
|
||||
sqlpp::serialize(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||
{
|
||||
Db::_serialize_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||
{
|
||||
Db::_interpret_interpretable(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
std::string _get_name() const
|
||||
{
|
||||
return T::_name_t::_get_name();
|
||||
}
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, named_interpretable_t<Database>>
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, named_interpretable_t<Database>>
|
||||
{
|
||||
using T = named_interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = named_interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
t.serialize(context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
t.serialize(context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,44 +34,44 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
#warning: Need extra include file for no_data
|
||||
struct no_data_t {};
|
||||
struct no_data_t {};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_data_t>
|
||||
{
|
||||
using T = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct noop
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_data_t>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using T = no_data_t;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, noop>
|
||||
struct noop
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, noop>
|
||||
{
|
||||
using T = noop;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = noop;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_noop: std::is_same<T, noop> {};
|
||||
template<typename T>
|
||||
struct is_noop: std::is_same<T, noop> {};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct noop;
|
||||
struct noop;
|
||||
|
||||
template<typename T>
|
||||
struct is_noop;
|
||||
template<typename T>
|
||||
struct is_noop;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -37,17 +37,17 @@ namespace sqlpp
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, null_t>
|
||||
{
|
||||
using Operand = null_t;
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, null_t>
|
||||
{
|
||||
using Operand = null_t;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << "NULL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << "NULL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr null_t null = {};
|
||||
|
||||
|
||||
@@ -33,161 +33,37 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// OFFSET DATA
|
||||
template<typename Offset>
|
||||
struct offset_data_t
|
||||
{
|
||||
offset_data_t(Offset value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
offset_data_t(const offset_data_t&) = default;
|
||||
offset_data_t(offset_data_t&&) = default;
|
||||
offset_data_t& operator=(const offset_data_t&) = default;
|
||||
offset_data_t& operator=(offset_data_t&&) = default;
|
||||
~offset_data_t() = default;
|
||||
|
||||
Offset _value;
|
||||
};
|
||||
|
||||
// OFFSET
|
||||
template<typename Offset>
|
||||
struct offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _recursive_traits = make_recursive_traits<Offset>;
|
||||
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
|
||||
// Data
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// DYNAMIC OFFSET DATA
|
||||
template<typename Database>
|
||||
struct dynamic_offset_data_t
|
||||
{
|
||||
dynamic_offset_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Offset>
|
||||
dynamic_offset_data_t(Offset value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Offset>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
||||
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
||||
~dynamic_offset_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC OFFSET
|
||||
template<typename Database>
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Offset>
|
||||
void set(Offset value)
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Offset>::type;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
template<typename Offset>
|
||||
void set_offset(Offset value)
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Offset>::type;
|
||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._value = arg_t{value};
|
||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._initialized = true;
|
||||
}
|
||||
};
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
struct no_offset_t
|
||||
// OFFSET DATA
|
||||
template<typename Offset>
|
||||
struct offset_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
offset_data_t(Offset value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
offset_data_t(const offset_data_t&) = default;
|
||||
offset_data_t(offset_data_t&&) = default;
|
||||
offset_data_t& operator=(const offset_data_t&) = default;
|
||||
offset_data_t& operator=(offset_data_t&&) = default;
|
||||
~offset_data_t() = default;
|
||||
|
||||
Offset _value;
|
||||
};
|
||||
|
||||
// OFFSET
|
||||
template<typename Offset>
|
||||
struct offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _recursive_traits = make_recursive_traits<Offset>;
|
||||
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
@@ -197,71 +73,195 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
_impl_t<Policies> no_offset;
|
||||
_impl_t<Policies>& operator()() { return no_offset; }
|
||||
const _impl_t<Policies>& operator()() const { return no_offset; }
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_offset)
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.no_offset;
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_offset_t, T>;
|
||||
|
||||
template<typename Arg>
|
||||
auto offset(Arg arg)
|
||||
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_offset()
|
||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Offset>
|
||||
struct serializer_t<Context, offset_data_t<Offset>>
|
||||
// DYNAMIC OFFSET DATA
|
||||
template<typename Database>
|
||||
struct dynamic_offset_data_t
|
||||
{
|
||||
dynamic_offset_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
using T = offset_data_t<Offset>;
|
||||
}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
template<typename Offset>
|
||||
dynamic_offset_data_t(Offset value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Offset>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
||||
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
||||
~dynamic_offset_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC OFFSET
|
||||
template<typename Database>
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Offset>
|
||||
void set(Offset value)
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Offset>::type;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
template<typename Offset>
|
||||
void set_offset(Offset value)
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Offset>::type;
|
||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._value = arg_t{value};
|
||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._initialized = true;
|
||||
}
|
||||
};
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
struct no_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_offset;
|
||||
_impl_t<Policies>& operator()() { return no_offset; }
|
||||
const _impl_t<Policies>& operator()() const { return no_offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_offset)
|
||||
{
|
||||
return t.no_offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_offset_t, T>;
|
||||
|
||||
template<typename Arg>
|
||||
auto offset(Arg arg)
|
||||
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_offset()
|
||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Offset>
|
||||
struct serializer_t<Context, offset_data_t<Offset>>
|
||||
{
|
||||
using T = offset_data_t<Offset>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " OFFSET ";
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
||||
{
|
||||
using T = dynamic_offset_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._initialized)
|
||||
{
|
||||
context << " OFFSET ";
|
||||
serialize(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
||||
{
|
||||
using T = dynamic_offset_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._initialized)
|
||||
{
|
||||
context << " OFFSET ";
|
||||
serialize(t._value, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,23 +56,23 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct serializer_t<Context, on_t<Database, Expr...>>
|
||||
{
|
||||
using T = on_t<Database, Expr...>;
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct serializer_t<Context, on_t<Database, Expr...>>
|
||||
{
|
||||
using T = on_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ON ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
}
|
||||
};
|
||||
context << " ON ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,113 +37,74 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// ORDER BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_data_t
|
||||
{
|
||||
order_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
order_by_data_t(const order_by_data_t&) = default;
|
||||
order_by_data_t(order_by_data_t&&) = default;
|
||||
order_by_data_t& operator=(const order_by_data_t&) = default;
|
||||
order_by_data_t& operator=(order_by_data_t&&) = default;
|
||||
~order_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// ORDER BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> order_by;
|
||||
_impl_t<Policies>& operator()() { return order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return order_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.order_by)
|
||||
{
|
||||
return t.order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO ORDER BY YET
|
||||
struct no_order_by_t
|
||||
// ORDER BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
order_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
order_by_data_t(const order_by_data_t&) = default;
|
||||
order_by_data_t(order_by_data_t&&) = default;
|
||||
order_by_data_t& operator=(const order_by_data_t&) = default;
|
||||
order_by_data_t& operator=(order_by_data_t&&) = default;
|
||||
~order_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// ORDER BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -151,61 +112,100 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> no_order_by;
|
||||
_impl_t<Policies>& operator()() { return no_order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
||||
_impl_t<Policies> order_by;
|
||||
_impl_t<Policies>& operator()() { return order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return order_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_order_by)
|
||||
static auto _get_member(T t) -> decltype(t.order_by)
|
||||
{
|
||||
return t.no_order_by;
|
||||
return t.order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_order_by_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto order_by(Args... args)
|
||||
-> _new_statement_t<order_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_order_by(Args... args)
|
||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = order_by_data_t<Database, Expressions...>;
|
||||
// NO ORDER BY YET
|
||||
struct no_order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ORDER BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_order_by;
|
||||
_impl_t<Policies>& operator()() { return no_order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_order_by)
|
||||
{
|
||||
return t.no_order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_order_by_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto order_by(Args... args)
|
||||
-> _new_statement_t<order_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_order_by(Args... args)
|
||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ORDER BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename ValueType, typename NameType>
|
||||
struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>>
|
||||
struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using _traits = make_traits<ValueType, tag::parameter, tag::expression>;
|
||||
struct _recursive_traits
|
||||
@@ -57,17 +57,17 @@ namespace sqlpp
|
||||
~parameter_t() = default;
|
||||
};
|
||||
|
||||
template<typename Context, typename ValueType, typename NameType>
|
||||
struct serializer_t<Context, parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using T = parameter_t<ValueType, NameType>;
|
||||
template<typename Context, typename ValueType, typename NameType>
|
||||
struct serializer_t<Context, parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using T = parameter_t<ValueType, NameType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "?";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "?";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename NamedExpr>
|
||||
auto parameter(const NamedExpr&)
|
||||
|
||||
@@ -31,24 +31,24 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Needle, typename Replacement>
|
||||
struct policy_update_impl
|
||||
{
|
||||
template<typename T>
|
||||
using _policy_t = typename std::conditional<std::is_same<Needle, T>::value, Replacement, T>::type;
|
||||
};
|
||||
template<typename Needle, typename Replacement>
|
||||
struct policy_update_impl
|
||||
{
|
||||
template<typename T>
|
||||
using _policy_t = typename std::conditional<std::is_same<Needle, T>::value, Replacement, T>::type;
|
||||
};
|
||||
|
||||
template<typename T, typename Needle, typename Replacement>
|
||||
using policy_update_t = typename policy_update_impl<Needle, Replacement>::template _policy_t<T>;
|
||||
template<typename T, typename Needle, typename Replacement>
|
||||
using policy_update_t = typename policy_update_impl<Needle, Replacement>::template _policy_t<T>;
|
||||
|
||||
template<typename Original, typename Needle, typename Replacement>
|
||||
struct update_policies_impl
|
||||
{
|
||||
using type = typename Original::template _policy_update_t<Needle, Replacement>;
|
||||
};
|
||||
template<typename Original, typename Needle, typename Replacement>
|
||||
struct update_policies_impl
|
||||
{
|
||||
using type = typename Original::template _policy_update_t<Needle, Replacement>;
|
||||
};
|
||||
|
||||
template<typename Original, typename Needle, typename Replacement>
|
||||
using update_policies_t = typename update_policies_impl<Original, Needle, Replacement>::type;
|
||||
template<typename Original, typename Needle, typename Replacement>
|
||||
using update_policies_t = typename update_policies_impl<Original, Needle, Replacement>::type;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace sqlpp
|
||||
|
||||
auto _run(Db& db) const
|
||||
-> size_t
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
|
||||
void _bind_params() const
|
||||
{
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace sqlpp
|
||||
|
||||
auto _run(Db& db) const
|
||||
-> size_t
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
|
||||
void _bind_params() const
|
||||
{
|
||||
|
||||
@@ -42,9 +42,9 @@ namespace sqlpp
|
||||
|
||||
auto _run(Database& db) const
|
||||
-> result_t<decltype(db.run_prepared_select(*this)), _result_row_t>
|
||||
{
|
||||
return {db.run_prepared_select(*this), _dynamic_names};
|
||||
}
|
||||
{
|
||||
return {db.run_prepared_select(*this), _dynamic_names};
|
||||
}
|
||||
|
||||
void _bind_params() const
|
||||
{
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace sqlpp
|
||||
|
||||
auto _run(Db& db) const
|
||||
-> size_t
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
{
|
||||
return db.run_prepared_insert(*this);
|
||||
}
|
||||
|
||||
void _bind_params() const
|
||||
{
|
||||
|
||||
@@ -79,26 +79,26 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, remove_name_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, remove_name_t>
|
||||
{
|
||||
using T = remove_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = remove_name_t;
|
||||
context << "DELETE";
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "DELETE";
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Database>
|
||||
using blank_remove_t = statement_t<Database,
|
||||
remove_t,
|
||||
no_from_t,
|
||||
no_using_t,
|
||||
no_extra_tables_t,
|
||||
no_where_t>;
|
||||
remove_t,
|
||||
no_from_t,
|
||||
no_using_t,
|
||||
no_extra_tables_t,
|
||||
no_where_t>;
|
||||
|
||||
auto remove()
|
||||
-> blank_remove_t<void>
|
||||
|
||||
@@ -45,12 +45,12 @@ namespace sqlpp
|
||||
result_t() = default;
|
||||
|
||||
template<typename DynamicNames>
|
||||
result_t(db_result_t&& result, const DynamicNames& dynamic_names):
|
||||
_result(std::move(result)),
|
||||
_result_row(dynamic_names)
|
||||
{
|
||||
_result.next(_result_row);
|
||||
}
|
||||
result_t(db_result_t&& result, const DynamicNames& dynamic_names):
|
||||
_result(std::move(result)),
|
||||
_result_row(dynamic_names)
|
||||
{
|
||||
_result.next(_result_row);
|
||||
}
|
||||
|
||||
result_t(const result_t&) = delete;
|
||||
result_t(result_t&&) = default;
|
||||
|
||||
@@ -43,48 +43,48 @@ namespace sqlpp
|
||||
template<typename Db, std::size_t index, typename NamedExpr>
|
||||
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>>
|
||||
{
|
||||
using _field = typename NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
|
||||
|
||||
result_field() = default;
|
||||
result_field(const char_result_row_t& char_result_row_t):
|
||||
_field({{char_result_row_t.data[index], char_result_row_t.len[index]}})
|
||||
{
|
||||
}
|
||||
|
||||
result_field& operator=(const char_result_row_t& char_result_row_t)
|
||||
{
|
||||
using _field = typename NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
|
||||
_field::operator()().assign(char_result_row_t.data[index], char_result_row_t.len[index]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
result_field() = default;
|
||||
result_field(const char_result_row_t& char_result_row_t):
|
||||
_field({{char_result_row_t.data[index], char_result_row_t.len[index]}})
|
||||
{
|
||||
}
|
||||
void validate()
|
||||
{
|
||||
_field::operator()().validate();
|
||||
}
|
||||
|
||||
result_field& operator=(const char_result_row_t& char_result_row_t)
|
||||
{
|
||||
_field::operator()().assign(char_result_row_t.data[index], char_result_row_t.len[index]);
|
||||
return *this;
|
||||
}
|
||||
void invalidate()
|
||||
{
|
||||
_field::operator()().invalidate();
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_field::operator()().validate();
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_field::operator()().invalidate();
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
template<typename Target>
|
||||
void _bind(Target& target)
|
||||
{
|
||||
_field::operator()()._bind(target, index);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
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...>>
|
||||
public 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, NamedExprs...>, NamedExprs...>>;
|
||||
|
||||
result_field() = default;
|
||||
result_field(const char_result_row_t& char_result_row_t):
|
||||
_multi_field({char_result_row_t})
|
||||
{}
|
||||
{}
|
||||
|
||||
result_field& operator=(const char_result_row_t& char_result_row_t)
|
||||
{
|
||||
@@ -103,15 +103,15 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target)
|
||||
{
|
||||
_multi_field::operator()()._bind(target);
|
||||
}
|
||||
void _bind(Target& target)
|
||||
{
|
||||
_multi_field::operator()()._bind(target);
|
||||
}
|
||||
};
|
||||
|
||||
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>...
|
||||
public result_field<Db, Is, NamedExprs>...
|
||||
{
|
||||
static constexpr std::size_t _last_index = LastIndex;
|
||||
result_row_impl() = default;
|
||||
@@ -140,17 +140,17 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(result_field<Db, Is, NamedExprs>::_bind(target), 0)...};
|
||||
}
|
||||
void _bind(Target& target)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(result_field<Db, Is, NamedExprs>::_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...>
|
||||
struct result_row_t: public 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, NamedExprs...>, NamedExprs...>;
|
||||
bool _is_valid;
|
||||
@@ -163,9 +163,9 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename DynamicNames>
|
||||
result_row_t(const DynamicNames&):
|
||||
_impl(),
|
||||
_is_valid(false)
|
||||
result_row_t(const DynamicNames&):
|
||||
_impl(),
|
||||
_is_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ 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...>
|
||||
struct dynamic_result_row_t: public 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, NamedExprs...>, NamedExprs...>;
|
||||
using _field_type = detail::text::_result_entry_t<Db, false>;
|
||||
|
||||
@@ -51,32 +51,32 @@ namespace sqlpp
|
||||
struct select_t: public statement_name_t<select_name_t>
|
||||
{};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, select_name_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, select_name_t>
|
||||
{
|
||||
using T = select_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = select_name_t;
|
||||
context << "SELECT ";
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SELECT ";
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Database>
|
||||
using blank_select_t = statement_t<Database,
|
||||
select_t,
|
||||
no_select_flag_list_t,
|
||||
no_select_column_list_t,
|
||||
no_from_t,
|
||||
no_extra_tables_t,
|
||||
no_where_t,
|
||||
no_group_by_t,
|
||||
no_having_t,
|
||||
no_order_by_t,
|
||||
no_limit_t,
|
||||
no_offset_t>;
|
||||
select_t,
|
||||
no_select_flag_list_t,
|
||||
no_select_column_list_t,
|
||||
no_from_t,
|
||||
no_extra_tables_t,
|
||||
no_where_t,
|
||||
no_group_by_t,
|
||||
no_having_t,
|
||||
no_order_by_t,
|
||||
no_limit_t,
|
||||
no_offset_t>;
|
||||
|
||||
|
||||
blank_select_t<void> select() // FIXME: These should be constexpr
|
||||
|
||||
@@ -59,256 +59,256 @@ namespace sqlpp
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
struct dynamic_select_column_list
|
||||
{
|
||||
using _names_t = std::vector<std::string>;
|
||||
std::vector<named_interpretable_t<Db>> _dynamic_columns;
|
||||
_names_t _dynamic_expression_names;
|
||||
template<typename Db>
|
||||
struct dynamic_select_column_list
|
||||
{
|
||||
using _names_t = std::vector<std::string>;
|
||||
std::vector<named_interpretable_t<Db>> _dynamic_columns;
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
template<typename Expr>
|
||||
void emplace_back(Expr expr)
|
||||
{
|
||||
_dynamic_expression_names.push_back(Expr::_name_t::_get_name());
|
||||
_dynamic_columns.emplace_back(expr);
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
template<typename Expr>
|
||||
void emplace_back(Expr expr)
|
||||
{
|
||||
return _dynamic_columns.empty();
|
||||
_dynamic_expression_names.push_back(Expr::_name_t::_get_name());
|
||||
_dynamic_columns.emplace_back(expr);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct dynamic_select_column_list<void>
|
||||
bool empty() const
|
||||
{
|
||||
struct _names_t
|
||||
return _dynamic_columns.empty();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct dynamic_select_column_list<void>
|
||||
{
|
||||
struct _names_t
|
||||
{
|
||||
static constexpr size_t size() { return 0; }
|
||||
};
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
static constexpr bool empty()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Db>
|
||||
struct serializer_t<Context, dynamic_select_column_list<Db>>
|
||||
{
|
||||
using T = dynamic_select_column_list<Db>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto column : t._dynamic_columns)
|
||||
{
|
||||
static constexpr size_t size() { return 0; }
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
context << ',';
|
||||
serialize(column, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, dynamic_select_column_list<void>>
|
||||
{
|
||||
using T = dynamic_select_column_list<void>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
// SELECTED COLUMNS DATA
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_data_t
|
||||
{
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
select_column_list_data_t(Columns... columns):
|
||||
_columns(columns...)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t(select_column_list_data_t&&) = default;
|
||||
select_column_list_data_t& operator=(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t& operator=(select_column_list_data_t&&) = default;
|
||||
~select_column_list_data_t() = default;
|
||||
|
||||
std::tuple<Columns...> _columns;
|
||||
dynamic_select_column_list<Database> _dynamic_columns;
|
||||
};
|
||||
|
||||
|
||||
// SELECTED COLUMNS
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_t
|
||||
{
|
||||
using _traits = typename ::sqlpp::detail::select_traits<Columns...>::_traits;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
using _name_t = typename ::sqlpp::detail::select_traits<Columns...>::_name_t;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<(is_named_expression_t<Columns>::value or is_multi_column_t<Columns>::value)...>::value, "at least one argument is not a named expression");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
struct _column_type {};
|
||||
|
||||
// Data
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename NamedExpression>
|
||||
void add_ntc(NamedExpression namedExpression)
|
||||
{
|
||||
add<NamedExpression, std::false_type>(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression, typename TableCheckRequired = std::true_type>
|
||||
void add(NamedExpression namedExpression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
|
||||
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in selected_columns::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in selected_columns::add()");
|
||||
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
|
||||
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
_is_dynamic::value,
|
||||
is_named_expression_t<NamedExpression>::value
|
||||
>;
|
||||
|
||||
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
//private:
|
||||
template<typename NamedExpression>
|
||||
void _add_impl(NamedExpression namedExpression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_columns.emplace_back(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression>
|
||||
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
static constexpr bool empty()
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
template<typename Context, typename Db>
|
||||
struct serializer_t<Context, dynamic_select_column_list<Db>>
|
||||
{
|
||||
using T = dynamic_select_column_list<Db>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto column : t._dynamic_columns)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
context << ',';
|
||||
serialize(column, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, dynamic_select_column_list<void>>
|
||||
{
|
||||
using T = dynamic_select_column_list<void>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
// SELECTED COLUMNS DATA
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_data_t
|
||||
{
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
select_column_list_data_t(Columns... columns):
|
||||
_columns(columns...)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t(select_column_list_data_t&&) = default;
|
||||
select_column_list_data_t& operator=(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t& operator=(select_column_list_data_t&&) = default;
|
||||
~select_column_list_data_t() = default;
|
||||
|
||||
std::tuple<Columns...> _columns;
|
||||
dynamic_select_column_list<Database> _dynamic_columns;
|
||||
};
|
||||
|
||||
|
||||
// SELECTED COLUMNS
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_t
|
||||
{
|
||||
using _traits = typename ::sqlpp::detail::select_traits<Columns...>::_traits;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
using _name_t = typename ::sqlpp::detail::select_traits<Columns...>::_name_t;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<(is_named_expression_t<Columns>::value or is_multi_column_t<Columns>::value)...>::value, "at least one argument is not a named expression");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
struct _column_type {};
|
||||
|
||||
// Data
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename NamedExpression>
|
||||
void add_ntc(NamedExpression namedExpression)
|
||||
{
|
||||
add<NamedExpression, std::false_type>(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression, typename TableCheckRequired = std::true_type>
|
||||
void add(NamedExpression namedExpression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
|
||||
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in selected_columns::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in selected_columns::add()");
|
||||
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
|
||||
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
_is_dynamic::value,
|
||||
is_named_expression_t<NamedExpression>::value
|
||||
>;
|
||||
|
||||
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
//private:
|
||||
template<typename NamedExpression>
|
||||
void _add_impl(NamedExpression namedExpression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_columns.emplace_back(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression>
|
||||
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
_impl_t<Policies> selected_columns;
|
||||
_impl_t<Policies>& operator()() { return selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return selected_columns; }
|
||||
_impl_t<Policies> selected_columns;
|
||||
_impl_t<Policies>& operator()() { return selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return selected_columns; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.selected_columns)
|
||||
{
|
||||
return t.selected_columns;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
// Result methods
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
};
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
// Result methods
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
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;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct _deferred_table_t
|
||||
{
|
||||
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _table_t = typename _deferred_table_t<AliasProvider>::table;
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = typename _deferred_table_t<AliasProvider>::alias;
|
||||
|
||||
template<typename AliasProvider>
|
||||
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
|
||||
{
|
||||
static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables");
|
||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
||||
}
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return sizeof...(Columns) + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
_statement_t::_check_consistency();
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
||||
return {db.select(_get_statement()), get_dynamic_names()};
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct _deferred_table_t
|
||||
{
|
||||
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _table_t = typename _deferred_table_t<AliasProvider>::table;
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = typename _deferred_table_t<AliasProvider>::alias;
|
||||
|
||||
template<typename AliasProvider>
|
||||
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
|
||||
{
|
||||
static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables");
|
||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
||||
}
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return sizeof...(Columns) + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
||||
return {db.select(_get_statement()), get_dynamic_names()};
|
||||
}
|
||||
#if 0
|
||||
|
||||
// Prepare
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_select_t<Db, select_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
// Prepare
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_select_t<Db, select_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -318,84 +318,84 @@ namespace sqlpp
|
||||
decltype(std::tuple_cat(as_tuple<Columns>::_(std::declval<Columns>())...))>;
|
||||
}
|
||||
|
||||
struct no_select_column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
struct no_select_column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
struct _name_t {};
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_selected_columns;
|
||||
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_selected_columns)
|
||||
{
|
||||
return t.no_selected_columns;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_column_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<void, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_columns(Args... args)
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Columns>
|
||||
struct serializer_t<Context, select_column_list_data_t<Database, Columns...>>
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
using T = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
// check for at least one expression
|
||||
static_assert(T::_is_dynamic::value or sizeof...(Columns), "at least one select expression required");
|
||||
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
||||
context << ',';
|
||||
serialize(t._dynamic_columns, context);
|
||||
return context;
|
||||
}
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_selected_columns;
|
||||
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_selected_columns)
|
||||
{
|
||||
return t.no_selected_columns;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_column_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<void, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_columns(Args... args)
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Columns>
|
||||
struct serializer_t<Context, select_column_list_data_t<Database, Columns...>>
|
||||
{
|
||||
using T = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
// check for at least one expression
|
||||
static_assert(T::_is_dynamic::value or sizeof...(Columns), "at least one select expression required");
|
||||
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
||||
context << ',';
|
||||
serialize(t._dynamic_columns, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,112 +36,72 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// SELECTED FLAGS DATA
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_data_t
|
||||
{
|
||||
select_flag_list_data_t(Flags... flags):
|
||||
_flags(flags...)
|
||||
{}
|
||||
|
||||
select_flag_list_data_t(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t(select_flag_list_data_t&&) = default;
|
||||
select_flag_list_data_t& operator=(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t& operator=(select_flag_list_data_t&&) = default;
|
||||
~select_flag_list_data_t() = default;
|
||||
|
||||
std::tuple<Flags...> _flags;
|
||||
interpretable_list_t<Database> _dynamic_flags;
|
||||
};
|
||||
|
||||
// SELECT FLAGS
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::select_flag_list>;
|
||||
using _recursive_traits = make_recursive_traits<Flags...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
|
||||
|
||||
// Data
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Flag>
|
||||
void add_ntc(Flag flag)
|
||||
{
|
||||
add<Flag, std::false_type>(flag);
|
||||
}
|
||||
|
||||
template<typename Flag, typename TableCheckRequired = std::true_type>
|
||||
void add(Flag flag)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
|
||||
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in select_flags::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
|
||||
|
||||
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Flag>
|
||||
void _add_impl(Flag flag, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_flags.emplace_back(flag);
|
||||
}
|
||||
|
||||
template<typename Flag>
|
||||
void _add_impl(Flag flag, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
_impl_t<Policies> select_flags;
|
||||
_impl_t<Policies>& operator()() { return select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return select_flags; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.select_flags)
|
||||
{
|
||||
return t.select_flags;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct no_select_flag_list_t
|
||||
// SELECTED FLAGS DATA
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
select_flag_list_data_t(Flags... flags):
|
||||
_flags(flags...)
|
||||
{}
|
||||
|
||||
select_flag_list_data_t(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t(select_flag_list_data_t&&) = default;
|
||||
select_flag_list_data_t& operator=(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t& operator=(select_flag_list_data_t&&) = default;
|
||||
~select_flag_list_data_t() = default;
|
||||
|
||||
std::tuple<Flags...> _flags;
|
||||
interpretable_list_t<Database> _dynamic_flags;
|
||||
};
|
||||
|
||||
// SELECT FLAGS
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::select_flag_list>;
|
||||
using _recursive_traits = make_recursive_traits<Flags...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Flag>
|
||||
void add_ntc(Flag flag)
|
||||
{
|
||||
add<Flag, std::false_type>(flag);
|
||||
}
|
||||
|
||||
template<typename Flag, typename TableCheckRequired = std::true_type>
|
||||
void add(Flag flag)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
|
||||
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in select_flags::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
|
||||
|
||||
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Flag>
|
||||
void _add_impl(Flag flag, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_flags.emplace_back(flag);
|
||||
}
|
||||
|
||||
template<typename Flag>
|
||||
void _add_impl(Flag flag, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -149,62 +109,102 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
_impl_t<Policies> no_select_flags;
|
||||
_impl_t<Policies>& operator()() { return no_select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return no_select_flags; }
|
||||
_impl_t<Policies> select_flags;
|
||||
_impl_t<Policies>& operator()() { return select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return select_flags; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_select_flags)
|
||||
static auto _get_member(T t) -> decltype(t.select_flags)
|
||||
{
|
||||
return t.no_select_flags;
|
||||
return t.select_flags;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_flag_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto flags(Args... args)
|
||||
-> _new_statement_t<select_flag_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_flags(Args... args)
|
||||
-> _new_statement_t<select_flag_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct no_select_flag_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Flags>
|
||||
struct serializer_t<Context, select_flag_list_data_t<Database, Flags...>>
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
using T = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._flags, ' ', context);
|
||||
if (sizeof...(Flags))
|
||||
context << ' ';
|
||||
interpret_list(t._dynamic_flags, ',', context);
|
||||
if (not t._dynamic_flags.empty())
|
||||
context << ' ';
|
||||
return context;
|
||||
}
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_select_flags;
|
||||
_impl_t<Policies>& operator()() { return no_select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return no_select_flags; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_select_flags)
|
||||
{
|
||||
return t.no_select_flags;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_flag_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto flags(Args... args)
|
||||
-> _new_statement_t<select_flag_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_flags(Args... args)
|
||||
-> _new_statement_t<select_flag_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Flags>
|
||||
struct serializer_t<Context, select_flag_list_data_t<Database, Flags...>>
|
||||
{
|
||||
using T = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._flags, ' ', context);
|
||||
if (sizeof...(Flags))
|
||||
context << ' ';
|
||||
interpret_list(t._dynamic_flags, ',', context);
|
||||
if (not t._dynamic_flags.empty())
|
||||
context << ' ';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -42,15 +42,15 @@ namespace sqlpp
|
||||
};
|
||||
static constexpr all_t all = {};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, all_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, all_t>
|
||||
{
|
||||
static Context& _(const all_t&, Context& context)
|
||||
{
|
||||
static Context& _(const all_t&, Context& context)
|
||||
{
|
||||
context << "ALL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
context << "ALL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct distinct_t
|
||||
{
|
||||
@@ -59,15 +59,15 @@ namespace sqlpp
|
||||
};
|
||||
static constexpr distinct_t distinct = {};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, distinct_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, distinct_t>
|
||||
{
|
||||
static Context& _(const distinct_t&, Context& context)
|
||||
{
|
||||
static Context& _(const distinct_t&, Context& context)
|
||||
{
|
||||
context << "DISTINCT";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
context << "DISTINCT";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct straight_join_t
|
||||
{
|
||||
@@ -76,15 +76,15 @@ namespace sqlpp
|
||||
};
|
||||
static constexpr straight_join_t straight_join = {};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, straight_join_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, straight_join_t>
|
||||
{
|
||||
static Context& _(const straight_join_t&, Context& context)
|
||||
{
|
||||
static Context& _(const straight_join_t&, Context& context)
|
||||
{
|
||||
context << "STRAIGHT_JOIN";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
context << "STRAIGHT_JOIN";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -42,13 +42,13 @@ namespace sqlpp
|
||||
using _name_t = typename Expr::_name_t;
|
||||
struct _column_type
|
||||
{
|
||||
using _must_not_insert = std::true_type;
|
||||
using _must_not_update = std::true_type;
|
||||
using _must_not_insert = std::true_type;
|
||||
using _must_not_update = std::true_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<
|
||||
typename Select,
|
||||
typename Select,
|
||||
typename... NamedExpr
|
||||
>
|
||||
struct select_pseudo_table_t: public sqlpp::table_t<select_pseudo_table_t<
|
||||
@@ -72,17 +72,17 @@ namespace sqlpp
|
||||
Select _select;
|
||||
};
|
||||
|
||||
template<typename Context, typename Select, typename... NamedExpr>
|
||||
struct serializer_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
||||
{
|
||||
using T = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
template<typename Context, typename Select, typename... NamedExpr>
|
||||
struct serializer_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
||||
{
|
||||
using T = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._select, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._select, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename T, typename Context>
|
||||
auto serialize(const T& t, Context& context)
|
||||
-> decltype(serializer_t<Context, T>::_(t, context))
|
||||
{
|
||||
return serializer_t<Context, T>::_(t, context);
|
||||
}
|
||||
*/
|
||||
template<typename T, typename Context>
|
||||
auto serialize(const T& t, Context& context)
|
||||
-> decltype(serializer_t<Context, T>::_(t, context))
|
||||
{
|
||||
return serializer_t<Context, T>::_(t, context);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Context, typename T, typename Enable = void>
|
||||
struct serializer_t
|
||||
template<typename Context, typename T, typename Enable = void>
|
||||
struct serializer_t
|
||||
{
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<Context, T>::value, "missing serializer specialization");
|
||||
}
|
||||
};
|
||||
static_assert(wrong_t<Context, T>::value, "missing serializer specialization");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,29 +31,29 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Column>
|
||||
struct simple_column_t
|
||||
{
|
||||
Column _column;
|
||||
};
|
||||
template<typename Column>
|
||||
struct simple_column_t
|
||||
{
|
||||
Column _column;
|
||||
};
|
||||
|
||||
template<typename Context, typename Column>
|
||||
struct serializer_t<Context, simple_column_t<Column>>
|
||||
{
|
||||
using T = simple_column_t<Column>;
|
||||
template<typename Context, typename Column>
|
||||
struct serializer_t<Context, simple_column_t<Column>>
|
||||
{
|
||||
using T = simple_column_t<Column>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._column._get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Column>
|
||||
simple_column_t<Column> simple_column(Column c)
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return {c};
|
||||
context << t._column._get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Column>
|
||||
simple_column_t<Column> simple_column(Column c)
|
||||
{
|
||||
return {c};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,129 +34,39 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_data_t
|
||||
{
|
||||
single_table_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
single_table_data_t(const single_table_data_t&) = default;
|
||||
single_table_data_t(single_table_data_t&&) = default;
|
||||
single_table_data_t& operator=(const single_table_data_t&) = default;
|
||||
single_table_data_t& operator=(single_table_data_t&&) = default;
|
||||
~single_table_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
// FIXME: Read up on what is allowed/prohibited in INSERT
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// NO INTO YET
|
||||
struct no_single_table_t
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
single_table_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
single_table_data_t(const single_table_data_t&) = default;
|
||||
single_table_data_t(single_table_data_t&&) = default;
|
||||
single_table_data_t& operator=(const single_table_data_t&) = default;
|
||||
single_table_data_t& operator=(single_table_data_t&&) = default;
|
||||
~single_table_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
@@ -166,49 +76,139 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.no_from;
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_single_table_t, T>;
|
||||
};
|
||||
|
||||
#warning: remove can operate on several tables at once, so it should not use single_table anyway
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<single_table_t<void, Args...>>
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
// FIXME: Read up on what is allowed/prohibited in INSERT
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_data_t<void, Args...>{args...} };
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, single_table_data_t<Database, Table>>
|
||||
{
|
||||
using T = single_table_data_t<Database, Table>;
|
||||
// NO INTO YET
|
||||
struct no_single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._table, context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
{
|
||||
return t.no_from;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_single_table_t, T>;
|
||||
|
||||
#warning: remove can operate on several tables at once, so it should not use single_table anyway
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<single_table_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_data_t<void, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, single_table_data_t<Database, Table>>
|
||||
{
|
||||
using T = single_table_data_t<Database, Table>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._table, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Select>
|
||||
template<typename Select>
|
||||
struct some_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Select>, ::sqlpp::tag::multi_expression>;
|
||||
@@ -63,19 +63,19 @@ namespace sqlpp
|
||||
Select _select;
|
||||
};
|
||||
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, some_t<Select>>
|
||||
{
|
||||
using T = some_t<Select>;
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, some_t<Select>>
|
||||
{
|
||||
using T = some_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SOME(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SOME(";
|
||||
serialize(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto some(T t) -> typename some_t<wrap_operand_t<T>>
|
||||
|
||||
@@ -46,26 +46,26 @@ namespace sqlpp
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
template<typename Context, typename Expression, sort_type SortType>
|
||||
struct serializer_t<Context, sort_order_t<Expression, SortType>>
|
||||
{
|
||||
using T = sort_order_t<Expression, SortType>;
|
||||
template<typename Context, typename Expression, sort_type SortType>
|
||||
struct serializer_t<Context, sort_order_t<Expression, SortType>>
|
||||
{
|
||||
using T = sort_order_t<Expression, SortType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._expression, context);
|
||||
switch(SortType)
|
||||
{
|
||||
serialize(t._expression, context);
|
||||
switch(SortType)
|
||||
{
|
||||
case sort_type::asc:
|
||||
context << " ASC";
|
||||
break;
|
||||
default:
|
||||
context << " DESC";
|
||||
break;
|
||||
}
|
||||
return context;
|
||||
case sort_type::asc:
|
||||
context << " ASC";
|
||||
break;
|
||||
default:
|
||||
context << " DESC";
|
||||
break;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace sqlpp
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
>;
|
||||
|
||||
using _result_type_provider = detail::get_last_if<is_return_value_t, noop, Policies...>;
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace sqlpp
|
||||
is_select_column_list_t<_result_type_provider>::value and _required_tables::size::value == 0,
|
||||
std::true_type,
|
||||
std::false_type
|
||||
>::type;
|
||||
>::type;
|
||||
|
||||
using _value_type = typename std::conditional<
|
||||
detail::none_t<is_missing_t<Policies>::value...>::value,
|
||||
@@ -121,82 +121,82 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Db,
|
||||
typename... Policies
|
||||
>
|
||||
struct statement_t:
|
||||
public Policies::template _member_t<detail::statement_policies_t<Db, Policies...>>...,
|
||||
public detail::statement_policies_t<Db, Policies...>::_value_type::template expression_operators<statement_t<Db, Policies...>>,
|
||||
public detail::statement_policies_t<Db, Policies...>::_result_methods_t,
|
||||
public detail::statement_policies_t<Db, Policies...>::_methods_t
|
||||
typename... Policies
|
||||
>
|
||||
struct statement_t:
|
||||
public Policies::template _member_t<detail::statement_policies_t<Db, Policies...>>...,
|
||||
public detail::statement_policies_t<Db, Policies...>::_value_type::template expression_operators<statement_t<Db, Policies...>>,
|
||||
public detail::statement_policies_t<Db, Policies...>::_result_methods_t,
|
||||
public detail::statement_policies_t<Db, Policies...>::_methods_t
|
||||
{
|
||||
using _policies_t = typename detail::statement_policies_t<Db, Policies...>;
|
||||
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 _recursive_traits = typename _policies_t::_recursive_traits;
|
||||
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 _recursive_traits = typename _policies_t::_recursive_traits;
|
||||
|
||||
using _result_type_provider = typename _policies_t::_result_type_provider;
|
||||
using _result_type_provider = typename _policies_t::_result_type_provider;
|
||||
|
||||
using _requires_braces = std::true_type;
|
||||
using _requires_braces = std::true_type;
|
||||
|
||||
using _name_t = typename _result_type_provider::_name_t;
|
||||
using _name_t = typename _result_type_provider::_name_t;
|
||||
|
||||
// Constructors
|
||||
statement_t()
|
||||
{}
|
||||
// Constructors
|
||||
statement_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
statement_t(Statement statement, Term term):
|
||||
Policies::template _member_t<_policies_t>{
|
||||
typename Policies::template _impl_t<_policies_t>{
|
||||
detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)
|
||||
}}...
|
||||
//Policies::template _member_t<_policies_t>{{detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)}}...
|
||||
{}
|
||||
template<typename Statement, typename Term>
|
||||
statement_t(Statement statement, Term term):
|
||||
Policies::template _member_t<_policies_t>{
|
||||
typename Policies::template _impl_t<_policies_t>{
|
||||
detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)
|
||||
}}...
|
||||
//Policies::template _member_t<_policies_t>{{detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)}}...
|
||||
{}
|
||||
|
||||
statement_t(const statement_t& r) = default;
|
||||
statement_t(statement_t&& r) = default;
|
||||
statement_t& operator=(const statement_t& r) = default;
|
||||
statement_t& operator=(statement_t&& r) = default;
|
||||
~statement_t() = default;
|
||||
statement_t(const statement_t& r) = default;
|
||||
statement_t(statement_t&& r) = default;
|
||||
statement_t& operator=(const statement_t& r) = default;
|
||||
statement_t& operator=(statement_t&& r) = default;
|
||||
~statement_t() = default;
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _get_static_no_of_parameters();
|
||||
}
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _get_static_no_of_parameters();
|
||||
}
|
||||
|
||||
static void _check_consistency()
|
||||
{
|
||||
// FIXME: Check each "methods" or each member...
|
||||
static void _check_consistency()
|
||||
{
|
||||
// FIXME: Check each "methods" or each member...
|
||||
#warning check for missing terms here, and for missing tables
|
||||
static_assert(not required_tables_of<_policies_t>::size::value, "one sub expression requires tables which are otherwise not known in the statement");
|
||||
static_assert(not required_tables_of<_policies_t>::size::value, "one sub expression requires tables which are otherwise not known in the statement");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, statement_t<Database, Policies...>>
|
||||
{
|
||||
using T = statement_t<Database, Policies...>;
|
||||
using P = ::sqlpp::detail::statement_policies_t<Database, Policies...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const typename Policies::template _member_t<P>&>(t)()._data, context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, statement_t<Database, Policies...>>
|
||||
{
|
||||
using T = statement_t<Database, Policies...>;
|
||||
using P = ::sqlpp::detail::statement_policies_t<Database, Policies...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const typename Policies::template _member_t<P>&>(t)()._data, context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename NameData>
|
||||
template<typename NameData>
|
||||
struct statement_name_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
|
||||
@@ -31,59 +31,59 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
template<typename Flag, typename Expr>
|
||||
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
|
||||
public alias_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 _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'");
|
||||
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::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'");
|
||||
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
|
||||
|
||||
struct _name_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "SUM"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T sum;
|
||||
T& operator()() { return sum; }
|
||||
const T& operator()() const { return sum; }
|
||||
};
|
||||
};
|
||||
|
||||
sum_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
sum_t(const sum_t&) = default;
|
||||
sum_t(sum_t&&) = default;
|
||||
sum_t& operator=(const sum_t&) = default;
|
||||
sum_t& operator=(sum_t&&) = default;
|
||||
~sum_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
static constexpr const char* _get_name() { return "SUM"; }
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T sum;
|
||||
T& operator()() { return sum; }
|
||||
const T& operator()() const { return sum; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, sum_t<Flag, Expr>>
|
||||
{
|
||||
using T = sum_t<Flag, Expr>;
|
||||
sum_t(Expr expr):
|
||||
_expr(expr)
|
||||
{}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
sum_t(const sum_t&) = default;
|
||||
sum_t(sum_t&&) = default;
|
||||
sum_t& operator=(const sum_t&) = default;
|
||||
sum_t& operator=(sum_t&&) = default;
|
||||
~sum_t() = default;
|
||||
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, sum_t<Flag, Expr>>
|
||||
{
|
||||
using T = sum_t<Flag, Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SUM(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
context << "SUM(";
|
||||
if (std::is_same<sqlpp::distinct_t, Flag>::value)
|
||||
{
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
}
|
||||
};
|
||||
serialize(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto sum(T t) -> typename sum_t<noop, wrap_operand_t<T>>
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace sqlpp
|
||||
struct table_base_t {};
|
||||
|
||||
template<typename Table, typename... ColumnSpec>
|
||||
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, 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>;
|
||||
|
||||
@@ -101,17 +101,17 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename X>
|
||||
struct serializer_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
template<typename Context, typename X>
|
||||
struct serializer_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -61,19 +61,19 @@ namespace sqlpp
|
||||
Table _table;
|
||||
};
|
||||
|
||||
template<typename Context, typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||
struct serializer_t<Context, table_alias_t<AliasProvider, Table, ColumnSpec...>>
|
||||
{
|
||||
using T = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
||||
template<typename Context, typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||
struct serializer_t<Context, table_alias_t<AliasProvider, Table, ColumnSpec...>>
|
||||
{
|
||||
using T = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._table, context);
|
||||
context << ") AS " << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._table, context);
|
||||
context << ") AS " << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ namespace sqlpp
|
||||
_parameter_t():
|
||||
_value(""),
|
||||
_is_null(true)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(false)
|
||||
{}
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
{
|
||||
return _is_null;
|
||||
}
|
||||
|
||||
@@ -96,94 +96,94 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Db, bool NullIsTrivial = false>
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_value_ptr(nullptr),
|
||||
_len(0)
|
||||
struct _result_entry_t
|
||||
{
|
||||
_result_entry_t():
|
||||
_is_valid(false),
|
||||
_value_ptr(nullptr),
|
||||
_len(0)
|
||||
{}
|
||||
|
||||
_result_entry_t(char* data, size_t len):
|
||||
_is_valid(true),
|
||||
_value_ptr(data),
|
||||
_len(_value_ptr ? 0 : len)
|
||||
{}
|
||||
_result_entry_t(char* data, size_t len):
|
||||
_is_valid(true),
|
||||
_value_ptr(data),
|
||||
_len(_value_ptr ? 0 : len)
|
||||
{}
|
||||
|
||||
void assign(const char* data, size_t len)
|
||||
{
|
||||
_is_valid = true;
|
||||
_value_ptr = data;
|
||||
_len = _value_ptr ? len: 0;
|
||||
}
|
||||
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_value_ptr = nullptr;
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; }
|
||||
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _value_ptr == nullptr;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
void assign(const char* data, size_t len)
|
||||
{
|
||||
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 "";
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_text_result(i, &_value_ptr, &_len);
|
||||
_is_valid = true;
|
||||
_value_ptr = data;
|
||||
_len = _value_ptr ? len: 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
const char* _value_ptr;
|
||||
size_t _len;
|
||||
};
|
||||
void validate()
|
||||
{
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
_is_valid = false;
|
||||
_value_ptr = nullptr;
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; }
|
||||
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
assert(_is_valid);
|
||||
else if (not _is_valid)
|
||||
throw exception("accessing is_null in non-existing row");
|
||||
return _value_ptr == nullptr;
|
||||
}
|
||||
|
||||
_cpp_value_type value() const
|
||||
{
|
||||
const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t<Db>::value;
|
||||
if (connector_assert_result_validity_t<Db>::value)
|
||||
{
|
||||
assert(_is_valid);
|
||||
assert(not null_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (not _is_valid)
|
||||
throw exception("accessing value in non-existing row");
|
||||
if (null_value)
|
||||
throw exception("accessing value of NULL field");
|
||||
}
|
||||
if (_value_ptr)
|
||||
return std::string(_value_ptr, _value_ptr + _len);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
operator _cpp_value_type() const { return value(); }
|
||||
|
||||
template<typename Target>
|
||||
void _bind(Target& target, size_t i)
|
||||
{
|
||||
target._bind_text_result(i, &_value_ptr, &_len);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _is_valid;
|
||||
const char* _value_ptr;
|
||||
size_t _len;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _is_valid_operand
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_text_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_expression_t<T>::value // expressions are OK
|
||||
and is_text_t<T>::value // the correct value type is required, of course
|
||||
;
|
||||
};
|
||||
|
||||
template<typename Base>
|
||||
struct expression_operators: public basic_expression_operators<Base, is_text_t>
|
||||
@@ -209,23 +209,23 @@ namespace sqlpp
|
||||
|
||||
template<typename Base>
|
||||
struct column_operators
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, concat_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
{
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> assignment_t<Base, concat_t<Base, wrap_operand_t<T>>>
|
||||
{
|
||||
using rhs = wrap_operand_t<T>;
|
||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Db, bool TrivialIsNull>
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, TrivialIsNull>& e)
|
||||
{
|
||||
return os << e.value();
|
||||
}
|
||||
}
|
||||
|
||||
using text = detail::text;
|
||||
|
||||
@@ -35,56 +35,56 @@ namespace sqlpp
|
||||
static constexpr bool report_auto_rollback = true;
|
||||
|
||||
template<typename Db>
|
||||
class transaction_t
|
||||
{
|
||||
Db& _db;
|
||||
const bool _report_unfinished_transaction;
|
||||
bool _finished = false;
|
||||
|
||||
public:
|
||||
transaction_t(Db& db, bool report_unfinished_transaction):
|
||||
_db(db),
|
||||
_report_unfinished_transaction(report_unfinished_transaction)
|
||||
class transaction_t
|
||||
{
|
||||
_db.start_transaction();
|
||||
}
|
||||
Db& _db;
|
||||
const bool _report_unfinished_transaction;
|
||||
bool _finished = false;
|
||||
|
||||
transaction_t(const transaction_t&) = delete;
|
||||
transaction_t(transaction_t&&) = default;
|
||||
transaction_t& operator=(const transaction_t&) = delete;
|
||||
transaction_t& operator=(transaction_t&&) = delete;
|
||||
|
||||
~transaction_t()
|
||||
{
|
||||
if (not _finished)
|
||||
public:
|
||||
transaction_t(Db& db, bool report_unfinished_transaction):
|
||||
_db(db),
|
||||
_report_unfinished_transaction(report_unfinished_transaction)
|
||||
{
|
||||
try
|
||||
_db.start_transaction();
|
||||
}
|
||||
|
||||
transaction_t(const transaction_t&) = delete;
|
||||
transaction_t(transaction_t&&) = default;
|
||||
transaction_t& operator=(const transaction_t&) = delete;
|
||||
transaction_t& operator=(transaction_t&&) = delete;
|
||||
|
||||
~transaction_t()
|
||||
{
|
||||
if (not _finished)
|
||||
{
|
||||
_db.rollback_transaction(_report_unfinished_transaction);
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
_db.report_rollback_failure(std::string("auto rollback failed: ") + e.what());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
_db.report_rollback_failure("auto rollback failed with unknown exception");
|
||||
try
|
||||
{
|
||||
_db.rollback_transaction(_report_unfinished_transaction);
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
_db.report_rollback_failure(std::string("auto rollback failed: ") + e.what());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
_db.report_rollback_failure("auto rollback failed with unknown exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void commit()
|
||||
{
|
||||
_finished = true;
|
||||
_db.commit_transaction();
|
||||
}
|
||||
void commit()
|
||||
{
|
||||
_finished = true;
|
||||
_db.commit_transaction();
|
||||
}
|
||||
|
||||
void rollback()
|
||||
{
|
||||
_finished = true;
|
||||
_db.rollback_transaction(false);
|
||||
}
|
||||
};
|
||||
void rollback()
|
||||
{
|
||||
_finished = true;
|
||||
_db.rollback_transaction(false);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
transaction_t<Db> start_transaction(Db& db, bool report_unfinished_transaction = report_auto_rollback)
|
||||
|
||||
@@ -61,16 +61,16 @@ namespace sqlpp
|
||||
Operand _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, tvin_t<Operand>>
|
||||
{
|
||||
using T = tvin_t<Operand>;
|
||||
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 !");
|
||||
}
|
||||
};
|
||||
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
|
||||
@@ -118,31 +118,31 @@ namespace sqlpp
|
||||
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>;
|
||||
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)
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
{
|
||||
if (t._is_trivial())
|
||||
{
|
||||
context << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(t._value, context);
|
||||
}
|
||||
return context;
|
||||
context << "NULL";
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
serialize(t._value, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Operand>
|
||||
auto tvin(Operand operand) -> tvin_t<typename wrap_operand<Operand>::type>
|
||||
{
|
||||
using _operand_t = typename wrap_operand<Operand>::type;
|
||||
static_assert(std::is_same<_operand_t, text_operand>::value
|
||||
or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)");
|
||||
or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)");
|
||||
return {{operand}};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,57 +36,57 @@ namespace sqlpp
|
||||
namespace detail\
|
||||
{\
|
||||
template<typename T, typename Enable = void>\
|
||||
struct is_##name##_impl: std::false_type {};\
|
||||
struct is_##name##_impl: 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 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 {};\
|
||||
}\
|
||||
namespace tag\
|
||||
{\
|
||||
struct name{};\
|
||||
};\
|
||||
template<typename T>\
|
||||
using is_##name##_t = detail::is_element_of<tag::name, typename T::_traits::_tags>;
|
||||
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; };\
|
||||
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<std::is_same<typename T::_column_type::_##name, std::true_type>::value>::type> { using type = std::true_type; };\
|
||||
}\
|
||||
template<typename T>\
|
||||
using name##_t = typename detail::name##_impl<T>::type;
|
||||
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 {};\
|
||||
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 {};\
|
||||
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> {};
|
||||
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 {};\
|
||||
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 {};\
|
||||
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> {};
|
||||
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);
|
||||
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>;
|
||||
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);
|
||||
|
||||
@@ -70,34 +70,34 @@ namespace sqlpp
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_update_t<Db, update_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_update(*this)};
|
||||
return {{}, db.prepare_update(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, update_name_t>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, update_name_t>
|
||||
{
|
||||
using T = update_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using T = update_name_t;
|
||||
context << "UPDATE ";
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "UPDATE ";
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Database>
|
||||
using blank_update_t = statement_t<Database,
|
||||
update_t,
|
||||
no_single_table_t,
|
||||
no_update_list_t,
|
||||
no_where_t>;
|
||||
update_t,
|
||||
no_single_table_t,
|
||||
no_update_list_t,
|
||||
no_where_t>;
|
||||
|
||||
template<typename Table>
|
||||
constexpr auto update(Table table)
|
||||
|
||||
@@ -34,127 +34,88 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// UPDATE ASSIGNMENTS DATA
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_data_t
|
||||
{
|
||||
update_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
{}
|
||||
// UPDATE ASSIGNMENTS DATA
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_data_t
|
||||
{
|
||||
update_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
{}
|
||||
|
||||
update_list_data_t(const update_list_data_t&) = default;
|
||||
update_list_data_t(update_list_data_t&&) = default;
|
||||
update_list_data_t& operator=(const update_list_data_t&) = default;
|
||||
update_list_data_t& operator=(update_list_data_t&&) = default;
|
||||
~update_list_data_t() = default;
|
||||
update_list_data_t(const update_list_data_t&) = default;
|
||||
update_list_data_t(update_list_data_t&&) = default;
|
||||
update_list_data_t& operator=(const update_list_data_t&) = default;
|
||||
update_list_data_t& operator=(update_list_data_t&&) = default;
|
||||
~update_list_data_t() = default;
|
||||
|
||||
std::tuple<Assignments...> _assignments;
|
||||
typename interpretable_list_t<Database> _dynamic_assignments;
|
||||
};
|
||||
std::tuple<Assignments...> _assignments;
|
||||
typename interpretable_list_t<Database> _dynamic_assignments;
|
||||
};
|
||||
|
||||
// UPDATE ASSIGNMENTS
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::update_list>;
|
||||
using _recursive_traits = make_recursive_traits<Assignments...>;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
// UPDATE ASSIGNMENTS
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::update_list>;
|
||||
using _recursive_traits = make_recursive_traits<Assignments...>;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment 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::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
#warning reactivate tests
|
||||
/*
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
// Data
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
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()");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_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<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value,
|
||||
not must_not_update_t<typename Assignment::_column_t>::value>;
|
||||
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_assignments.emplace_back(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
_impl_t<Policies> assignments;
|
||||
_impl_t<Policies>& operator()() { return assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return assignments; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.assignments)
|
||||
{
|
||||
return t.assignments;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
/*
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
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()");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_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<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value,
|
||||
not must_not_update_t<typename Assignment::_column_t>::value>;
|
||||
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_assignments.emplace_back(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -162,59 +123,98 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
_impl_t<Policies> no_assignments;
|
||||
_impl_t<Policies>& operator()() { return no_assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return no_assignments; }
|
||||
_impl_t<Policies> assignments;
|
||||
_impl_t<Policies>& operator()() { return assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return assignments; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_assignments)
|
||||
static auto _get_member(T t) -> decltype(t.assignments)
|
||||
{
|
||||
return t.no_assignments;
|
||||
return t.assignments;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_update_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<update_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _new_statement_t<update_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = update_list_data_t<Database, Assignments...>;
|
||||
struct no_update_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " SET ";
|
||||
interpret_tuple(t._assignments, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_assignments, ',', context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_assignments;
|
||||
_impl_t<Policies>& operator()() { return no_assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return no_assignments; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_assignments)
|
||||
{
|
||||
return t.no_assignments;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_update_list_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<update_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _new_statement_t<update_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " SET ";
|
||||
interpret_tuple(t._assignments, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_assignments, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,108 +35,68 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// USING DATA
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_data_t
|
||||
{
|
||||
using_data_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
using_data_t(const using_data_t&) = default;
|
||||
using_data_t(using_data_t&&) = default;
|
||||
using_data_t& operator=(const using_data_t&) = default;
|
||||
using_data_t& operator=(using_data_t&&) = default;
|
||||
~using_data_t() = default;
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
// USING
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::using_>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
|
||||
|
||||
// Data
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add must not be called for static using()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
_impl_t<Policies> using_;
|
||||
_impl_t<Policies>& operator()() { return using_; }
|
||||
const _impl_t<Policies>& operator()() const { return using_; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.using_)
|
||||
{
|
||||
return t.using_;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO USING YET
|
||||
struct no_using_t
|
||||
// USING DATA
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using_data_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
using_data_t(const using_data_t&) = default;
|
||||
using_data_t(using_data_t&&) = default;
|
||||
using_data_t& operator=(const using_data_t&) = default;
|
||||
using_data_t& operator=(using_data_t&&) = default;
|
||||
~using_data_t() = default;
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
// USING
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::using_>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add must not be called for static using()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
@@ -144,61 +104,101 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
_impl_t<Policies> no_using;
|
||||
_impl_t<Policies>& operator()() { return no_using; }
|
||||
const _impl_t<Policies>& operator()() const { return no_using; }
|
||||
_impl_t<Policies> using_;
|
||||
_impl_t<Policies>& operator()() { return using_; }
|
||||
const _impl_t<Policies>& operator()() const { return using_; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_using)
|
||||
static auto _get_member(T t) -> decltype(t.using_)
|
||||
{
|
||||
return t.no_using;
|
||||
return t.using_;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_using_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto using_(Args... args)
|
||||
-> _new_statement_t<using_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_using(Args... args)
|
||||
-> _new_statement_t<using_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, using_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = using_data_t<Database, Tables...>;
|
||||
// NO USING YET
|
||||
struct no_using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " USING ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_using;
|
||||
_impl_t<Policies>& operator()() { return no_using; }
|
||||
const _impl_t<Policies>& operator()() const { return no_using; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_using)
|
||||
{
|
||||
return t.no_using;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_using_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto using_(Args... args)
|
||||
-> _new_statement_t<using_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_using(Args... args)
|
||||
-> _new_statement_t<using_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, using_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = using_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " USING ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
using value_type_t = value_type_of<wrap_operand_t<T>>;
|
||||
template<typename T>
|
||||
using value_type_t = value_type_of<wrap_operand_t<T>>;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -63,17 +63,17 @@ namespace sqlpp
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, verbatim_table_t>
|
||||
{
|
||||
using T = verbatim_table_t;
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, verbatim_table_t>
|
||||
{
|
||||
using T = verbatim_table_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._name;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._name;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
verbatim_table_t verbatim_table(std::string name)
|
||||
|
||||
@@ -36,157 +36,116 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// WHERE DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_data_t
|
||||
{
|
||||
where_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
// WHERE DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_data_t
|
||||
{
|
||||
where_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
where_data_t(const where_data_t&) = default;
|
||||
where_data_t(where_data_t&&) = default;
|
||||
where_data_t& operator=(const where_data_t&) = default;
|
||||
where_data_t& operator=(where_data_t&&) = default;
|
||||
~where_data_t() = default;
|
||||
where_data_t(const where_data_t&) = default;
|
||||
where_data_t(where_data_t&&) = default;
|
||||
where_data_t& operator=(const where_data_t&) = default;
|
||||
where_data_t& operator=(where_data_t&&) = default;
|
||||
~where_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// WHERE(EXPR)
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
// WHERE(EXPR)
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
#warning: is_dynamic should be using a template alias (making it easier to replace the logic)
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
||||
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
||||
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
|
||||
|
||||
// Data
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
// Data
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in where::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in where::add()");
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in where::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in where::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct where_data_t<void, bool>
|
||||
{
|
||||
bool _condition;
|
||||
};
|
||||
template<>
|
||||
struct where_data_t<void, bool>
|
||||
{
|
||||
bool _condition;
|
||||
};
|
||||
|
||||
// WHERE(BOOL)
|
||||
template<>
|
||||
struct where_t<void, bool>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// NO WHERE YET
|
||||
struct no_where_t
|
||||
// WHERE(BOOL)
|
||||
template<>
|
||||
struct where_t<void, bool>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
@@ -199,16 +158,16 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
_impl_t<Policies> no_where;
|
||||
_impl_t<Policies>& operator()() { return no_where; }
|
||||
const _impl_t<Policies>& operator()() const { return no_where; }
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_where)
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.no_where;
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -216,59 +175,100 @@ namespace sqlpp
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_where_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> _new_statement_t<where_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> _new_statement_t<where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, where_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = where_data_t<Database, Expressions...>;
|
||||
// NO WHERE YET
|
||||
struct no_where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " WHERE ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, where_data_t<void, bool>>
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using T = where_data_t<void, bool>;
|
||||
using _data_t = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (not t._condition)
|
||||
context << " WHERE NULL";
|
||||
return context;
|
||||
}
|
||||
_impl_t<Policies> no_where;
|
||||
_impl_t<Policies>& operator()() { return no_where; }
|
||||
const _impl_t<Policies>& operator()() const { return no_where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_where)
|
||||
{
|
||||
return t.no_where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_where_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> _new_statement_t<where_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> _new_statement_t<where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, where_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = where_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " WHERE ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, where_data_t<void, bool>>
|
||||
{
|
||||
using T = where_data_t<void, bool>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (not t._condition)
|
||||
context << " WHERE NULL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,193 +41,193 @@ namespace sqlpp
|
||||
struct text;
|
||||
}
|
||||
|
||||
struct boolean_operand
|
||||
struct boolean_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = bool;
|
||||
|
||||
boolean_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
boolean_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
boolean_operand(const boolean_operand&) = default;
|
||||
boolean_operand(boolean_operand&&) = default;
|
||||
boolean_operand& operator=(const boolean_operand&) = default;
|
||||
boolean_operand& operator=(boolean_operand&&) = default;
|
||||
~boolean_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, boolean_operand>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using Operand = boolean_operand;
|
||||
|
||||
using _value_t = bool;
|
||||
|
||||
boolean_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
boolean_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
boolean_operand(const boolean_operand&) = default;
|
||||
boolean_operand(boolean_operand&&) = default;
|
||||
boolean_operand& operator=(const boolean_operand&) = default;
|
||||
boolean_operand& operator=(boolean_operand&&) = default;
|
||||
~boolean_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
_value_t _t;
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, boolean_operand>
|
||||
{
|
||||
using Operand = boolean_operand;
|
||||
struct integral_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
using _value_t = int64_t;
|
||||
|
||||
struct integral_operand
|
||||
integral_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
integral_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, integral_operand>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using Operand = integral_operand;
|
||||
|
||||
using _value_t = int64_t;
|
||||
|
||||
integral_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
integral_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, integral_operand>
|
||||
{
|
||||
using Operand = integral_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
struct floating_point_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = double;
|
||||
|
||||
struct floating_point_operand
|
||||
floating_point_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
floating_point_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, floating_point_operand>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using Operand = floating_point_operand;
|
||||
|
||||
using _value_t = double;
|
||||
|
||||
floating_point_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
floating_point_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, floating_point_operand>
|
||||
{
|
||||
using Operand = floating_point_operand;
|
||||
struct text_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
using _value_t = std::string;
|
||||
|
||||
struct text_operand
|
||||
text_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
text_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
text_operand(const text_operand&) = default;
|
||||
text_operand(text_operand&&) = default;
|
||||
text_operand& operator=(const text_operand&) = default;
|
||||
text_operand& operator=(text_operand&&) = default;
|
||||
~text_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, text_operand>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using Operand = text_operand;
|
||||
|
||||
using _value_t = std::string;
|
||||
|
||||
text_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
text_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
text_operand(const text_operand&) = default;
|
||||
text_operand(text_operand&&) = default;
|
||||
text_operand& operator=(const text_operand&) = default;
|
||||
text_operand& operator=(text_operand&&) = default;
|
||||
~text_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
_value_t _t;
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, text_operand>
|
||||
{
|
||||
using Operand = text_operand;
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = integral_operand;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = boolean_operand;
|
||||
};
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = integral_operand;
|
||||
};
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand;
|
||||
};
|
||||
// FIXME: Need to allow std::ref arguments
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand;
|
||||
};
|
||||
|
||||
// FIXME: Need to allow std::ref arguments
|
||||
|
||||
template<typename T>
|
||||
using wrap_operand_t = typename wrap_operand<T>::type;
|
||||
template<typename T>
|
||||
using wrap_operand_t = typename wrap_operand<T>::type;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,18 +31,18 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// A template that always returns false
|
||||
// To be used with static assert, for instance, to ensure it
|
||||
// fires only when the template is instantiated.
|
||||
template<typename... T>
|
||||
struct wrong
|
||||
{
|
||||
using type = std::false_type;
|
||||
};
|
||||
}
|
||||
namespace detail
|
||||
{
|
||||
// A template that always returns false
|
||||
// To be used with static assert, for instance, to ensure it
|
||||
// fires only when the template is instantiated.
|
||||
template<typename... T>
|
||||
using wrong_t = typename detail::wrong<T...>::type;
|
||||
struct wrong
|
||||
{
|
||||
using type = std::false_type;
|
||||
};
|
||||
}
|
||||
template<typename... T>
|
||||
using wrong_t = typename detail::wrong<T...>::type;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user