diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 2cd0da5d..eeb9e2b6 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -46,20 +46,20 @@ namespace sqlpp Expression _expression; }; - template - struct serializer_t> - { - using T = expression_alias_t; + template + struct serializer_t> + { + using T = expression_alias_t; - 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; + } + }; } diff --git a/include/sqlpp11/alias_provider.h b/include/sqlpp11/alias_provider.h index 6949933b..78dcf1e3 100644 --- a/include/sqlpp11/alias_provider.h +++ b/include/sqlpp11/alias_provider.h @@ -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\ + struct _member_t\ {\ - static constexpr const char* _get_name() { return #name; }\ - template\ - 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 { diff --git a/include/sqlpp11/all_of.h b/include/sqlpp11/all_of.h index fb3c6a14..b4d90fae 100644 --- a/include/sqlpp11/all_of.h +++ b/include/sqlpp11/all_of.h @@ -34,33 +34,33 @@ namespace sqlpp { template - 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 - detail::copy_tuple_args_t as(const AliasProvider& alias) - { - return ::sqlpp::multi_column(_column_tuple_t{}).as(alias); - } - }; + template + detail::copy_tuple_args_t as(const AliasProvider& alias) + { + return ::sqlpp::multi_column(_column_tuple_t{}).as(alias); + } + }; template - auto all_of(Table t) -> all_of_t - { - return {}; - } + auto all_of(Table t) -> all_of_t
+ { + return {}; + } - template - struct serializer_t> + template + struct serializer_t> + { + using T = all_of_t
; + + static Context& _(const T& t, const Context&) { - using T = all_of_t
; - - static Context& _(const T& t, const Context&) - { - static_assert(wrong_t::value, "all_of(table) does not seem to be used in select"); - } - }; + static_assert(wrong_t::value, "all_of(table) does not seem to be used in select"); + } + }; } diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index a8ffed96..c2f6258f 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -32,7 +32,7 @@ namespace sqlpp { - template + template struct any_t { using _traits = make_traits, ::sqlpp::tag::multi_expression>; @@ -63,28 +63,28 @@ namespace sqlpp Select _select; }; - template - struct serializer_t> - { - using T = any_t; - static Context& _(const T& t, Context& context) - { - context << "ANY("; - serialize(t._select, context); - context << ")"; - return context; - } - }; - - template - auto any(T t) -> typename any_t> + static Context& _(const T& t, Context& context) { - static_assert(is_select_t>::value, "any() requires a select expression as argument"); - static_assert(is_expression_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 + auto any(T t) -> typename any_t> + { + static_assert(is_select_t>::value, "any() requires a select expression as argument"); + static_assert(is_expression_t>::value, "any() requires a single column select expression as argument"); + // FIXME: can we accept non-values like NULL here? + return { t }; + } } diff --git a/include/sqlpp11/assignment.h b/include/sqlpp11/assignment.h index 15ed6dcb..8161db1b 100644 --- a/include/sqlpp11/assignment.h +++ b/include/sqlpp11/assignment.h @@ -36,7 +36,7 @@ namespace sqlpp { - template + template struct is_trivial_t { static constexpr bool _(const T&) @@ -45,7 +45,7 @@ namespace sqlpp } }; - template + template struct is_trivial_t::value, void>::type> { static bool _(const T& t) @@ -54,108 +54,108 @@ namespace sqlpp } }; - template + template bool is_trivial(const T& t) { return is_trivial_t::_(t); } - template - struct assignment_t + template + struct assignment_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + 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 + struct serializer_t> + { + using T = assignment_t; + + static Context& _(const T& t, Context& context) { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - 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 - struct serializer_t> - { - using T = assignment_t; - - static Context& _(const T& t, Context& context) - { - if ((trivial_value_is_null_t::value - and is_trivial(t._rhs)) - or (std::is_same::value)) - { - serialize(simple_column(t._lhs), context); - context << "=NULL"; - } - else - { - serialize(simple_column(t._lhs), context); - context << "="; - serialize(t._rhs, context); - } - return context; - } - }; - - template - struct assignment_t> - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _column_t = Lhs; - using _value_t = tvin_t; - - 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 - struct serializer_t>> - { - using T = assignment_t>; - - static Context& _(const T& t, Context& context) + if ((trivial_value_is_null_t::value + and is_trivial(t._rhs)) + or (std::is_same::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 + struct assignment_t> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _column_t = Lhs; + using _value_t = tvin_t; + + 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 + struct serializer_t>> + { + using T = assignment_t>; + + 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 diff --git a/include/sqlpp11/avg.h b/include/sqlpp11/avg.h index 0e2cb3df..46bba2b3 100644 --- a/include/sqlpp11/avg.h +++ b/include/sqlpp11/avg.h @@ -31,59 +31,59 @@ namespace sqlpp { - template + template struct avg_t: public floating_point::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static_assert(is_noop::value or std::is_same::value, "avg() used with flag other than 'distinct'"); + static_assert(is_numeric_t::value, "avg() requires a value expression as argument"); + + struct _name_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - static_assert(is_noop::value or std::is_same::value, "avg() used with flag other than 'distinct'"); - static_assert(is_numeric_t::value, "avg() requires a value expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "AVG"; } - template - 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 + struct _member_t + { + T avg; + T& operator()() { return avg; } + const T& operator()() const { return avg; } + }; }; - template - struct serializer_t> - { - using T = avg_t; + 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 + struct serializer_t> + { + using T = avg_t; + + static Context& _(const T& t, Context& context) + { + context << "AVG("; + if (std::is_same::value) { - context << "AVG("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + serialize(Flag(), context); + context << ' '; } - }; + serialize(t._expr, context); + context << ")"; + return context; + } + }; template auto avg(T t) -> typename avg_t> diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index 87b06e5a..deeb5342 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -43,13 +43,13 @@ namespace sqlpp { template struct _is_valid_comparison_operand - { - static constexpr bool value = - (is_expression_t::value // expressions are OK - or is_multi_expression_t::value) // multi-expressions like ANY are OK for comparisons, too - and IsCorrectValueType::value // the correct value type is required, of course - ; - }; + { + static constexpr bool value = + (is_expression_t::value // expressions are OK + or is_multi_expression_t::value) // multi-expressions like ANY are OK for comparisons, too + and IsCorrectValueType::value // the correct value type is required, of course + ; + }; template equal_to_t> operator==(T t) const diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index b01d49bb..ed8fe94c 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -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 - 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::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::value; - if (connector_assert_result_validity_t::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 - 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::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::value; + if (connector_assert_result_validity_t::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 + 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 struct _is_valid_operand - { - static constexpr bool value = - is_expression_t::value // expressions are OK - and is_boolean_t::value // the correct value type is required, of course - ; - }; + { + static constexpr bool value = + is_expression_t::value // expressions are OK + and is_boolean_t::value // the correct value type is required, of course + ; + }; template struct expression_operators: public basic_expression_operators @@ -209,15 +209,15 @@ namespace sqlpp template struct column_operators - { - }; + { + }; }; template - inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e) - { - return os << e.value(); - } + inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e) + { + return os << e.value(); + } } using boolean = detail::boolean; diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index c69af308..31da39a2 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -42,8 +42,8 @@ namespace sqlpp { template - struct column_t: public ColumnSpec::_value_type::template expression_operators>, - public ColumnSpec::_value_type::template column_operators> + struct column_t: public ColumnSpec::_value_type::template expression_operators>, + public ColumnSpec::_value_type::template column_operators> { using _traits = make_traits; struct _recursive_traits @@ -103,17 +103,17 @@ namespace sqlpp } }; - template - struct serializer_t> - { - using T = column_t; + template + struct serializer_t> + { + using T = column_t; - 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; + } + }; } diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/concat.h index 766b4f0a..ecae74ce 100644 --- a/include/sqlpp11/concat.h +++ b/include/sqlpp11/concat.h @@ -33,52 +33,52 @@ namespace sqlpp { - // FIXME: Remove First, inherit from text_t - template - struct concat_t: public value_type_of::template expression_operators>, - public alias_operators> + // FIXME: Remove First, inherit from text_t + template + struct concat_t: public value_type_of::template expression_operators>, + public alias_operators> + { + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; + + static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); + static_assert(sqlpp::detail::all_t::value, is_text_t::value...>::value, "at least one non-text argument detected in concat()"); + struct _name_t { - using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; - using _recursive_traits = make_recursive_traits; - - static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); - static_assert(sqlpp::detail::all_t::value, is_text_t::value...>::value, "at least one non-text argument detected in concat()"); - struct _name_t - { - static constexpr const char* _get_name() { return "CONCAT"; } - template - 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 _args; + static constexpr const char* _get_name() { return "CONCAT"; } + template + struct _member_t + { + T concat; + }; }; - template - struct serializer_t> - { - using T = concat_t; + 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 _args; + }; + + template + struct serializer_t> + { + using T = concat_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + interpret_tuple(t._args, "||", context); + context << ")"; + return context; + } + }; } #endif diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index a29e1414..3e61bb53 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -32,59 +32,59 @@ namespace sqlpp { - template + template struct count_t: public sqlpp::detail::integral::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; + + static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); + static_assert(is_expression_t::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; - - static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); - static_assert(is_expression_t::value, "count() requires a sql expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "COUNT"; } - template - 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 + struct _member_t + { + T count; + T& operator()() { return count; } + const T& operator()() const { return count; } + }; }; - template - struct serializer_t> - { - using T = count_t; + 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 + struct serializer_t> + { + using T = count_t; + + static Context& _(const T& t, Context& context) + { + context << "COUNT("; + if (std::is_same::value) { - context << "COUNT("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + serialize(Flag(), context); + context << ' '; } - }; + serialize(t._expr, context); + context << ")"; + return context; + } + }; template auto count(T t) -> typename count_t> diff --git a/include/sqlpp11/default_value.h b/include/sqlpp11/default_value.h index d31aef95..bb8fce6d 100644 --- a/include/sqlpp11/default_value.h +++ b/include/sqlpp11/default_value.h @@ -39,17 +39,17 @@ namespace sqlpp static constexpr bool _is_trivial() { return false; } }; - template - struct serializer_t - { - using Operand = default_value_t; + template + struct serializer_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 = {}; diff --git a/include/sqlpp11/exists.h b/include/sqlpp11/exists.h index 811c502d..ca993727 100644 --- a/include/sqlpp11/exists.h +++ b/include/sqlpp11/exists.h @@ -31,53 +31,53 @@ namespace sqlpp { - template + template struct exists_t: public boolean::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits::value, "exists() requires a select expression as argument"); + + struct _name_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits::value, "exists() requires a select expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "EXISTS"; } - template - 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 + struct _member_t + { + T exists; + T& operator()() { return exists; } + const T& operator()() const { return exists; } + }; }; - template - struct serializer_t> - { - using T = exists_t; + + static Context& _(const T& t, Context& context) + { + context << "EXISTS("; + serialize(t._select, context); + context << ")"; + return context; + } + }; template diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h index ba192890..28a72bb3 100644 --- a/include/sqlpp11/expression.h +++ b/include/sqlpp11/expression.h @@ -37,9 +37,9 @@ namespace sqlpp { - template - struct binary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, - public alias_operators> + template + struct binary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, + public alias_operators> { using _traits = make_traits; using _recursive_traits = make_recursive_traits; @@ -59,32 +59,32 @@ namespace sqlpp maybe_tvin_t _rhs; }; - template - struct serializer_t> + template + struct serializer_t> + { + using T = equal_to_t; + + static Context& _(const T& t, Context& context) { - using T = equal_to_t; - - 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 - struct binary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, - public alias_operators> + template + struct binary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, + public alias_operators> { using _traits = make_traits; using _recursive_traits = make_recursive_traits; @@ -104,32 +104,32 @@ namespace sqlpp maybe_tvin_t _rhs; }; - template - struct serializer_t> + template + struct serializer_t> + { + using T = not_equal_to_t; + + static Context& _(const T& t, Context& context) { - using T = not_equal_to_t; - - 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 - struct unary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, - public alias_operators> + template + struct unary_expression_t: public ::sqlpp::detail::boolean::template expression_operators>, + public alias_operators> { using _traits = make_traits; using _recursive_traits = make_recursive_traits; @@ -147,93 +147,93 @@ namespace sqlpp Rhs _rhs; }; - template - struct serializer_t> - { - using T = logical_not_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - context << "NOT "; - serialize(t._lhs, context); - context << ")"; - return context; - } - }; - - template - struct binary_expression_t: public value_type_of::template expression_operators>, - public alias_operators> + template + struct serializer_t> { - using _traits = make_traits, sqlpp::tag::expression>; - using _recursive_traits = make_recursive_traits; + using T = logical_not_t; - 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 - struct serializer_t> - { - using T = binary_expression_t; + template + struct binary_expression_t: public value_type_of::template expression_operators>, + public alias_operators> + { + using _traits = make_traits, sqlpp::tag::expression>; + using _recursive_traits = make_recursive_traits; - 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 - struct unary_expression_t: public value_type_of::template expression_operators>, - public alias_operators> + 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 + struct serializer_t> { - using _traits = make_traits, sqlpp::tag::expression>; - using _recursive_traits = make_recursive_traits; + using T = binary_expression_t; - 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 - struct serializer_t> - { - using T = unary_expression_t; + template + struct unary_expression_t: public value_type_of::template expression_operators>, + public alias_operators> + { + using _traits = make_traits, sqlpp::tag::expression>; + using _recursive_traits = make_recursive_traits; - 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 + struct serializer_t> + { + using T = unary_expression_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + context << O::_name; + serialize(t._rhs, context); + context << ")"; + return context; + } + }; } #endif diff --git a/include/sqlpp11/expression_fwd.h b/include/sqlpp11/expression_fwd.h index ed542c7d..2a389e5b 100644 --- a/include/sqlpp11/expression_fwd.h +++ b/include/sqlpp11/expression_fwd.h @@ -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 + template struct plus { using _traits = make_traits; static constexpr const char* _name = "+"; }; - template + template struct minus { using _traits = make_traits; static constexpr const char* _name = "-"; }; - template + template struct multiplies { using _traits = make_traits; 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 + template struct unary_minus { using _traits = make_traits; static constexpr const char* _name = "-"; }; - template + template struct unary_plus { using _traits = make_traits; static constexpr const char* _name = "+"; }; - } + } - template - struct binary_expression_t; + template + struct binary_expression_t; - template - struct unary_expression_t; + template + struct unary_expression_t; - template - using less_than_t = binary_expression_t; + template + using less_than_t = binary_expression_t; - template - using less_equal_t = binary_expression_t; + template + using less_equal_t = binary_expression_t; - template - using equal_to_t = binary_expression_t; + template + using equal_to_t = binary_expression_t; - template - using not_equal_to_t = binary_expression_t; + template + using not_equal_to_t = binary_expression_t; - template - using greater_than_t = binary_expression_t; + template + using greater_than_t = binary_expression_t; - template - using greater_equal_t = binary_expression_t; + template + using greater_equal_t = binary_expression_t; - template - using logical_and_t = binary_expression_t; + template + using logical_and_t = binary_expression_t; - template - using logical_or_t = binary_expression_t; + template + using logical_or_t = binary_expression_t; - template - using plus_t = binary_expression_t, Rhs>; + template + using plus_t = binary_expression_t, Rhs>; - template - using minus_t = binary_expression_t, Rhs>; + template + using minus_t = binary_expression_t, Rhs>; - template - using multiplies_t = binary_expression_t, Rhs>; + template + using multiplies_t = binary_expression_t, Rhs>; - template - using divides_t = binary_expression_t; + template + using divides_t = binary_expression_t; - template - using modulus_t = binary_expression_t; + template + using modulus_t = binary_expression_t; - template - using logical_not_t = unary_expression_t; + template + using logical_not_t = unary_expression_t; - template - using unary_plus_t = unary_expression_t, Rhs>; + template + using unary_plus_t = unary_expression_t, Rhs>; - template - using unary_minus_t = unary_expression_t, Rhs>; + template + using unary_minus_t = unary_expression_t, Rhs>; } diff --git a/include/sqlpp11/extra_tables.h b/include/sqlpp11/extra_tables.h index f660e92a..4b25a04f 100644 --- a/include/sqlpp11/extra_tables.h +++ b/include/sqlpp11/extra_tables.h @@ -33,86 +33,46 @@ namespace sqlpp { - template - 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 - struct extra_tables_t - { - using _traits = make_traits; - 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; - }; - - using _recursive_traits = make_recursive_traits; - - // 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::value, "at least one duplicate argument detected in extra_tables()"); - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a table or join in extra_tables()"); - - // Data - using _data_t = extra_tables_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = extra_tables_data_t; - - _impl_t extra_tables; - _impl_t& operator()() { return extra_tables; } - const _impl_t& operator()() const { return extra_tables; } - - template - static auto _get_member(T t) -> decltype(t.extra_tables) - { - return t.extra_tables; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - // NO EXTRA TABLES YET - struct no_extra_tables_t + template + struct extra_tables_data_t { - using _traits = make_traits; - 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 + struct extra_tables_t + { + using _traits = make_traits; + 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; + }; + + using _recursive_traits = make_recursive_traits; + + // 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::value, "at least one duplicate argument detected in extra_tables()"); + static_assert(::sqlpp::detail::all_t::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; // Member implementation with data and methods - template + template struct _impl_t { _data_t _data; @@ -122,46 +82,86 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = extra_tables_data_t; - _impl_t no_extra_tables; - _impl_t& operator()() { return no_extra_tables; } - const _impl_t& operator()() const { return no_extra_tables; } + _impl_t extra_tables; + _impl_t& operator()() { return extra_tables; } + const _impl_t& operator()() const { return extra_tables; } template - 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 struct _methods_t { - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto extra_tables(Args...) - -> _new_statement_t> - { - return { *static_cast(this), extra_tables_data_t{} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = extra_tables_data_t; + // NO EXTRA TABLES YET + struct no_extra_tables_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_extra_tables; + _impl_t& operator()() { return no_extra_tables; } + const _impl_t& operator()() const { return no_extra_tables; } + + template + static auto _get_member(T t) -> decltype(t.no_extra_tables) + { + return t.no_extra_tables; + } + }; + + template + struct _methods_t + { + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto extra_tables(Args...) + -> _new_statement_t> + { + return { *static_cast(this), extra_tables_data_t{} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = extra_tables_data_t; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + } #endif diff --git a/include/sqlpp11/field.h b/include/sqlpp11/field.h index 49a6abe6..1a5db815 100644 --- a/include/sqlpp11/field.h +++ b/include/sqlpp11/field.h @@ -31,40 +31,40 @@ namespace sqlpp { - template - struct field_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + template + struct field_t + { + using _traits = make_traits; + 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 - struct multi_field_t - { - }; - - namespace detail + template + struct multi_field_t { - template - struct make_field_t_impl - { - using type = field_t, - trivial_value_is_null_t::value>; - }; - - template - struct make_field_t_impl> - { - using type = multi_field_t::type...>>; - }; - } + }; + namespace detail + { template - using make_field_t = typename detail::make_field_t_impl::type; + struct make_field_t_impl + { + using type = field_t, + trivial_value_is_null_t::value>; + }; + + template + struct make_field_t_impl> + { + using type = multi_field_t::type...>>; + }; + } + + template + using make_field_t = typename detail::make_field_t_impl::type; } diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index bbed7aac..0b9b57b6 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -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 - 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::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::value; - if (connector_assert_result_validity_t::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 - 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::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::value; + if (connector_assert_result_validity_t::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 + 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 struct _is_valid_operand - { - static constexpr bool value = - is_expression_t::value // expressions are OK - and is_numeric_t::value // the correct value type is required, of course - ; - }; + { + static constexpr bool value = + is_expression_t::value // expressions are OK + and is_numeric_t::value // the correct value type is required, of course + ; + }; template struct expression_operators: public basic_expression_operators @@ -231,50 +231,50 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + { + template + auto operator +=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator -=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator -=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator /=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator /=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator *=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator *=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } - }; + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } + }; }; template - inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e) - { - return os << e.value(); - } + inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e) + { + return os << e.value(); + } } using floating_point = detail::floating_point; diff --git a/include/sqlpp11/from.h b/include/sqlpp11/from.h index efb8cedf..74babb1e 100644 --- a/include/sqlpp11/from.h +++ b/include/sqlpp11/from.h @@ -35,8 +35,8 @@ namespace sqlpp { - // FROM DATA - template + // FROM DATA + template struct from_data_t { from_data_t(Tables... tables): @@ -53,93 +53,54 @@ namespace sqlpp interpretable_list_t _dynamic_tables; }; - // FROM - template - struct from_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in from()"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a table or join in from()"); - - static_assert(required_tables_of::size::value == 0, "at least one table depends on another table"); - - // Data - using _data_t = from_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add(Table table) - { - static_assert(_is_dynamic::value, "from::add() must not be called for static from()"); - static_assert(is_table_t
::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
::value>; - - _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Table table, const std::true_type&) - { - return _data._dynamic_tables.emplace_back(table); - } - - template - void _add_impl(Table table, const std::false_type&); - - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = from_data_t; - - _impl_t from; - _impl_t& operator()() { return from; } - const _impl_t& operator()() const { return from; } - - template - static auto _get_member(T t) -> decltype(t.from) - { - return t.from; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - struct no_from_t + // FROM + template + struct from_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in from()"); + + static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a table or join in from()"); + + static_assert(required_tables_of::size::value == 0, "at least one table depends on another table"); // Data - using _data_t = no_data_t; + using _data_t = from_data_t; // Member implementation with data and methods template struct _impl_t { + template + void add(Table table) + { + static_assert(_is_dynamic::value, "from::add() must not be called for static from()"); + static_assert(is_table_t
::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
::value>; + + _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Table table, const std::true_type&) + { + return _data._dynamic_tables.emplace_back(table); + } + + template + void _add_impl(Table table, const std::false_type&); + + public: _data_t _data; }; @@ -147,16 +108,16 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = from_data_t; - _impl_t no_from; - _impl_t& operator()() { return no_from; } - const _impl_t& operator()() const { return no_from; } + _impl_t from; + _impl_t& operator()() { return from; } + const _impl_t& operator()() const { return from; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto from(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), from_data_t{args...} }; - } - - template - auto dynamic_from(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement"); - return { *static_cast(this), from_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = from_data_t; + struct no_from_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_from; + _impl_t& operator()() { return no_from; } + const _impl_t& operator()() const { return no_from; } + + template + static auto _get_member(T t) -> decltype(t.no_from) + { + return t.no_from; + } + }; + + // Additional methods for the statement + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto from(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), from_data_t{args...} }; + } + + template + auto dynamic_from(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement"); + return { *static_cast(this), from_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = from_data_t; + + 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 diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 3896c23e..a01aa323 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -55,8 +55,8 @@ namespace sqlpp } template // Csaba Csoma suggests: unsafe_sql instead of verbatim - struct verbatim_t: public ValueType::template expression_operators>, - public alias_operators> + struct verbatim_t: public ValueType::template expression_operators>, + public alias_operators> { using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; @@ -71,17 +71,17 @@ namespace sqlpp std::string _verbatim; }; - template - struct serializer_t> - { - using T = verbatim_t; + template + struct serializer_t> + { + using T = verbatim_t; - 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 auto verbatim(StringType s) -> verbatim_t @@ -119,26 +119,26 @@ namespace sqlpp _container_t _container; }; - template - struct serializer_t> + template + struct serializer_t> + { + using T = value_list_t; + + static Context& _(const T& t, Context& context) { - using T = value_list_t; - - 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 auto value_list(Container c) -> value_list_t diff --git a/include/sqlpp11/group_by.h b/include/sqlpp11/group_by.h index 0b059201..8e369b0c 100644 --- a/include/sqlpp11/group_by.h +++ b/include/sqlpp11/group_by.h @@ -37,113 +37,74 @@ namespace sqlpp { - // GROUP BY DATA - template - 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; - interpretable_list_t _dynamic_expressions; - }; - - // GROUP BY - template - struct group_by_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in group_by()"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an expression in group_by()"); - - // Data - using _data_t = group_by_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Expression expression) - { - add(expression); - } - - template - void add(Expression expression) - { - static_assert(_is_dynamic::value, "add() must not be called for static group_by"); - static_assert(is_expression_t::value, "invalid expression argument in group_by::add()"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in group_by::add()"); - - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; - - _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Expression expression, const std::true_type&) - { - return _data._dynamic_expressions.emplace_back(expression); - } - - template - void _add_impl(Expression expression, const std::false_type&); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = group_by_data_t; - - _impl_t group_by; - _impl_t& operator()() { return group_by; } - const _impl_t& operator()() const { return group_by; } - - template - static auto _get_member(T t) -> decltype(t.group_by) - { - return t.group_by; - } - }; - - template - struct _methods_t - { - }; - }; - - // NO GROUP BY YET - struct no_group_by_t + // GROUP BY DATA + template + struct group_by_data_t { - using _traits = make_traits; - 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; + interpretable_list_t _dynamic_expressions; + }; + + // GROUP BY + template + struct group_by_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in group_by()"); + + static_assert(::sqlpp::detail::all_t::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; // Member implementation with data and methods template struct _impl_t { + template + void add_ntc(Expression expression) + { + add(expression); + } + + template + void add(Expression expression) + { + static_assert(_is_dynamic::value, "add() must not be called for static group_by"); + static_assert(is_expression_t::value, "invalid expression argument in group_by::add()"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in group_by::add()"); + + using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; + + _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Expression expression, const std::true_type&) + { + return _data._dynamic_expressions.emplace_back(expression); + } + + template + void _add_impl(Expression expression, const std::false_type&); + public: _data_t _data; }; @@ -151,61 +112,100 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = group_by_data_t; - _impl_t no_group_by; - _impl_t& operator()() { return no_group_by; } - const _impl_t& operator()() const { return no_group_by; } + _impl_t group_by; + _impl_t& operator()() { return group_by; } + const _impl_t& operator()() const { return group_by; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto group_by(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), group_by_data_t{args...} }; - } - - template - auto dynamic_group_by(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement"); - return { *static_cast(this), group_by_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = group_by_data_t; + // NO GROUP BY YET + struct no_group_by_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_group_by; + _impl_t& operator()() { return no_group_by; } + const _impl_t& operator()() const { return no_group_by; } + + template + static auto _get_member(T t) -> decltype(t.no_group_by) + { + return t.no_group_by; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto group_by(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), group_by_data_t{args...} }; + } + + template + auto dynamic_group_by(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement"); + return { *static_cast(this), group_by_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = group_by_data_t; + + 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 diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index 483b45ae..d50f5600 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -36,112 +36,72 @@ namespace sqlpp { - // HAVING DATA - template - 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; - interpretable_list_t _dynamic_expressions; - }; - - // HAVING - template - struct having_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::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::value...>::value, "at least one argument is not an expression in having()"); - - // Data - using _data_t = having_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Expression expression) - { - add(expression); - } - - template - void add(Expression expression) - { - static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having"); - static_assert(is_expression_t::value, "invalid expression argument in having::add()"); - static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in having::add()"); - - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; - - _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Expression expression, const std::true_type&) - { - return _data._dynamic_expressions.emplace_back(expression); - } - - template - void _add_impl(Expression expression, const std::false_type&); - - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = having_data_t; - - _impl_t having; - _impl_t& operator()() { return having; } - const _impl_t& operator()() const { return having; } - - template - static auto _get_member(T t) -> decltype(t.having) - { - return t.having; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - // NO HAVING YET - struct no_having_t + // HAVING DATA + template + struct having_data_t { - using _traits = make_traits; - 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; + interpretable_list_t _dynamic_expressions; + }; + + // HAVING + template + struct having_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::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::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; // Member implementation with data and methods - template + template struct _impl_t { + template + void add_ntc(Expression expression) + { + add(expression); + } + + template + void add(Expression expression) + { + static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having"); + static_assert(is_expression_t::value, "invalid expression argument in having::add()"); + static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in having::add()"); + + using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; + + _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Expression expression, const std::true_type&) + { + return _data._dynamic_expressions.emplace_back(expression); + } + + template + void _add_impl(Expression expression, const std::false_type&); + + public: _data_t _data; }; @@ -149,61 +109,101 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = having_data_t; - _impl_t no_having; - _impl_t& operator()() { return no_having; } - const _impl_t& operator()() const { return no_having; } + _impl_t having; + _impl_t& operator()() { return having; } + const _impl_t& operator()() const { return having; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto having(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), having_data_t{args...} }; - } - - template - auto dynamic_having(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement"); - return { *static_cast(this), having_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = having_data_t; + // NO HAVING YET + struct no_having_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_having; + _impl_t& operator()() { return no_having; } + const _impl_t& operator()() const { return no_having; } + + template + static auto _get_member(T t) -> decltype(t.no_having) + { + return t.no_having; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto having(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), having_data_t{args...} }; + } + + template + auto dynamic_having(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement"); + return { *static_cast(this), having_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = having_data_t; + + 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 diff --git a/include/sqlpp11/in.h b/include/sqlpp11/in.h index 76b9ed77..5ec661b4 100644 --- a/include/sqlpp11/in.h +++ b/include/sqlpp11/in.h @@ -34,55 +34,55 @@ namespace sqlpp { - template - struct in_t: public boolean::template expression_operators>, - public alias_operators> + template + struct in_t: public boolean::template expression_operators>, + public alias_operators> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static constexpr bool _inverted = not NotInverted; + static_assert(sizeof...(Args) > 0, "in() requires at least one argument"); + + struct _name_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - 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 - 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; + static constexpr const char* _get_name() { return _inverted ? "NOT IN" : "IN"; } + template + struct _member_t + { + T in; + }; }; - template - struct serializer_t> - { - using T = in_t; + 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; + }; + + template + struct serializer_t> + { + using T = in_t; + + 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; + } + }; } diff --git a/include/sqlpp11/in_fwd.h b/include/sqlpp11/in_fwd.h index 9b2e06a4..3b464307 100644 --- a/include/sqlpp11/in_fwd.h +++ b/include/sqlpp11/in_fwd.h @@ -29,7 +29,7 @@ namespace sqlpp { - template + template struct in_t; } diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index eeb08f4b..491d9a8c 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -43,24 +43,24 @@ namespace sqlpp struct insert_t: public statement_name_t {}; - template - struct serializer_t + template + struct serializer_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 using blank_insert_t = statement_t; + insert_t, + no_into_t, + no_insert_value_list_t>; auto insert() -> blank_insert_t diff --git a/include/sqlpp11/insert_value.h b/include/sqlpp11/insert_value.h index d9c0f4e1..1be64b10 100644 --- a/include/sqlpp11/insert_value.h +++ b/include/sqlpp11/insert_value.h @@ -36,85 +36,85 @@ namespace sqlpp { - namespace detail + namespace detail + { + template + struct type_if + { + using type = Type; + }; + + template + struct type_if + { + struct type + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + }; + }; + } + + template + struct insert_value_t { - template - struct type_if - { - using type = Type; - }; + using _is_insert_value = std::true_type; + using _pure_value_t = typename value_type_of::_cpp_value_type; + using _wrapped_value_t = typename wrap_operand<_pure_value_t>::type; + using _tvin_t = typename detail::type_if, can_be_null_t::value>::type; // static asserts and SFINAE do not work together + using _null_t = typename detail::type_if::value>::type; // static asserts and SFINAE do not work together - template - struct type_if - { - struct type - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - }; - }; - } + insert_value_t(assignment_t assignment): + _is_null(false), + _is_default(false), + _value(assignment._rhs) + {} - template - struct insert_value_t + insert_value_t(assignment_t assignment): + _is_null(assignment._rhs._is_trivial()), + _is_default(false), + _value(assignment._rhs._value) + {} + + insert_value_t(const assignment_t&): + _is_null(true), + _is_default(false), + _value() + {} + + insert_value_t(const assignment_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 + struct serializer_t> + { + using T = insert_value_t; + + static Context& _(const T& t, Context& context) { - using _is_insert_value = std::true_type; - using _pure_value_t = typename value_type_of::_cpp_value_type; - using _wrapped_value_t = typename wrap_operand<_pure_value_t>::type; - using _tvin_t = typename detail::type_if, can_be_null_t::value>::type; // static asserts and SFINAE do not work together - using _null_t = typename detail::type_if::value>::type; // static asserts and SFINAE do not work together - - insert_value_t(assignment_t assignment): - _is_null(false), - _is_default(false), - _value(assignment._rhs) - {} - - insert_value_t(assignment_t assignment): - _is_null(assignment._rhs._is_trivial()), - _is_default(false), - _value(assignment._rhs._value) - {} - - insert_value_t(const assignment_t&): - _is_null(true), - _is_default(false), - _value() - {} - - insert_value_t(const assignment_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 - struct serializer_t> - { - using T = insert_value_t; - - 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; + } + }; } diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index ea3676f3..831a6752 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -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; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = insert_default_values_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = insert_default_values_data_t; + + _impl_t default_values; + _impl_t& operator()() { return default_values; } + const _impl_t& operator()() const { return default_values; } + + template + static auto _get_member(T t) -> decltype(t.default_values) + { + return t.default_values; + } + }; + + template + struct _methods_t + {}; + }; + + template + struct insert_list_data_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - - // Data - using _data_t = insert_default_values_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = insert_default_values_data_t; - - _impl_t default_values; - _impl_t& operator()() { return default_values; } - const _impl_t& operator()() const { return default_values; } - - template - static auto _get_member(T t) -> decltype(t.default_values) - { - return t.default_values; - } - }; - - template - struct _methods_t - {}; - }; - - template - 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...> _columns; - std::tuple _values; - std::tuple _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments) - interpretable_list_t _dynamic_columns; - interpretable_list_t _dynamic_values; - }; - - template - struct insert_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - template class Target> - using copy_assignments_t = Target; // FIXME: Nice idea to copy variadic template arguments? - template class Target, template class Wrap> - using copy_wrapped_assignments_t = Target...>; - - static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()"); - - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - - static_assert(sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); - - static_assert(sqlpp::detail::none_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::type; - using _value_required_tables = typename ::sqlpp::detail::make_joined_set::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; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Assignment assignment) - { - add(assignment); - } - - template - void add(Assignment assignment) - { - static_assert(_is_dynamic::value, "add must not be called for static from()"); - static_assert(is_assignment_t::value, "add() arguments require to be assigments"); - static_assert(not must_not_insert_t::value, "add() argument must not be used in insert"); - static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "add() contains a column from a foreign table"); - - using ok = ::sqlpp::detail::all_t< - _is_dynamic::value, - is_assignment_t::value, - not must_not_insert_t::value, - (not TableCheckRequired::value or Policies::template _no_unknown_tables::value)>; - - _add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Assignment assignment, const std::true_type&) - { - _data._dynamic_columns.emplace_back(simple_column_t{assignment._lhs}); - _data._dynamic_values.emplace_back(assignment._rhs); - } - - template - void _add_impl(Assignment assignment, const std::false_type&); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = insert_list_data_t; - - _impl_t insert_list; - _impl_t& operator()() { return insert_list; } - const _impl_t& operator()() const { return insert_list; } - - template - static auto _get_member(T t) -> decltype(t.insert_list) - { - return t.insert_list; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - - - - }; - - template - struct column_list_data_t - { - column_list_data_t(Columns... columns): - _columns(simple_column_t{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...>; - std::tuple...> _columns; - std::vector<_value_tuple_t> _insert_values; - }; + std::tuple...> _columns; + std::tuple _values; + std::tuple _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments) + interpretable_list_t _dynamic_columns; + interpretable_list_t _dynamic_values; + }; - template - struct column_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - static_assert(sizeof...(Columns), "at least one column required in columns()"); - - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in columns()"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a column in columns()"); - - static_assert(::sqlpp::detail::none_t::value...>::value, "at least one column argument has a must_not_insert flag in its definition"); - - using _value_tuple_t = std::tuple...>; - - static_assert(required_tables_of::size::value == 1, "columns from multiple tables in columns()"); - - // Data - using _data_t = column_list_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add(Assignments... assignments) - { - static_assert(::sqlpp::detail::all_t::value...>::value, "add_values() arguments have to be assignments"); - using _arg_value_tuple = std::tuple...>; - 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::value...>::value, - _args_correct::value>; - - _add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(const std::true_type&, Assignments... assignments) - { - return _data._insert_values.emplace_back(insert_value_t{assignments}...); - } - - template - void _add_impl(const std::false_type&, Assignments... assignments); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = column_list_data_t; - - _impl_t values; - _impl_t& operator()() { return values; } - const _impl_t& operator()() const { return values; } - - template - static auto _get_member(T t) -> decltype(t.values) - { - return t.values; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - -/* - bool empty() const - { - return _insert_values.empty(); - } - */ - - }; - - // NO HAVING YET - struct no_insert_value_list_t + template + struct insert_list_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + + template class Target> + using copy_assignments_t = Target; // FIXME: Nice idea to copy variadic template arguments? + template class Target, template class Wrap> + using copy_wrapped_assignments_t = Target...>; + + static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()"); + + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); + + static_assert(sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); + + static_assert(sqlpp::detail::none_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::type; + using _value_required_tables = typename ::sqlpp::detail::make_joined_set::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; // Member implementation with data and methods - template + template struct _impl_t { + template + void add_ntc(Assignment assignment) + { + add(assignment); + } + + template + void add(Assignment assignment) + { + static_assert(_is_dynamic::value, "add must not be called for static from()"); + static_assert(is_assignment_t::value, "add() arguments require to be assigments"); + static_assert(not must_not_insert_t::value, "add() argument must not be used in insert"); + static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "add() contains a column from a foreign table"); + + using ok = ::sqlpp::detail::all_t< + _is_dynamic::value, + is_assignment_t::value, + not must_not_insert_t::value, + (not TableCheckRequired::value or Policies::template _no_unknown_tables::value)>; + + _add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Assignment assignment, const std::true_type&) + { + _data._dynamic_columns.emplace_back(simple_column_t{assignment._lhs}); + _data._dynamic_values.emplace_back(assignment._rhs); + } + + template + void _add_impl(Assignment assignment, const std::false_type&); + public: _data_t _data; }; @@ -326,124 +179,271 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = insert_list_data_t; - _impl_t no_insert_values; - _impl_t& operator()() { return no_insert_values; } - const _impl_t& operator()() const { return no_insert_values; } + _impl_t insert_list; + _impl_t& operator()() { return insert_list; } + const _impl_t& operator()() const { return insert_list; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - auto default_values() - -> _new_statement_t - { - return { *static_cast(this), insert_default_values_data_t{} }; - } - - template - auto columns(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), column_list_data_t{args...} }; - } - - template - auto set(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), insert_list_data_t{args...} }; - } - - template - auto dynamic_set(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement"); - return { *static_cast(this), insert_list_data_t<_database_t, Args...>{args...} }; - } }; + + + }; - // Interpreters - template - struct serializer_t - { - using T = insert_default_values_data_t; + template + struct column_list_data_t + { + column_list_data_t(Columns... columns): + _columns(simple_column_t{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...>; + std::tuple...> _columns; + std::vector<_value_tuple_t> _insert_values; + }; + + template + struct column_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static_assert(sizeof...(Columns), "at least one column required in columns()"); + + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in columns()"); + + static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a column in columns()"); + + static_assert(::sqlpp::detail::none_t::value...>::value, "at least one column argument has a must_not_insert flag in its definition"); + + using _value_tuple_t = std::tuple...>; + + static_assert(required_tables_of::size::value == 1, "columns from multiple tables in columns()"); + + // Data + using _data_t = column_list_data_t; + + // Member implementation with data and methods + template + struct _impl_t { - context << " DEFAULT VALUES"; - return context; - } + template + void add(Assignments... assignments) + { + static_assert(::sqlpp::detail::all_t::value...>::value, "add_values() arguments have to be assignments"); + using _arg_value_tuple = std::tuple...>; + 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::value...>::value, + _args_correct::value>; + + _add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(const std::true_type&, Assignments... assignments) + { + return _data._insert_values.emplace_back(insert_value_t{assignments}...); + } + + template + void _add_impl(const std::false_type&, Assignments... assignments); + public: + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = column_list_data_t; + + _impl_t values; + _impl_t& operator()() { return values; } + const _impl_t& operator()() const { return values; } + + template + static auto _get_member(T t) -> decltype(t.values) + { + return t.values; + } + }; + + // Additional methods for the statement + template + struct _methods_t + { + }; + + /* + bool empty() const + { + return _insert_values.empty(); + } + */ + + }; + + // NO HAVING YET + struct no_insert_value_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = no_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + _data_t _data; }; - template - struct serializer_t> + // Member template for adding the named member to a statement + template + struct _member_t { - using T = column_list_data_t; + using _data_t = no_data_t; - static Context& _(const T& t, Context& context) + _impl_t no_insert_values; + _impl_t& operator()() { return no_insert_values; } + const _impl_t& operator()() const { return no_insert_values; } + + template + static auto _get_member(T t) -> decltype(t.no_insert_values) + { + return t.no_insert_values; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + auto default_values() + -> _new_statement_t + { + return { *static_cast(this), insert_default_values_data_t{} }; + } + + template + auto columns(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), column_list_data_t{args...} }; + } + + template + auto set(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), insert_list_data_t{args...} }; + } + + template + auto dynamic_set(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement"); + return { *static_cast(this), insert_list_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t + { + using T = insert_default_values_data_t; + + static Context& _(const T& t, Context& context) + { + context << " DEFAULT VALUES"; + return context; + } + }; + + template + struct serializer_t> + { + using T = column_list_data_t; + + 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 + struct serializer_t> + { + using T = insert_list_data_t; + + 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 - struct serializer_t> - { - using T = insert_list_data_t; - - 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; + } + }; } diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index 47fc007c..2b52fb6e 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -45,7 +45,7 @@ namespace sqlpp using _traits = make_traits; 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 - 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::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::value; - if (connector_assert_result_validity_t::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 - 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::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::value; + if (connector_assert_result_validity_t::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 + 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 struct _is_valid_operand - { - static constexpr bool value = - is_expression_t::value // expressions are OK - and is_numeric_t::value // the correct value type is required, of course - ; - }; + { + static constexpr bool value = + is_expression_t::value // expressions are OK + and is_numeric_t::value // the correct value type is required, of course + ; + }; template struct expression_operators: public basic_expression_operators @@ -243,50 +243,50 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> assignment_t, wrap_operand_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + { + template + auto operator +=(T t) const -> assignment_t, wrap_operand_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator -=(T t) const -> assignment_t, wrap_operand_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator -=(T t) const -> assignment_t, wrap_operand_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator /=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator /=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } - template - auto operator *=(T t) const -> assignment_t, wrap_operand_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + template + auto operator *=(T t) const -> assignment_t, wrap_operand_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } - }; + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } + }; }; template - inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e) - { - return os << e.value(); - } + inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e) + { + return os << e.value(); + } } using tinyint = detail::integral; diff --git a/include/sqlpp11/interpret_tuple.h b/include/sqlpp11/interpret_tuple.h index aa12c9b8..04ac5d4a 100644 --- a/include/sqlpp11/interpret_tuple.h +++ b/include/sqlpp11/interpret_tuple.h @@ -50,7 +50,7 @@ namespace sqlpp auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const ::sqlpp::detail::index_sequence&) -> 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 diff --git a/include/sqlpp11/interpretable.h b/include/sqlpp11/interpretable.h index faa6a133..28a2413b 100644 --- a/include/sqlpp11/interpretable.h +++ b/include/sqlpp11/interpretable.h @@ -35,94 +35,94 @@ namespace sqlpp { - template - struct interpretable_t + template + struct interpretable_t + { + using _serializer_context_t = typename Db::_serializer_context_t; + using _interpreter_context_t = typename Db::_interpreter_context_t; + + template + interpretable_t(T t): + _impl(std::make_shared<_impl_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 - interpretable_t(T t): - _impl(std::make_shared<_impl_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 + // This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same + template auto serialize(Context& context) const -> typename std::enable_if::value - and not std::is_same::value, Context&>::type + and not std::is_same::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 - struct _impl_t: public _impl_base - { - static_assert(not make_parameter_list_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 _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 - struct serializer_t> + template + struct _impl_t: public _impl_base { - using T = interpretable_t; + static_assert(not make_parameter_list_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 _impl; + }; + + template + struct serializer_t> + { + using T = interpretable_t; + + static Context& _(const T& t, Context& context) + { + t.serialize(context); + return context; + } + }; + } #endif diff --git a/include/sqlpp11/interpretable_list.h b/include/sqlpp11/interpretable_list.h index 8c9367d0..e3641972 100644 --- a/include/sqlpp11/interpretable_list.h +++ b/include/sqlpp11/interpretable_list.h @@ -32,85 +32,85 @@ namespace sqlpp { - template - struct interpretable_list_t + template + struct interpretable_list_t + { + std::vector> _serializables; + + std::size_t size() const { - std::vector> _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 + template void emplace_back(Expr expr) { _serializables.emplace_back(expr); } - }; + }; - template<> - struct interpretable_list_t + template<> + struct interpretable_list_t + { + static constexpr std::size_t size() { - static constexpr std::size_t size() - { - return 0; - } - - static constexpr bool empty() - { - return true; - } - - }; - - template - struct serializable_list_interpreter_t - { - using T = List; - - template - 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 - struct serializable_list_interpreter_t> - { - using T = interpretable_list_t; - - template - static Context& _(const T& t, const Separator& separator, Context& context) - { - return context; - } - }; - - template - auto interpret_list(const T& t, const Separator& separator, Context& context) - -> decltype(serializable_list_interpreter_t::_(t, separator, context)) - { - return serializable_list_interpreter_t::_(t, separator, context); + return 0; } + static constexpr bool empty() + { + return true; + } + + }; + + template + struct serializable_list_interpreter_t + { + using T = List; + + template + 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 + struct serializable_list_interpreter_t> + { + using T = interpretable_list_t; + + template + static Context& _(const T& t, const Separator& separator, Context& context) + { + return context; + } + }; + + template + auto interpret_list(const T& t, const Separator& separator, Context& context) + -> decltype(serializable_list_interpreter_t::_(t, separator, context)) + { + return serializable_list_interpreter_t::_(t, separator, context); + } + } #endif diff --git a/include/sqlpp11/interpreter.h b/include/sqlpp11/interpreter.h index f58f0940..cd7c9690 100644 --- a/include/sqlpp11/interpreter.h +++ b/include/sqlpp11/interpreter.h @@ -31,14 +31,14 @@ namespace sqlpp { - template - struct interpreter_t + template + struct interpreter_t + { + static void _(const T& t, Context& context) { - static void _(const T& t, Context& context) - { - static_assert(wrong_t::value, "missing interpreter specialization"); - } - }; + static_assert(wrong_t::value, "missing interpreter specialization"); + } + }; } diff --git a/include/sqlpp11/into.h b/include/sqlpp11/into.h index f65857cd..9395e840 100644 --- a/include/sqlpp11/into.h +++ b/include/sqlpp11/into.h @@ -34,110 +34,39 @@ namespace sqlpp { - // A SINGLE TABLE DATA - template - 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 - struct into_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits
; - - static_assert(is_table_t
::value, "argument has to be a table"); - static_assert(required_tables_of
::size::value == 0, "table depends on another table"); - - using _data_t = into_data_t; - - struct _name_t {}; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = into_data_t; - - _impl_t into; - _impl_t& operator()() { return into; } - const _impl_t& operator()() const { return into; } - - template - static auto _get_member(T t) -> decltype(t.into) - { - return t.into; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - - template - struct _result_methods_t - { - using _statement_t = typename Policies::_statement_t; - - const _statement_t& _get_statement() const - { - return static_cast(*this); - } - - template - 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 - auto _prepare(Db& db) const - -> prepared_insert_t - { - _statement_t::_check_consistency(); - - return {{}, db.prepare_insert(*this)}; - } - */ - }; - }; - - // NO INTO YET - struct no_into_t + // A SINGLE TABLE DATA + template + struct into_data_t { - using _traits = make_traits; - 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 + struct into_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits
; + + static_assert(is_table_t
::value, "argument has to be a table"); + static_assert(required_tables_of
::size::value == 0, "table depends on another table"); + + using _data_t = into_data_t; + + struct _name_t {}; // Member implementation with data and methods - template + template struct _impl_t { _data_t _data; @@ -147,49 +76,120 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = into_data_t; - _impl_t no_into; - _impl_t& operator()() { return no_into; } - const _impl_t& operator()() const { return no_into; } + _impl_t into; + _impl_t& operator()() { return into; } + const _impl_t& operator()() const { return into; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; + }; - template - auto into(Args... args) - -> _new_statement_t> + template + struct _result_methods_t + { + using _statement_t = typename Policies::_statement_t; + + const _statement_t& _get_statement() const + { + return static_cast(*this); + } + + template + auto _run(Db& db) const -> decltype(db.insert(_get_statement())) { - return { *static_cast(this), into_data_t{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 + auto _prepare(Db& db) const + -> prepared_insert_t + { + _statement_t::_check_consistency(); + + return {{}, db.prepare_insert(*this)}; + } + */ }; }; - // Interpreters - template - struct serializer_t> - { - using T = into_data_t; + // NO INTO YET + struct no_into_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_into; + _impl_t& operator()() { return no_into; } + const _impl_t& operator()() const { return no_into; } + + template + static auto _get_member(T t) -> decltype(t.no_into) + { + return t.no_into; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto into(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), into_data_t{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = into_data_t; + + static Context& _(const T& t, Context& context) + { + context << " INTO "; + serialize(t._table, context); + return context; + } + }; + } #endif diff --git a/include/sqlpp11/is_null.h b/include/sqlpp11/is_null.h index 5dc584dd..1aedf49a 100644 --- a/include/sqlpp11/is_null.h +++ b/include/sqlpp11/is_null.h @@ -33,55 +33,55 @@ namespace sqlpp { - template + template struct is_null_t: public boolean::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static constexpr bool _inverted = not NotInverted; + + struct _value_type: public boolean { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - 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 - 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 - struct serializer_t> - { - using T = ::sqlpp::is_null_t; - - static Context& _(const T& t, Context& context) + struct _name_t + { + static constexpr const char* _get_name() { return _inverted ? "IS NOT NULL" : "IS NULL"; } + template + 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 + struct serializer_t> + { + using T = ::sqlpp::is_null_t; + + static Context& _(const T& t, Context& context) + { + serialize(t._operand, context); + context << (t._inverted ? " IS NOT NULL" : " IS NULL"); + return context; + } + }; } diff --git a/include/sqlpp11/is_null_fwd.h b/include/sqlpp11/is_null_fwd.h index 0a866b3d..8d53cc01 100644 --- a/include/sqlpp11/is_null_fwd.h +++ b/include/sqlpp11/is_null_fwd.h @@ -29,7 +29,7 @@ namespace sqlpp { - template + template struct is_null_t; } diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 811fb0c5..9d0a92f4 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -143,22 +143,22 @@ namespace sqlpp On _on; }; - template - struct serializer_t> - { - using T = join_t; + template + struct serializer_t> + { + using T = join_t; - static Context& _(const T& t, Context& context) - { - static_assert(not is_noop::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::value, "joined tables require on()"); + serialize(t._lhs, context); + context << JoinType::_name; + context << " JOIN "; + serialize(t._rhs, context); + serialize(t._on, context); + return context; + } + }; } diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h index 10b987ed..46f1572a 100644 --- a/include/sqlpp11/like.h +++ b/include/sqlpp11/like.h @@ -33,55 +33,55 @@ namespace sqlpp { - template - struct like_t: public boolean::template expression_operators>, - public alias_operators> + template + struct like_t: public boolean::template expression_operators>, + public alias_operators> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static_assert(is_text_t::value, "Operand for like() has to be a text"); + static_assert(is_text_t::value, "Pattern for like() has to be a text"); + + struct _name_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - static_assert(is_text_t::value, "Operand for like() has to be a text"); - static_assert(is_text_t::value, "Pattern for like() has to be a text"); - - struct _name_t - { - static constexpr const char* _get_name() { return "LIKE"; } - template - 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 + struct _member_t + { + T like; + }; }; - template - struct serializer_t> - { - using T = like_t; + 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 + struct serializer_t> + { + using T = like_t; + + static Context& _(const T& t, Context& context) + { + serialize(t._operand, context); + context << " LIKE("; + serialize(t._pattern, context); + context << ")"; + return context; + } + }; } #endif diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/limit.h index 61e94d06..99a31928 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/limit.h @@ -33,151 +33,37 @@ namespace sqlpp { - // LIMIT DATA - template - 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 - struct limit_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - static_assert(is_integral_t::value, "limit requires an integral value or integral parameter"); - - // Data - using _data_t = limit_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = limit_data_t; - - _impl_t limit; - _impl_t& operator()() { return limit; } - const _impl_t& operator()() const { return limit; } - - template - static auto _get_member(T t) -> decltype(t.limit) - { - return t.limit; - } - }; - - template - struct _methods_t - { - }; - }; - - // DYNAMIC LIMIT DATA - template - struct dynamic_limit_data_t - { - dynamic_limit_data_t(): - _value(noop()) - { - } - - template - dynamic_limit_data_t(Limit value): - _initialized(true), - _value(typename wrap_operand::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 _value; - }; - - // DYNAMIC LIMIT - template - struct dynamic_limit_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - - // Data - using _data_t = dynamic_limit_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - 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::type; - _data._value = arg_t{value}; - _data._initialized = true; - } - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = dynamic_limit_data_t; - - _impl_t limit; - _impl_t& operator()() { return limit; } - const _impl_t& operator()() const { return limit; } - - template - static auto _get_member(T t) -> decltype(t.limit) - { - return t.limit; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - struct no_limit_t + // LIMIT DATA + template + struct limit_data_t { - using _traits = make_traits; - 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 + struct limit_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static_assert(is_integral_t::value, "limit requires an integral value or integral parameter"); // Data - using _data_t = no_data_t; + using _data_t = limit_data_t; // Member implementation with data and methods - template + template struct _impl_t { _data_t _data; @@ -187,71 +73,185 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = limit_data_t; - _impl_t no_limit; - _impl_t& operator()() { return no_limit; } - const _impl_t& operator()() const { return no_limit; } + _impl_t limit; + _impl_t& operator()() { return limit; } + const _impl_t& operator()() const { return limit; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto limit(Arg arg) - -> _new_statement_t::type>> - { - return { *static_cast(this), limit_data_t::type>{{arg}} }; - } - - auto dynamic_limit() - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement"); - return { *static_cast(this), dynamic_limit_data_t<_database_t>{} }; - } }; }; - // Interpreters - template - struct serializer_t> + // DYNAMIC LIMIT DATA + template + struct dynamic_limit_data_t + { + dynamic_limit_data_t(): + _value(noop()) { - using T = dynamic_limit_data_t; + } - static Context& _(const T& t, Context& context) + template + dynamic_limit_data_t(Limit value): + _initialized(true), + _value(typename wrap_operand::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 _value; + }; + + // DYNAMIC LIMIT + template + struct dynamic_limit_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = dynamic_limit_data_t; + + // Member implementation with data and methods + template + struct _impl_t { - if (t._initialized) - { - context << " LIMIT "; - serialize(t._value, context); - } - return context; - } + template + 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::type; + _data._value = arg_t{value}; + _data._initialized = true; + } + public: + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = dynamic_limit_data_t; + + _impl_t limit; + _impl_t& operator()() { return limit; } + const _impl_t& operator()() const { return limit; } + + template + static auto _get_member(T t) -> decltype(t.limit) + { + return t.limit; + } + }; + + // Additional methods for the statement + template + struct _methods_t + { + }; + }; + + struct no_limit_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = no_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + _data_t _data; }; - template - struct serializer_t> + // Member template for adding the named member to a statement + template + struct _member_t { - using T = limit_data_t; + using _data_t = no_data_t; - static Context& _(const T& t, Context& context) + _impl_t no_limit; + _impl_t& operator()() { return no_limit; } + const _impl_t& operator()() const { return no_limit; } + + template + static auto _get_member(T t) -> decltype(t.no_limit) + { + return t.no_limit; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto limit(Arg arg) + -> _new_statement_t::type>> + { + return { *static_cast(this), limit_data_t::type>{{arg}} }; + } + + auto dynamic_limit() + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement"); + return { *static_cast(this), dynamic_limit_data_t<_database_t>{} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = dynamic_limit_data_t; + + static Context& _(const T& t, Context& context) + { + if (t._initialized) { context << " LIMIT "; serialize(t._value, context); - return context; } - }; + return context; + } + }; + + template + struct serializer_t> + { + using T = limit_data_t; + + static Context& _(const T& t, Context& context) + { + context << " LIMIT "; + serialize(t._value, context); + return context; + } + }; } #endif diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index 78cb12f9..46489282 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -31,53 +31,53 @@ namespace sqlpp { - template + template struct max_t: public value_type_of::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; + + static_assert(is_expression_t::value, "max() requires a value expression as argument"); + + struct _name_t { - using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; - using _recursive_traits = make_recursive_traits; - - static_assert(is_expression_t::value, "max() requires a value expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "MAX"; } - template - 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 + struct _member_t + { + T max; + T& operator()() { return max; } + const T& operator()() const { return max; } + }; }; - template - struct serializer_t> - { - using T = max_t; + 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 + struct serializer_t> + { + using T = max_t; + + static Context& _(const T& t, Context& context) + { + context << "MAX("; + serialize(t._expr, context); + context << ")"; + return context; + } + }; template auto max(T t) -> typename max_t> diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index 28e72f21..0ae1248a 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -31,53 +31,53 @@ namespace sqlpp { - template + template struct min_t: public value_type_of::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; + + static_assert(is_expression_t::value, "min() requires a value expression as argument"); + + struct _name_t { - using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; - using _recursive_traits = make_recursive_traits; - - static_assert(is_expression_t::value, "min() requires a value expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "MIN"; } - template - 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 + struct _member_t + { + T min; + T& operator()() { return min; } + const T& operator()() const { return min; } + }; }; - template - struct serializer_t> - { - using T = min_t; + 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 + struct serializer_t> + { + using T = min_t; + + static Context& _(const T& t, Context& context) + { + context << "MIN("; + serialize(t._expr, context); + context << ")"; + return context; + } + }; template auto min(T t) -> typename min_t> diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index 6484ba96..52de9d5f 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -110,28 +110,28 @@ namespace sqlpp std::tuple _columns; }; - template - struct serializer_t> + template + struct serializer_t> + { + using T = multi_column_t; + + static void _(const T& t, Context& context) { - using T = multi_column_t; + static_assert(wrong_t::value, "multi_column must be used with an alias"); + } + }; - static void _(const T& t, Context& context) - { - static_assert(wrong_t::value, "multi_column must be used with an alias"); - } - }; + template + struct serializer_t> + { + using T = multi_column_alias_t; - template - struct serializer_t> + static Context& _(const T& t, Context& context) { - using T = multi_column_alias_t; - - static Context& _(const T& t, Context& context) - { - interpret_tuple(t._columns, ',', context); - return context; - } - }; + interpret_tuple(t._columns, ',', context); + return context; + } + }; namespace detail { diff --git a/include/sqlpp11/named_interpretable.h b/include/sqlpp11/named_interpretable.h index 8e91d06c..4aa93fa2 100644 --- a/include/sqlpp11/named_interpretable.h +++ b/include/sqlpp11/named_interpretable.h @@ -33,104 +33,104 @@ namespace sqlpp { - template - struct named_interpretable_t + template + struct named_interpretable_t + { + using _serializer_context_t = typename Db::_serializer_context_t; + using _interpreter_context_t = typename Db::_interpreter_context_t; + + template + named_interpretable_t(T t): + _impl(std::make_shared<_impl_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 - named_interpretable_t(T t): - _impl(std::make_shared<_impl_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 + // This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same + template auto serialize(Context& context) const -> typename std::enable_if::value - and not std::is_same::value, Context&>::type + and not std::is_same::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 + struct _impl_t: public _impl_base + { + static_assert(not make_parameter_list_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 - struct _impl_t: public _impl_base - { - static_assert(not make_parameter_list_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 _impl; + T _t; }; - template - struct serializer_t> + std::shared_ptr _impl; + }; + + template + struct serializer_t> + { + using T = named_interpretable_t; + + static Context& _(const T& t, Context& context) { - using T = named_interpretable_t; - - static Context& _(const T& t, Context& context) - { - t.serialize(context); - return context; - } - }; + t.serialize(context); + return context; + } + }; } diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/noop.h index 57ca5e14..74198fd0 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/noop.h @@ -34,44 +34,44 @@ namespace sqlpp { #warning: Need extra include file for no_data - struct no_data_t {}; + struct no_data_t {}; - template - struct serializer_t - { - using T = no_data_t; - - static Context& _(const T& t, Context& context) - { - return context; - } - }; - - struct noop + template + struct serializer_t { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using T = no_data_t; - struct _name_t {}; - - template - struct _result_methods_t - {}; + static Context& _(const T& t, Context& context) + { + return context; + } }; - template - struct serializer_t + struct noop + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + struct _name_t {}; + + template + struct _result_methods_t + {}; + }; + + template + struct serializer_t + { + 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 - struct is_noop: std::is_same {}; + template + struct is_noop: std::is_same {}; } #endif diff --git a/include/sqlpp11/noop_fwd.h b/include/sqlpp11/noop_fwd.h index 4936e858..0c87c75e 100644 --- a/include/sqlpp11/noop_fwd.h +++ b/include/sqlpp11/noop_fwd.h @@ -29,9 +29,9 @@ namespace sqlpp { - struct noop; + struct noop; - template - struct is_noop; + template + struct is_noop; } #endif diff --git a/include/sqlpp11/null.h b/include/sqlpp11/null.h index f78ce12d..a3309b15 100644 --- a/include/sqlpp11/null.h +++ b/include/sqlpp11/null.h @@ -37,17 +37,17 @@ namespace sqlpp using _recursive_traits = make_recursive_traits<>; }; - template - struct serializer_t - { - using Operand = null_t; + template + struct serializer_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 = {}; diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/offset.h index 1a9eb8e2..9d89674c 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/offset.h @@ -33,161 +33,37 @@ namespace sqlpp { - // OFFSET DATA - template - 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 - struct offset_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); - - // Data - using _data_t = offset_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = offset_data_t; - - _impl_t offset; - _impl_t& operator()() { return offset; } - const _impl_t& operator()() const { return offset; } - - template - static auto _get_member(T t) -> decltype(t.offset) - { - return t.offset; - } - }; - - template - struct _methods_t - { - }; - }; - - // DYNAMIC OFFSET DATA - template - struct dynamic_offset_data_t - { - dynamic_offset_data_t(): - _value(noop()) - { - } - - template - dynamic_offset_data_t(Offset value): - _initialized(true), - _value(typename wrap_operand::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 _value; - }; - - // DYNAMIC OFFSET - template - struct dynamic_offset_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - - // Data - using _data_t = dynamic_offset_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - 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::type; - _data._value = arg_t{value}; - _data._initialized = true; - } - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = dynamic_offset_data_t; - - _impl_t offset; - _impl_t& operator()() { return offset; } - const _impl_t& operator()() const { return offset; } - - template - static auto _get_member(T t) -> decltype(t.offset) - { - return t.offset; - } - }; - - template - struct _methods_t - { - template - 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::type; - static_cast(this)->_offset()._value = arg_t{value}; - static_cast(this)->_offset()._initialized = true; - } - }; - - bool _initialized = false; - interpretable_t _value; - }; - - struct no_offset_t + // OFFSET DATA + template + struct offset_data_t { - using _traits = make_traits; - 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 + struct offset_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); // Data - using _data_t = no_data_t; + using _data_t = offset_data_t; // Member implementation with data and methods - template + template struct _impl_t { _data_t _data; @@ -197,71 +73,195 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = offset_data_t; - _impl_t no_offset; - _impl_t& operator()() { return no_offset; } - const _impl_t& operator()() const { return no_offset; } + _impl_t offset; + _impl_t& operator()() { return offset; } + const _impl_t& operator()() const { return offset; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto offset(Arg arg) - -> _new_statement_t::type>> - { - return { *static_cast(this), offset_data_t::type>{{arg}} }; - } - - auto dynamic_offset() - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement"); - return { *static_cast(this), dynamic_offset_data_t<_database_t>{} }; - } }; }; - // Interpreters - template - struct serializer_t> + // DYNAMIC OFFSET DATA + template + struct dynamic_offset_data_t + { + dynamic_offset_data_t(): + _value(noop()) { - using T = offset_data_t; + } - static Context& _(const T& t, Context& context) + template + dynamic_offset_data_t(Offset value): + _initialized(true), + _value(typename wrap_operand::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 _value; + }; + + // DYNAMIC OFFSET + template + struct dynamic_offset_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = dynamic_offset_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + template + 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::type; + _data._value = arg_t{value}; + _data._initialized = true; + } + public: + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = dynamic_offset_data_t; + + _impl_t offset; + _impl_t& operator()() { return offset; } + const _impl_t& operator()() const { return offset; } + + template + static auto _get_member(T t) -> decltype(t.offset) + { + return t.offset; + } + }; + + template + struct _methods_t + { + template + 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::type; + static_cast(this)->_offset()._value = arg_t{value}; + static_cast(this)->_offset()._initialized = true; + } + }; + + bool _initialized = false; + interpretable_t _value; + }; + + struct no_offset_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + // Data + using _data_t = no_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_offset; + _impl_t& operator()() { return no_offset; } + const _impl_t& operator()() const { return no_offset; } + + template + static auto _get_member(T t) -> decltype(t.no_offset) + { + return t.no_offset; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto offset(Arg arg) + -> _new_statement_t::type>> + { + return { *static_cast(this), offset_data_t::type>{{arg}} }; + } + + auto dynamic_offset() + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement"); + return { *static_cast(this), dynamic_offset_data_t<_database_t>{} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = offset_data_t; + + static Context& _(const T& t, Context& context) + { + context << " OFFSET "; + serialize(t._value, context); + return context; + } + }; + + template + struct serializer_t> + { + using T = dynamic_offset_data_t; + + static Context& _(const T& t, Context& context) + { + if (t._initialized) { context << " OFFSET "; serialize(t._value, context); - return context; } - }; - - template - struct serializer_t> - { - using T = dynamic_offset_data_t; - - static Context& _(const T& t, Context& context) - { - if (t._initialized) - { - context << " OFFSET "; - serialize(t._value, context); - } - return context; - } - }; + return context; + } + }; } #endif diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 224cc652..26b93a9f 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -56,23 +56,23 @@ namespace sqlpp interpretable_list_t _dynamic_expressions; }; - template - struct serializer_t> - { - using T = on_t; + template + struct serializer_t> + { + using T = on_t; - 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; + } + }; } diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h index f431224f..0f9fdc75 100644 --- a/include/sqlpp11/order_by.h +++ b/include/sqlpp11/order_by.h @@ -37,113 +37,74 @@ namespace sqlpp { - // ORDER BY DATA - template - 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; - interpretable_list_t _dynamic_expressions; - }; - - // ORDER BY - template - struct order_by_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in order_by()"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an expression in order_by()"); - - // Data - using _data_t = order_by_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Expression expression) - { - add(expression); - } - - template - void add(Expression expression) - { - static_assert(_is_dynamic::value, "add() must not be called for static order_by"); - static_assert(is_expression_t::value, "invalid expression argument in order_by::add()"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in order_by::add()"); - - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; - - _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Expression expression, const std::true_type&) - { - return _data._dynamic_expressions.emplace_back(expression); - } - - template - void _add_impl(Expression expression, const std::false_type&); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = order_by_data_t; - - _impl_t order_by; - _impl_t& operator()() { return order_by; } - const _impl_t& operator()() const { return order_by; } - - template - static auto _get_member(T t) -> decltype(t.order_by) - { - return t.order_by; - } - }; - - template - struct _methods_t - { - }; - }; - - // NO ORDER BY YET - struct no_order_by_t + // ORDER BY DATA + template + struct order_by_data_t { - using _traits = make_traits; - 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; + interpretable_list_t _dynamic_expressions; + }; + + // ORDER BY + template + struct order_by_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in order_by()"); + + static_assert(::sqlpp::detail::all_t::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; // Member implementation with data and methods template struct _impl_t { + template + void add_ntc(Expression expression) + { + add(expression); + } + + template + void add(Expression expression) + { + static_assert(_is_dynamic::value, "add() must not be called for static order_by"); + static_assert(is_expression_t::value, "invalid expression argument in order_by::add()"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in order_by::add()"); + + using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; + + _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Expression expression, const std::true_type&) + { + return _data._dynamic_expressions.emplace_back(expression); + } + + template + void _add_impl(Expression expression, const std::false_type&); + public: _data_t _data; }; @@ -151,61 +112,100 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = order_by_data_t; - _impl_t no_order_by; - _impl_t& operator()() { return no_order_by; } - const _impl_t& operator()() const { return no_order_by; } + _impl_t order_by; + _impl_t& operator()() { return order_by; } + const _impl_t& operator()() const { return order_by; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto order_by(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), order_by_data_t{args...} }; - } - - template - auto dynamic_order_by(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement"); - return { *static_cast(this), order_by_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = order_by_data_t; + // NO ORDER BY YET + struct no_order_by_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_order_by; + _impl_t& operator()() { return no_order_by; } + const _impl_t& operator()() const { return no_order_by; } + + template + static auto _get_member(T t) -> decltype(t.no_order_by) + { + return t.no_order_by; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto order_by(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), order_by_data_t{args...} }; + } + + template + auto dynamic_order_by(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement"); + return { *static_cast(this), order_by_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = order_by_data_t; + + 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 diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index b582b805..3cf45236 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -34,7 +34,7 @@ namespace sqlpp { template - struct parameter_t: public ValueType::template expression_operators> + struct parameter_t: public ValueType::template expression_operators> { using _traits = make_traits; struct _recursive_traits @@ -57,17 +57,17 @@ namespace sqlpp ~parameter_t() = default; }; - template - struct serializer_t> - { - using T = parameter_t; + template + struct serializer_t> + { + using T = parameter_t; - static Context& _(const T& t, Context& context) - { - context << "?"; - return context; - } - }; + static Context& _(const T& t, Context& context) + { + context << "?"; + return context; + } + }; template auto parameter(const NamedExpr&) diff --git a/include/sqlpp11/policy_update.h b/include/sqlpp11/policy_update.h index 5183767b..ecb61181 100644 --- a/include/sqlpp11/policy_update.h +++ b/include/sqlpp11/policy_update.h @@ -31,24 +31,24 @@ namespace sqlpp { - template - struct policy_update_impl - { - template - using _policy_t = typename std::conditional::value, Replacement, T>::type; - }; + template + struct policy_update_impl + { + template + using _policy_t = typename std::conditional::value, Replacement, T>::type; + }; - template - using policy_update_t = typename policy_update_impl::template _policy_t; + template + using policy_update_t = typename policy_update_impl::template _policy_t; - template - struct update_policies_impl - { - using type = typename Original::template _policy_update_t; - }; + template + struct update_policies_impl + { + using type = typename Original::template _policy_update_t; + }; - template - using update_policies_t = typename update_policies_impl::type; + template + using update_policies_t = typename update_policies_impl::type; } diff --git a/include/sqlpp11/prepared_insert.h b/include/sqlpp11/prepared_insert.h index 63a995df..c6f963e7 100644 --- a/include/sqlpp11/prepared_insert.h +++ b/include/sqlpp11/prepared_insert.h @@ -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 { diff --git a/include/sqlpp11/prepared_remove.h b/include/sqlpp11/prepared_remove.h index 21e72986..593f75ce 100644 --- a/include/sqlpp11/prepared_remove.h +++ b/include/sqlpp11/prepared_remove.h @@ -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 { diff --git a/include/sqlpp11/prepared_select.h b/include/sqlpp11/prepared_select.h index 0cdb56b4..fab451ca 100644 --- a/include/sqlpp11/prepared_select.h +++ b/include/sqlpp11/prepared_select.h @@ -42,9 +42,9 @@ namespace sqlpp auto _run(Database& db) const -> result_t - { - return {db.run_prepared_select(*this), _dynamic_names}; - } + { + return {db.run_prepared_select(*this), _dynamic_names}; + } void _bind_params() const { diff --git a/include/sqlpp11/prepared_update.h b/include/sqlpp11/prepared_update.h index a6206e9e..071ee404 100644 --- a/include/sqlpp11/prepared_update.h +++ b/include/sqlpp11/prepared_update.h @@ -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 { diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index 54ffcbc1..f3b0a722 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -79,26 +79,26 @@ namespace sqlpp }; - template - struct serializer_t + template + struct serializer_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 using blank_remove_t = statement_t; + remove_t, + no_from_t, + no_using_t, + no_extra_tables_t, + no_where_t>; auto remove() -> blank_remove_t diff --git a/include/sqlpp11/result.h b/include/sqlpp11/result.h index 314ffc26..f24eee85 100644 --- a/include/sqlpp11/result.h +++ b/include/sqlpp11/result.h @@ -45,12 +45,12 @@ namespace sqlpp result_t() = default; template - 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; diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 2f31c117..ce4d4eb3 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -43,48 +43,48 @@ namespace sqlpp template struct result_field: public NamedExpr::_name_t::template _member_t::template _result_entry_t> + { + using _field = typename NamedExpr::_name_t::template _member_t::template _result_entry_t>; + + 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::template _result_entry_t>; + _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 + template void _bind(Target& target) { _field::operator()()._bind(target, index); } - }; + }; template struct result_field>>: - public AliasProvider::_name_t::template _member_t, NamedExprs...>> + public AliasProvider::_name_t::template _member_t, NamedExprs...>> { using _multi_field = typename AliasProvider::_name_t::template _member_t, 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 - void _bind(Target& target) - { - _multi_field::operator()()._bind(target); - } + void _bind(Target& target) + { + _multi_field::operator()()._bind(target); + } }; template struct result_row_impl, NamedExprs...>: - public result_field... + public result_field... { static constexpr std::size_t _last_index = LastIndex; result_row_impl() = default; @@ -140,17 +140,17 @@ namespace sqlpp } template - void _bind(Target& target) - { - using swallow = int[]; - (void) swallow{(result_field::_bind(target), 0)...}; - } + void _bind(Target& target) + { + using swallow = int[]; + (void) swallow{(result_field::_bind(target), 0)...}; + } }; } template - struct result_row_t: public detail::result_row_impl, NamedExprs...> + struct result_row_t: public detail::result_row_impl, NamedExprs...> { using _impl = detail::result_row_impl, NamedExprs...>; bool _is_valid; @@ -163,9 +163,9 @@ namespace sqlpp } template - 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 - struct dynamic_result_row_t: public detail::result_row_impl, NamedExprs...> + struct dynamic_result_row_t: public detail::result_row_impl, NamedExprs...> { using _impl = detail::result_row_impl, NamedExprs...>; using _field_type = detail::text::_result_entry_t; diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index c014abe4..0c5b320f 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -51,32 +51,32 @@ namespace sqlpp struct select_t: public statement_name_t {}; - template - struct serializer_t + template + struct serializer_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 using blank_select_t = statement_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 select() // FIXME: These should be constexpr diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index efdaf8ed..7dc7937c 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -59,256 +59,256 @@ namespace sqlpp }; } - template - struct dynamic_select_column_list - { - using _names_t = std::vector; - std::vector> _dynamic_columns; - _names_t _dynamic_expression_names; + template + struct dynamic_select_column_list + { + using _names_t = std::vector; + std::vector> _dynamic_columns; + _names_t _dynamic_expression_names; - template - void emplace_back(Expr expr) - { - _dynamic_expression_names.push_back(Expr::_name_t::_get_name()); - _dynamic_columns.emplace_back(expr); - } - - bool empty() const + template + 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 + bool empty() const { - struct _names_t + return _dynamic_columns.empty(); + } + }; + + template<> + struct dynamic_select_column_list + { + struct _names_t + { + static constexpr size_t size() { return 0; } + }; + _names_t _dynamic_expression_names; + + static constexpr bool empty() + { + return true; + } + }; + + template + struct serializer_t> + { + using T = dynamic_select_column_list; + + 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 + struct serializer_t> + { + using T = dynamic_select_column_list; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + + // SELECTED COLUMNS DATA + template + struct select_column_list_data_t + { + using _is_dynamic = typename std::conditional::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) + {} + + 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; + dynamic_select_column_list _dynamic_columns; + }; + + + // SELECTED COLUMNS + template + struct select_column_list_t + { + using _traits = typename ::sqlpp::detail::select_traits::_traits; + using _recursive_traits = make_recursive_traits; + + using _name_t = typename ::sqlpp::detail::select_traits::_name_t; + + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected"); + + static_assert(::sqlpp::detail::all_t<(is_named_expression_t::value or is_multi_column_t::value)...>::value, "at least one argument is not a named expression"); + + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate name detected"); + + struct _column_type {}; + + // Data + using _data_t = select_column_list_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + template + void add_ntc(NamedExpression namedExpression) + { + add(namedExpression); + } + + template + 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::value, "invalid named expression argument in selected_columns::add()"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "named expression uses tables unknown to this statement in selected_columns::add()"); + using column_names = ::sqlpp::detail::make_type_set_t; + static_assert(not ::sqlpp::detail::is_element_of::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::value + >; + + _add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert + } + + //private: + template + void _add_impl(NamedExpression namedExpression, const std::true_type&) + { + return _data._dynamic_columns.emplace_back(namedExpression); + } + + template + 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 + struct _member_t { - return true; - } - }; + using _data_t = select_column_list_data_t; - template - struct serializer_t> - { - using T = dynamic_select_column_list; - - 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 - struct serializer_t> - { - using T = dynamic_select_column_list; - - static Context& _(const T& t, Context& context) - { - return context; - } - }; - - // SELECTED COLUMNS DATA - template - struct select_column_list_data_t - { - using _is_dynamic = typename std::conditional::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) - {} - - 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; - dynamic_select_column_list _dynamic_columns; - }; - - - // SELECTED COLUMNS - template - struct select_column_list_t - { - using _traits = typename ::sqlpp::detail::select_traits::_traits; - using _recursive_traits = make_recursive_traits; - - using _name_t = typename ::sqlpp::detail::select_traits::_name_t; - - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected"); - - static_assert(::sqlpp::detail::all_t<(is_named_expression_t::value or is_multi_column_t::value)...>::value, "at least one argument is not a named expression"); - - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate name detected"); - - struct _column_type {}; - - // Data - using _data_t = select_column_list_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(NamedExpression namedExpression) - { - add(namedExpression); - } - - template - 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::value, "invalid named expression argument in selected_columns::add()"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "named expression uses tables unknown to this statement in selected_columns::add()"); - using column_names = ::sqlpp::detail::make_type_set_t; - static_assert(not ::sqlpp::detail::is_element_of::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::value - >; - - _add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert - } - - //private: - template - void _add_impl(NamedExpression namedExpression, const std::true_type&) - { - return _data._dynamic_columns.emplace_back(namedExpression); - } - - template - 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 - struct _member_t - { - using _data_t = select_column_list_data_t; - - _impl_t selected_columns; - _impl_t& operator()() { return selected_columns; } - const _impl_t& operator()() const { return selected_columns; } + _impl_t selected_columns; + _impl_t& operator()() { return selected_columns; } + const _impl_t& operator()() const { return selected_columns; } template static auto _get_member(T t) -> decltype(t.selected_columns) { return t.selected_columns; } - }; + }; - // Additional methods for the statement - template - struct _methods_t + // Additional methods for the statement + template + struct _methods_t + { + }; + + // Result methods + template + struct _result_methods_t + { + using _statement_t = typename Policies::_statement_t; + + const _statement_t& _get_statement() const { - }; + return static_cast(*this); + } - // Result methods - template - struct _result_methods_t + template + using _result_row_t = typename std::conditional<_is_dynamic::value, + dynamic_result_row_t...>, + result_row_t...>>::type; + + using _dynamic_names_t = typename dynamic_select_column_list::_names_t; + + template + struct _deferred_table_t + { + using table = select_pseudo_table_t<_statement_t, Columns...>; + using alias = typename table::template _alias_t; + }; + + template + using _table_t = typename _deferred_table_t::table; + + template + using _alias_t = typename _deferred_table_t::alias; + + template + _alias_t 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(_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 + auto _run(Db& db) const + -> result_t> { - return static_cast(*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 - using _result_row_t = typename std::conditional<_is_dynamic::value, - dynamic_result_row_t...>, - result_row_t...>>::type; - - using _dynamic_names_t = typename dynamic_select_column_list::_names_t; - - template - struct _deferred_table_t - { - using table = select_pseudo_table_t<_statement_t, Columns...>; - using alias = typename table::template _alias_t; - }; - - template - using _table_t = typename _deferred_table_t::table; - - template - using _alias_t = typename _deferred_table_t::alias; - - template - _alias_t 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(_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 - auto _run(Db& db) const - -> result_t> - { - _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 - auto _prepare(Db& db) const - -> prepared_select_t - { - _statement_t::_check_consistency(); + // Prepare + template + auto _prepare(Db& db) const + -> prepared_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::_(std::declval())...))>; } - struct no_select_column_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + struct no_select_column_list_t + { + using _traits = make_traits; + 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 - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = no_data_t; - - _impl_t no_selected_columns; - _impl_t& operator()() { return no_selected_columns; } - const _impl_t& operator()() const { return no_selected_columns; } - - template - static auto _get_member(T t) -> decltype(t.no_selected_columns) - { - return t.no_selected_columns; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto columns(Args... args) - -> _new_statement_t<::sqlpp::detail::make_select_column_list_t> - { - return { *static_cast(this), typename ::sqlpp::detail::make_select_column_list_t::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple::_(args)...)} }; - } - - template - 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(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple::_(args)...)} }; - } - }; - }; - - // Interpreters - template - struct serializer_t> + // Member implementation with data and methods + template + struct _impl_t { - using T = select_column_list_data_t; - - 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 + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_selected_columns; + _impl_t& operator()() { return no_selected_columns; } + const _impl_t& operator()() const { return no_selected_columns; } + + template + static auto _get_member(T t) -> decltype(t.no_selected_columns) + { + return t.no_selected_columns; + } + }; + + // Additional methods for the statement + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto columns(Args... args) + -> _new_statement_t<::sqlpp::detail::make_select_column_list_t> + { + return { *static_cast(this), typename ::sqlpp::detail::make_select_column_list_t::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple::_(args)...)} }; + } + + template + 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(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple::_(args)...)} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = select_column_list_data_t; + + 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 diff --git a/include/sqlpp11/select_flag_list.h b/include/sqlpp11/select_flag_list.h index 9b0414e3..8147e5d2 100644 --- a/include/sqlpp11/select_flag_list.h +++ b/include/sqlpp11/select_flag_list.h @@ -36,112 +36,72 @@ namespace sqlpp { - // SELECTED FLAGS DATA - template - 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; - interpretable_list_t _dynamic_flags; - }; - - // SELECT FLAGS - template - struct select_flag_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in select flag list"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not a select flag in select flag list"); - - // Data - using _data_t = select_flag_list_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Flag flag) - { - add(flag); - } - - template - 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::value, "invalid select flag argument in select_flags::add()"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::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::value>; - - _add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Flag flag, const std::true_type&) - { - return _data._dynamic_flags.emplace_back(flag); - } - - template - void _add_impl(Flag flag, const std::false_type&); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = select_flag_list_data_t; - - _impl_t select_flags; - _impl_t& operator()() { return select_flags; } - const _impl_t& operator()() const { return select_flags; } - - template - static auto _get_member(T t) -> decltype(t.select_flags) - { - return t.select_flags; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - - }; - - struct no_select_flag_list_t + // SELECTED FLAGS DATA + template + struct select_flag_list_data_t { - using _traits = make_traits; - 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; + interpretable_list_t _dynamic_flags; + }; + + // SELECT FLAGS + template + struct select_flag_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in select flag list"); + + static_assert(::sqlpp::detail::all_t::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; // Member implementation with data and methods template struct _impl_t { + template + void add_ntc(Flag flag) + { + add(flag); + } + + template + 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::value, "invalid select flag argument in select_flags::add()"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::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::value>; + + _add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Flag flag, const std::true_type&) + { + return _data._dynamic_flags.emplace_back(flag); + } + + template + void _add_impl(Flag flag, const std::false_type&); + public: _data_t _data; }; @@ -149,62 +109,102 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = select_flag_list_data_t; - _impl_t no_select_flags; - _impl_t& operator()() { return no_select_flags; } - const _impl_t& operator()() const { return no_select_flags; } + _impl_t select_flags; + _impl_t& operator()() { return select_flags; } + const _impl_t& operator()() const { return select_flags; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto flags(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), select_flag_list_data_t{args...} }; - } - - template - auto dynamic_flags(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement"); - return { *static_cast(this), select_flag_list_data_t<_database_t, Args...>{args...} }; - } }; + }; + struct no_select_flag_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; - // Interpreters - template - struct serializer_t> + // Data + using _data_t = no_data_t; + + // Member implementation with data and methods + template + struct _impl_t { - using T = select_flag_list_data_t; - - 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 + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_select_flags; + _impl_t& operator()() { return no_select_flags; } + const _impl_t& operator()() const { return no_select_flags; } + + template + static auto _get_member(T t) -> decltype(t.no_select_flags) + { + return t.no_select_flags; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto flags(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), select_flag_list_data_t{args...} }; + } + + template + auto dynamic_flags(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement"); + return { *static_cast(this), select_flag_list_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + + // Interpreters + template + struct serializer_t> + { + using T = select_flag_list_data_t; + + 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; + } + }; + } diff --git a/include/sqlpp11/select_flags.h b/include/sqlpp11/select_flags.h index e082680f..4b07d6be 100644 --- a/include/sqlpp11/select_flags.h +++ b/include/sqlpp11/select_flags.h @@ -42,15 +42,15 @@ namespace sqlpp }; static constexpr all_t all = {}; - template - struct serializer_t + template + struct serializer_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 - struct serializer_t + template + struct serializer_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 - struct serializer_t + template + struct serializer_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; + } + }; } diff --git a/include/sqlpp11/select_pseudo_table.h b/include/sqlpp11/select_pseudo_table.h index efd9d4d3..3378035a 100644 --- a/include/sqlpp11/select_pseudo_table.h +++ b/include/sqlpp11/select_pseudo_table.h @@ -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 - struct serializer_t> - { - using T = select_pseudo_table_t; + template + struct serializer_t> + { + using T = select_pseudo_table_t; - 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; + } + }; } diff --git a/include/sqlpp11/serialize.h b/include/sqlpp11/serialize.h index c8641ae7..e7331320 100644 --- a/include/sqlpp11/serialize.h +++ b/include/sqlpp11/serialize.h @@ -39,13 +39,13 @@ namespace sqlpp } /* - template - auto serialize(const T& t, Context& context) - -> decltype(serializer_t::_(t, context)) - { - return serializer_t::_(t, context); - } - */ + template + auto serialize(const T& t, Context& context) + -> decltype(serializer_t::_(t, context)) + { + return serializer_t::_(t, context); + } + */ } diff --git a/include/sqlpp11/serializer.h b/include/sqlpp11/serializer.h index c263b393..682c9602 100644 --- a/include/sqlpp11/serializer.h +++ b/include/sqlpp11/serializer.h @@ -31,14 +31,14 @@ namespace sqlpp { - template - struct serializer_t + template + struct serializer_t + { + static void _(const T& t, Context& context) { - static void _(const T& t, Context& context) - { - static_assert(wrong_t::value, "missing serializer specialization"); - } - }; + static_assert(wrong_t::value, "missing serializer specialization"); + } + }; } diff --git a/include/sqlpp11/simple_column.h b/include/sqlpp11/simple_column.h index bdf74345..34f030e3 100644 --- a/include/sqlpp11/simple_column.h +++ b/include/sqlpp11/simple_column.h @@ -31,29 +31,29 @@ namespace sqlpp { - template - struct simple_column_t - { - Column _column; - }; + template + struct simple_column_t + { + Column _column; + }; - template - struct serializer_t> - { - using T = simple_column_t; + template + struct serializer_t> + { + using T = simple_column_t; - static Context& _(const T& t, Context& context) - { - context << t._column._get_name(); - return context; - } - }; - - template - simple_column_t simple_column(Column c) + static Context& _(const T& t, Context& context) { - return {c}; + context << t._column._get_name(); + return context; } + }; + + template + simple_column_t simple_column(Column c) + { + return {c}; + } } #endif diff --git a/include/sqlpp11/single_table.h b/include/sqlpp11/single_table.h index 23544dba..0f760e10 100644 --- a/include/sqlpp11/single_table.h +++ b/include/sqlpp11/single_table.h @@ -34,129 +34,39 @@ namespace sqlpp { - // A SINGLE TABLE DATA - template - 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 - struct single_table_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits
; - - static_assert(is_table_t
::value, "argument has to be a table"); - static_assert(required_tables_of
::size::value == 0, "table depends on another table"); - - using _data_t = single_table_data_t; - - struct _name_t {}; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = single_table_data_t; - - _impl_t from; - _impl_t& operator()() { return from; } - const _impl_t& operator()() const { return from; } - - template - static auto _get_member(T t) -> decltype(t.from) - { - return t.from; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - - template - struct _result_methods_t - { - using _statement_t = typename Policies::_statement_t; - - const _statement_t& _get_statement() const - { - return static_cast(*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 - 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 - auto _prepare(Db& db) const - -> prepared_insert_t - { - _check_consistency(); - - return {{}, db.prepare_insert(*this)}; - } - */ - }; - }; - - // NO INTO YET - struct no_single_table_t + // A SINGLE TABLE DATA + template + struct single_table_data_t { - using _traits = make_traits; - 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 + struct single_table_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits
; + + static_assert(is_table_t
::value, "argument has to be a table"); + static_assert(required_tables_of
::size::value == 0, "table depends on another table"); + + using _data_t = single_table_data_t; + + struct _name_t {}; // Member implementation with data and methods - template + template struct _impl_t { _data_t _data; @@ -166,49 +76,139 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = single_table_data_t; - _impl_t no_from; - _impl_t& operator()() { return no_from; } - const _impl_t& operator()() const { return no_from; } + _impl_t from; + _impl_t& operator()() { return from; } + const _impl_t& operator()() const { return from; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; + }; -#warning: remove can operate on several tables at once, so it should not use single_table anyway - template - auto from(Args... args) - -> _new_statement_t> + template + struct _result_methods_t + { + using _statement_t = typename Policies::_statement_t; + + const _statement_t& _get_statement() const + { + return static_cast(*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 + auto _run(Db& db) const -> decltype(db.insert(_get_statement())) { - return { *static_cast(this), single_table_data_t{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 + auto _prepare(Db& db) const + -> prepared_insert_t + { + _check_consistency(); + + return {{}, db.prepare_insert(*this)}; + } + */ }; }; - // Interpreters - template - struct serializer_t> - { - using T = single_table_data_t; + // NO INTO YET + struct no_single_table_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_from; + _impl_t& operator()() { return no_from; } + const _impl_t& operator()() const { return no_from; } + + template + static auto _get_member(T t) -> decltype(t.no_from) + { + return t.no_from; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + +#warning: remove can operate on several tables at once, so it should not use single_table anyway + template + auto from(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), single_table_data_t{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = single_table_data_t; + + static Context& _(const T& t, Context& context) + { + serialize(t._table, context); + return context; + } + }; + } #endif diff --git a/include/sqlpp11/some.h b/include/sqlpp11/some.h index 2b1fb002..1fb864c8 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -32,7 +32,7 @@ namespace sqlpp { - template + template struct some_t { using _traits = make_traits, ::sqlpp::tag::multi_expression>; @@ -63,19 +63,19 @@ namespace sqlpp Select _select; }; - template - struct serializer_t> - { - using T = some_t; - 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 auto some(T t) -> typename some_t> diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index a7e8bdea..ae8d92bd 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -46,26 +46,26 @@ namespace sqlpp Expression _expression; }; - template - struct serializer_t> - { - using T = sort_order_t; + template + struct serializer_t> + { + using T = sort_order_t; - 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; + } + }; } diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index e875ac20..790206a1 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -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; @@ -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::value...>::value, @@ -121,82 +121,82 @@ namespace sqlpp } template - struct statement_t: - public Policies::template _member_t>..., - public detail::statement_policies_t::_value_type::template expression_operators>, - public detail::statement_policies_t::_result_methods_t, - public detail::statement_policies_t::_methods_t + typename... Policies + > + struct statement_t: + public Policies::template _member_t>..., + public detail::statement_policies_t::_value_type::template expression_operators>, + public detail::statement_policies_t::_result_methods_t, + public detail::statement_policies_t::_methods_t { - using _policies_t = typename detail::statement_policies_t; + using _policies_t = typename detail::statement_policies_t; - using _traits = make_traits, ::sqlpp::tag::select, tag::expression_if, tag::named_expression_if>; - using _recursive_traits = typename _policies_t::_recursive_traits; + using _traits = make_traits, ::sqlpp::tag::select, tag::expression_if, tag::named_expression_if>; + 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 - statement_t(Statement statement, Term term): - Policies::template _member_t<_policies_t>{ - typename Policies::template _impl_t<_policies_t>{ - detail::pick_arg>(statement, term) - }}... - //Policies::template _member_t<_policies_t>{{detail::pick_arg>(statement, term)}}... - {} + template + statement_t(Statement statement, Term term): + Policies::template _member_t<_policies_t>{ + typename Policies::template _impl_t<_policies_t>{ + detail::pick_arg>(statement, term) + }}... + //Policies::template _member_t<_policies_t>{{detail::pick_arg>(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 + struct serializer_t> + { + using T = statement_t; + using P = ::sqlpp::detail::statement_policies_t; + + static Context& _(const T& t, Context& context) + { + using swallow = int[]; + (void) swallow{(serialize(static_cast&>(t)()._data, context), 0)...}; + + return context; } - - }; - template - struct serializer_t> - { - using T = statement_t; - using P = ::sqlpp::detail::statement_policies_t; - - static Context& _(const T& t, Context& context) - { - using swallow = int[]; - (void) swallow{(serialize(static_cast&>(t)()._data, context), 0)...}; - - return context; - } - }; - - template + template struct statement_name_t { using _traits = make_traits; diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 9bfca5d9..d22f008f 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -31,59 +31,59 @@ namespace sqlpp { - template + template struct sum_t: public value_type_of::template expression_operators>, - public alias_operators> + public alias_operators> + { + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; + + static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); + static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); + + struct _name_t { - using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; - using _recursive_traits = make_recursive_traits; - - static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); - static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); - - struct _name_t - { - static constexpr const char* _get_name() { return "SUM"; } - template - 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 + struct _member_t + { + T sum; + T& operator()() { return sum; } + const T& operator()() const { return sum; } + }; }; - template - struct serializer_t> - { - using T = sum_t; + 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 + struct serializer_t> + { + using T = sum_t; + + static Context& _(const T& t, Context& context) + { + context << "SUM("; + if (std::is_same::value) { - context << "SUM("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + serialize(Flag(), context); + context << ' '; } - }; + serialize(t._expr, context); + context << ")"; + return context; + } + }; template auto sum(T t) -> typename sum_t> diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index fa2e1043..9dc4183f 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -40,7 +40,7 @@ namespace sqlpp struct table_base_t {}; template - struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t>... + struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t>... { using _traits = make_traits; @@ -101,17 +101,17 @@ namespace sqlpp } }; - template - struct serializer_t::value and not is_pseudo_table_t::value, void>::type> - { - using T = X; + template + struct serializer_t::value and not is_pseudo_table_t::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; + } + }; } diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index d8bc5ba5..ff1a3e19 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -61,19 +61,19 @@ namespace sqlpp Table _table; }; - template - struct serializer_t> - { - using T = table_alias_t; + template + struct serializer_t> + { + using T = table_alias_t; - 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; + } + }; } diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 1d533dcb..0e0c6a53 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -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 - 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::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::value; - if (connector_assert_result_validity_t::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 - 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::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::value; + if (connector_assert_result_validity_t::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 + 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 struct _is_valid_operand - { - static constexpr bool value = - is_expression_t::value // expressions are OK - and is_text_t::value // the correct value type is required, of course - ; - }; + { + static constexpr bool value = + is_expression_t::value // expressions are OK + and is_text_t::value // the correct value type is required, of course + ; + }; template struct expression_operators: public basic_expression_operators @@ -209,23 +209,23 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); + { + template + auto operator +=(T t) const -> assignment_t>> + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } - }; + return { *static_cast(this), { *static_cast(this), rhs{t} } }; + } + }; }; template - inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e) - { - return os << e.value(); - } + inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e) + { + return os << e.value(); + } } using text = detail::text; diff --git a/include/sqlpp11/transaction.h b/include/sqlpp11/transaction.h index a2b1dfbc..b0d456cc 100644 --- a/include/sqlpp11/transaction.h +++ b/include/sqlpp11/transaction.h @@ -35,56 +35,56 @@ namespace sqlpp static constexpr bool report_auto_rollback = true; template - 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 transaction_t start_transaction(Db& db, bool report_unfinished_transaction = report_auto_rollback) diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h index 823706c1..82e23b3d 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -61,16 +61,16 @@ namespace sqlpp Operand _value; }; - template - struct serializer_t> - { - using T = tvin_t; + template + struct serializer_t> + { + using T = tvin_t; - static void _(const T& t, Context& context) - { - static_assert(wrong_t::value, "tvin() must not be used with anything but =, ==, != and !"); - } - }; + static void _(const T& t, Context& context) + { + static_assert(wrong_t::value, "tvin() must not be used with anything but =, ==, != and !"); + } + }; template struct maybe_tvin_t @@ -118,31 +118,31 @@ namespace sqlpp typename tvin_t::_operand_t _value; }; - template - struct serializer_t> - { - using T = maybe_tvin_t; + template + struct serializer_t> + { + using T = maybe_tvin_t; - 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 auto tvin(Operand operand) -> tvin_t::type> { using _operand_t = typename wrap_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}}; } diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 6df505f4..1dc73f39 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -36,57 +36,57 @@ namespace sqlpp namespace detail\ {\ template\ - struct is_##name##_impl: std::false_type {};\ + struct is_##name##_impl: std::false_type {};\ template\ - struct is_##name##_impl::value>::type>: std::true_type {};\ + struct is_##name##_impl::value>::type>: std::true_type {};\ }\ namespace tag\ {\ struct name{};\ };\ template\ - using is_##name##_t = detail::is_element_of; + using is_##name##_t = detail::is_element_of; #define SQLPP_IS_COLUMN_TRAIT_GENERATOR(name) \ namespace detail\ {\ template\ - struct name##_impl { using type = std::false_type; };\ + struct name##_impl { using type = std::false_type; };\ template\ - struct name##_impl::value>::type> { using type = std::true_type; };\ + struct name##_impl::value>::type> { using type = std::true_type; };\ }\ template\ - using name##_t = typename detail::name##_impl::type; + using name##_t = typename detail::name##_impl::type; #define SQLPP_TYPE_TRAIT_GENERATOR(name) \ namespace detail\ {\ template\ - struct name##_impl: std::false_type {};\ + struct name##_impl: std::false_type {};\ template\ - struct name##_impl::value>::type>: std::true_type {};\ + struct name##_impl::value>::type>: std::true_type {};\ }\ template\ - struct name##_t: detail::name##_impl {}; + struct name##_t: detail::name##_impl {}; #define SQLPP_CONNECTOR_TRAIT_GENERATOR(name) \ namespace detail\ {\ template\ - struct connector_##name##_impl: std::false_type {};\ + struct connector_##name##_impl: std::false_type {};\ template\ - struct connector_##name##_impl::value>::type>: std::true_type {};\ + struct connector_##name##_impl::value>::type>: std::true_type {};\ }\ template\ - struct connector_##name##_t: detail::connector_##name##_impl {}; + struct connector_##name##_t: detail::connector_##name##_impl {}; SQLPP_IS_VALUE_TRAIT_GENERATOR(boolean); SQLPP_IS_VALUE_TRAIT_GENERATOR(integral); SQLPP_IS_VALUE_TRAIT_GENERATOR(floating_point); template using is_numeric_t = detail::any_t< - detail::is_element_of::value, - detail::is_element_of::value>; + detail::is_element_of::value, + detail::is_element_of::value>; SQLPP_IS_VALUE_TRAIT_GENERATOR(text); SQLPP_IS_VALUE_TRAIT_GENERATOR(wrapped_value); SQLPP_IS_VALUE_TRAIT_GENERATOR(expression); diff --git a/include/sqlpp11/update.h b/include/sqlpp11/update.h index e598d69b..88e7fdc1 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -70,34 +70,34 @@ namespace sqlpp auto _prepare(Db& db) const -> prepared_update_t { - _statement_t::_check_consistency(); + _statement_t::_check_consistency(); - return {{}, db.prepare_update(*this)}; + return {{}, db.prepare_update(*this)}; } */ }; }; - template - struct serializer_t + template + struct serializer_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 using blank_update_t = statement_t; + update_t, + no_single_table_t, + no_update_list_t, + no_where_t>; template constexpr auto update(Table table) diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index a311bef0..9b3c9626 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -34,127 +34,88 @@ namespace sqlpp { - // UPDATE ASSIGNMENTS DATA - template - struct update_list_data_t - { - update_list_data_t(Assignments... assignments): - _assignments(assignments...) - {} + // UPDATE ASSIGNMENTS DATA + template + 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; - typename interpretable_list_t _dynamic_assignments; - }; + std::tuple _assignments; + typename interpretable_list_t _dynamic_assignments; + }; - // UPDATE ASSIGNMENTS - template - struct update_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + // UPDATE ASSIGNMENTS + template + struct update_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in set()"); + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); + static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); - static_assert(::sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(::sqlpp::detail::none_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::type; - using _value_table_set = typename ::sqlpp::detail::make_joined_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; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Assignment assignment) - { - add(assignment); - } - - template - void add(Assignment assignment) - { - static_assert(_is_dynamic::value, "add must not be called for static from()"); - static_assert(is_assignment_t::value, "invalid assignment argument in add()"); - static_assert(sqlpp::detail::not_t::value, "add() argument must not be updated"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "assignment uses tables unknown to this statement in add()"); - - using ok = ::sqlpp::detail::all_t< - _is_dynamic::value, - is_assignment_t::value, - not must_not_update_t::value>; - - _add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Assignment assignment, const std::true_type&) - { - return _data._dynamic_assignments.emplace_back(assignment); - } - - template - void _add_impl(Assignment assignment, const std::false_type&); - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = update_list_data_t; - - _impl_t assignments; - _impl_t& operator()() { return assignments; } - const _impl_t& operator()() const { return assignments; } - - template - static auto _get_member(T t) -> decltype(t.assignments) - { - return t.assignments; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - struct no_update_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + /* + using _column_table_set = typename ::sqlpp::detail::make_joined_set::type; + using _value_table_set = typename ::sqlpp::detail::make_joined_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; // Member implementation with data and methods - template + template struct _impl_t { + template + void add_ntc(Assignment assignment) + { + add(assignment); + } + + template + void add(Assignment assignment) + { + static_assert(_is_dynamic::value, "add must not be called for static from()"); + static_assert(is_assignment_t::value, "invalid assignment argument in add()"); + static_assert(sqlpp::detail::not_t::value, "add() argument must not be updated"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "assignment uses tables unknown to this statement in add()"); + + using ok = ::sqlpp::detail::all_t< + _is_dynamic::value, + is_assignment_t::value, + not must_not_update_t::value>; + + _add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Assignment assignment, const std::true_type&) + { + return _data._dynamic_assignments.emplace_back(assignment); + } + + template + void _add_impl(Assignment assignment, const std::false_type&); + public: _data_t _data; }; @@ -162,59 +123,98 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = update_list_data_t; - _impl_t no_assignments; - _impl_t& operator()() { return no_assignments; } - const _impl_t& operator()() const { return no_assignments; } + _impl_t assignments; + _impl_t& operator()() { return assignments; } + const _impl_t& operator()() const { return assignments; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto set(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), update_list_data_t{args...} }; - } - - template - auto dynamic_set(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement"); - return { *static_cast(this), update_list_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = update_list_data_t; + struct no_update_list_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_assignments; + _impl_t& operator()() { return no_assignments; } + const _impl_t& operator()() const { return no_assignments; } + + template + static auto _get_member(T t) -> decltype(t.no_assignments) + { + return t.no_assignments; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto set(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), update_list_data_t{args...} }; + } + + template + auto dynamic_set(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement"); + return { *static_cast(this), update_list_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = update_list_data_t; + + 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 diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h index 6aabd249..0d345906 100644 --- a/include/sqlpp11/using.h +++ b/include/sqlpp11/using.h @@ -35,108 +35,68 @@ namespace sqlpp { - // USING DATA - template - 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; - interpretable_list_t _dynamic_tables; - }; - - // USING - template - struct using_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in using()"); - - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an table in using()"); - - // Data - using _data_t = using_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - template - void add(Table table) - { - static_assert(_is_dynamic::value, "add must not be called for static using()"); - static_assert(is_table_t
::value, "invalid table argument in add()"); - - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t
::value>; - - _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Table table, const std::true_type&) - { - return _data._dynamic_tables.emplace_back(table); - } - - template - void _add_impl(Table table, const std::false_type&); - - public: - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = using_data_t; - - _impl_t using_; - _impl_t& operator()() { return using_; } - const _impl_t& operator()() const { return using_; } - - template - static auto _get_member(T t) -> decltype(t.using_) - { - return t.using_; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - }; - - // NO USING YET - struct no_using_t + // USING DATA + template + struct using_data_t { - using _traits = make_traits; - 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; + interpretable_list_t _dynamic_tables; + }; + + // USING + template + struct using_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + using _is_dynamic = typename std::conditional::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::value, "at least one duplicate argument detected in using()"); + + static_assert(::sqlpp::detail::all_t::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; // Member implementation with data and methods - template + template struct _impl_t { + template + void add(Table table) + { + static_assert(_is_dynamic::value, "add must not be called for static using()"); + static_assert(is_table_t
::value, "invalid table argument in add()"); + + using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t
::value>; + + _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_impl(Table table, const std::true_type&) + { + return _data._dynamic_tables.emplace_back(table); + } + + template + void _add_impl(Table table, const std::false_type&); + + public: _data_t _data; }; @@ -144,61 +104,101 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = using_data_t; - _impl_t no_using; - _impl_t& operator()() { return no_using; } - const _impl_t& operator()() const { return no_using; } + _impl_t using_; + _impl_t& operator()() { return using_; } + const _impl_t& operator()() const { return using_; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto using_(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), using_data_t{args...} }; - } - - template - auto dynamic_using(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement"); - return { *static_cast(this), using_data_t<_database_t, Args...>{args...} }; - } }; }; - // Interpreters - template - struct serializer_t> - { - using T = using_data_t; + // NO USING YET + struct no_using_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_using; + _impl_t& operator()() { return no_using; } + const _impl_t& operator()() const { return no_using; } + + template + static auto _get_member(T t) -> decltype(t.no_using) + { + return t.no_using; + } + }; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto using_(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), using_data_t{args...} }; + } + + template + auto dynamic_using(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement"); + return { *static_cast(this), using_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = using_data_t; + + 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 diff --git a/include/sqlpp11/value_type.h b/include/sqlpp11/value_type.h index e7f38198..2fa3bee1 100644 --- a/include/sqlpp11/value_type.h +++ b/include/sqlpp11/value_type.h @@ -32,7 +32,7 @@ namespace sqlpp { - template - using value_type_t = value_type_of>; + template + using value_type_t = value_type_of>; } #endif diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index 39799bfe..7d6d15e4 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -63,17 +63,17 @@ namespace sqlpp std::string _name; }; - template - struct serializer_t - { - using T = verbatim_table_t; + template + struct serializer_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) diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index 93331606..8c9446e7 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -36,157 +36,116 @@ namespace sqlpp { - // WHERE DATA - template - struct where_data_t - { - where_data_t(Expressions... expressions): - _expressions(expressions...) - {} + // WHERE DATA + template + 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; - interpretable_list_t _dynamic_expressions; - }; + std::tuple _expressions; + interpretable_list_t _dynamic_expressions; + }; - // WHERE(EXPR) - template - struct where_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + // WHERE(EXPR) + template + struct where_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; #warning: is_dynamic should be using a template alias (making it easier to replace the logic) - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _is_dynamic = typename std::conditional::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::value...>::value, "at least one argument is an assignment in where()"); - static_assert(sqlpp::detail::all_t::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::value...>::value, "at least one argument is an assignment in where()"); + static_assert(sqlpp::detail::all_t::value...>::value, "at least one argument is not valid expression in where()"); - // Data - using _data_t = where_data_t; + // Data + using _data_t = where_data_t; - // Member implementation with data and methods - template - struct _impl_t - { - template - void add_ntc(Expression expression) - { - add(expression); - } + // Member implementation with data and methods + template + struct _impl_t + { + template + void add_ntc(Expression expression) + { + add(expression); + } - template - void add(Expression expression) - { - static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where"); - static_assert(is_expression_t::value, "invalid expression argument in where::add()"); - static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in where::add()"); + template + void add(Expression expression) + { + static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where"); + static_assert(is_expression_t::value, "invalid expression argument in where::add()"); + static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in where::add()"); - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; + using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::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 - void _add_impl(Expression expression, const std::true_type&) - { - return _data._dynamic_expressions.emplace_back(expression); - } + private: + template + void _add_impl(Expression expression, const std::true_type&) + { + return _data._dynamic_expressions.emplace_back(expression); + } - template - void _add_impl(Expression expression, const std::false_type&); + template + 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 - struct _member_t - { - using _data_t = where_data_t; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = where_data_t; - _impl_t where; - _impl_t& operator()() { return where; } - const _impl_t& operator()() const { return where; } + _impl_t where; + _impl_t& operator()() { return where; } + const _impl_t& operator()() const { return where; } - template - static auto _get_member(T t) -> decltype(t.where) - { - return t.where; - } - }; + template + static auto _get_member(T t) -> decltype(t.where) + { + return t.where; + } + }; - // Additional methods for the statement - template - struct _methods_t - { - }; - }; + // Additional methods for the statement + template + struct _methods_t + { + }; + }; - template<> - struct where_data_t - { - bool _condition; - }; + template<> + struct where_data_t + { + bool _condition; + }; - // WHERE(BOOL) - template<> - struct where_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - - // Data - using _data_t = where_data_t; - - // Member implementation with data and methods - template - struct _impl_t - { - _data_t _data; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = where_data_t; - - _impl_t where; - _impl_t& operator()() { return where; } - const _impl_t& operator()() const { return where; } - - template - static auto _get_member(T t) -> decltype(t.where) - { - return t.where; - } - }; - - // Additional methods for the statement - template - struct _methods_t - { - }; - - }; - - // NO WHERE YET - struct no_where_t + // WHERE(BOOL) + template<> + struct where_t { using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data - using _data_t = no_data_t; + using _data_t = where_data_t; // Member implementation with data and methods template @@ -199,16 +158,16 @@ namespace sqlpp template struct _member_t { - using _data_t = no_data_t; + using _data_t = where_data_t; - _impl_t no_where; - _impl_t& operator()() { return no_where; } - const _impl_t& operator()() const { return no_where; } + _impl_t where; + _impl_t& operator()() { return where; } + const _impl_t& operator()() const { return where; } template - 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 struct _methods_t { - using _database_t = typename Policies::_database_t; - template - using _new_statement_t = typename Policies::template _new_statement_t; - - template - auto where(Args... args) - -> _new_statement_t> - { - return { *static_cast(this), where_data_t{args...} }; - } - - template - auto dynamic_where(Args... args) - -> _new_statement_t> - { - static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement"); - return { *static_cast(this), where_data_t<_database_t, Args...>{args...} }; - } }; + }; - // Interpreters - template - struct serializer_t> - { - using T = where_data_t; + // NO WHERE YET + struct no_where_t + { + using _traits = make_traits; + 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 + struct _impl_t + { + _data_t _data; }; - template - struct serializer_t> + // Member template for adding the named member to a statement + template + struct _member_t { - using T = where_data_t; + using _data_t = no_data_t; - static Context& _(const T& t, Context& context) - { - if (not t._condition) - context << " WHERE NULL"; - return context; - } + _impl_t no_where; + _impl_t& operator()() { return no_where; } + const _impl_t& operator()() const { return no_where; } + + template + static auto _get_member(T t) -> decltype(t.no_where) + { + return t.no_where; + } }; + // Additional methods for the statement + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_statement_t = typename Policies::template _new_statement_t; + + template + auto where(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), where_data_t{args...} }; + } + + template + auto dynamic_where(Args... args) + -> _new_statement_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement"); + return { *static_cast(this), where_data_t<_database_t, Args...>{args...} }; + } + }; + }; + + // Interpreters + template + struct serializer_t> + { + using T = where_data_t; + + 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 + struct serializer_t> + { + using T = where_data_t; + + static Context& _(const T& t, Context& context) + { + if (not t._condition) + context << " WHERE NULL"; + return context; + } + }; + } #endif diff --git a/include/sqlpp11/wrap_operand.h b/include/sqlpp11/wrap_operand.h index e5be8c06..177f9294 100644 --- a/include/sqlpp11/wrap_operand.h +++ b/include/sqlpp11/wrap_operand.h @@ -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 + struct serializer_t { - 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 - struct serializer_t - { - 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 + struct serializer_t { - 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 - struct serializer_t - { - 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 + struct serializer_t { - 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 - struct serializer_t - { - 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 + struct serializer_t { - 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 - struct serializer_t - { - using Operand = text_operand; + template + struct wrap_operand + { + using type = T; + }; - static Context& _(const Operand& t, Context& context) - { - context << '\'' << context.escape(t._t) << '\''; - return context; - } - }; + template<> + struct wrap_operand + { + using type = boolean_operand; + }; - template - struct wrap_operand - { - using type = T; - }; + template + struct wrap_operand::value>::type> + { + using type = integral_operand; + }; - template<> - struct wrap_operand - { - using type = boolean_operand; - }; + template + struct wrap_operand::value>::type> + { + using type = floating_point_operand; + }; - template - struct wrap_operand::value>::type> - { - using type = integral_operand; - }; + template + struct wrap_operand::value>::type> + { + using type = text_operand; + }; - template - struct wrap_operand::value>::type> - { - using type = floating_point_operand; - }; + // FIXME: Need to allow std::ref arguments - template - struct wrap_operand::value>::type> - { - using type = text_operand; - }; - - // FIXME: Need to allow std::ref arguments - - template - using wrap_operand_t = typename wrap_operand::type; + template + using wrap_operand_t = typename wrap_operand::type; } diff --git a/include/sqlpp11/wrong.h b/include/sqlpp11/wrong.h index af7ce7f4..9249673e 100644 --- a/include/sqlpp11/wrong.h +++ b/include/sqlpp11/wrong.h @@ -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 - 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 - using wrong_t = typename detail::wrong::type; + struct wrong + { + using type = std::false_type; + }; + } + template + using wrong_t = typename detail::wrong::type; } #endif