diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index c280c893..eeb9e2b6 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -28,7 +28,7 @@ #define SQLPP_ALIAS_H #include -#include +#include namespace sqlpp { @@ -46,24 +46,21 @@ namespace sqlpp Expression _expression; }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = expression_alias_t; + + static Context& _(const T& t, Context& context) { - using T = expression_alias_t; + 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; - } - }; - - } } #endif 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 270dea20..b4d90fae 100644 --- a/include/sqlpp11/all_of.h +++ b/include/sqlpp11/all_of.h @@ -34,36 +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 {}; + } - namespace vendor - { - 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 b4897b6a..a193b825 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -32,9 +32,7 @@ namespace sqlpp { - namespace vendor - { - template + template struct any_t { using _traits = make_traits, ::sqlpp::tag::multi_expression>; @@ -64,34 +62,30 @@ namespace sqlpp Select _select; }; - } - namespace vendor - { - template - struct serializer_t> + 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 vendor::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 }; + context << "ANY("; + serialize(t._select, context); + context << ")"; + return context; } + }; + + template + auto any(T t) -> 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 }; + } - } } #endif diff --git a/include/sqlpp11/assignment.h b/include/sqlpp11/assignment.h new file mode 100644 index 00000000..8161db1b --- /dev/null +++ b/include/sqlpp11/assignment.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_ASSIGNMENT_H +#define SQLPP_ASSIGNMENT_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + template + struct is_trivial_t + { + static constexpr bool _(const T&) + { + return false; + } + }; + + template + struct is_trivial_t::value, void>::type> + { + static bool _(const T& t) + { + return t._is_trivial(); + } + }; + + template + bool is_trivial(const T& t) + { + return is_trivial_t::_(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) + { + 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) + { + 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 50ca491c..e4470be9 100644 --- a/include/sqlpp11/avg.h +++ b/include/sqlpp11/avg.h @@ -31,77 +31,71 @@ namespace sqlpp { - namespace vendor - { - template + template struct avg_t: public floating_point::template expression_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 - { - 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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::avg_t; + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; - static Context& _(const T& t, Context& context) + 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 { - context << "AVG("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + 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; + }; + + template + struct serializer_t> + { + using T = avg_t; + + static Context& _(const T& t, Context& context) + { + context << "AVG("; + if (std::is_same::value) + { + serialize(Flag(), context); + context << ' '; } - }; - } + serialize(t._expr, context); + context << ")"; + return context; + } + }; template - auto avg(T t) -> typename vendor::avg_t> + auto avg(T t) -> avg_t> { - static_assert(is_numeric_t>::value, "avg() requires a value expression as argument"); + static_assert(is_numeric_t>::value, "avg() requires a value expression as argument"); return { t }; } template - auto avg(const sqlpp::distinct_t&, T t) -> typename vendor::avg_t> + auto avg(const sqlpp::distinct_t&, T t) -> avg_t> { - static_assert(is_numeric_t>::value, "avg() requires a value expression as argument"); + static_assert(is_numeric_t>::value, "avg() requires a value expression as argument"); return { t }; } diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index d1f06749..deeb5342 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -29,10 +29,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace sqlpp @@ -43,74 +43,74 @@ 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 - vendor::equal_to_t> operator==(T t) const + equal_to_t> operator==(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } template - vendor::not_equal_to_t> operator!=(T t) const + not_equal_to_t> operator!=(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } template - vendor::less_than_t> operator<(T t) const + less_than_t> operator<(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } template - vendor::less_equal_t> operator<=(T t) const + less_equal_t> operator<=(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } template - vendor::greater_than_t> operator>(T t) const + greater_than_t> operator>(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } template - vendor::greater_equal_t> operator>=(T t) const + greater_equal_t> operator>=(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); return { *static_cast(this), rhs{t} }; } - vendor::is_null_t is_null() const + is_null_t is_null() const { return { *static_cast(this) }; } - vendor::is_null_t is_not_null() const + is_null_t is_not_null() const { return { *static_cast(this) }; } @@ -127,17 +127,17 @@ namespace sqlpp // Hint: use value_list wrapper for containers... template - vendor::in_t...> in(T... t) const + in_t...> in(T... t) const { - static_assert(detail::all_t<_is_valid_comparison_operand>::value...>::value, "at least one operand of in() is not valid"); - return { *static_cast(this), vendor::wrap_operand_t{t}... }; + static_assert(detail::all_t<_is_valid_comparison_operand>::value...>::value, "at least one operand of in() is not valid"); + return { *static_cast(this), wrap_operand_t{t}... }; } template - vendor::in_t...> not_in(T... t) const + in_t...> not_in(T... t) const { - static_assert(detail::all_t<_is_valid_comparison_operand>::value...>::value, "at least one operand of in() is not valid"); - return { *static_cast(this), vendor::wrap_operand_t{t}... }; + static_assert(detail::all_t<_is_valid_comparison_operand>::value...>::value, "at least one operand of in() is not valid"); + return { *static_cast(this), wrap_operand_t{t}... }; } }; diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index d5935484..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,111 +97,111 @@ 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 { template - vendor::logical_and_t> operator and(T t) const + logical_and_t> operator and(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), rhs{t} }; } template - vendor::logical_or_t> operator or(T t) const + logical_or_t> operator or(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), rhs{t} }; } - vendor::logical_not_t operator not() const + logical_not_t operator not() const { return { *static_cast(this) }; } @@ -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/vendor/char_result_row.h b/include/sqlpp11/char_result_row.h similarity index 100% rename from include/sqlpp11/vendor/char_result_row.h rename to include/sqlpp11/char_result_row.h diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 47f764f1..31da39a2 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -33,17 +33,17 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include 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 @@ -81,43 +81,40 @@ namespace sqlpp } template - auto operator =(T t) const -> vendor::assignment_t> + auto operator =(T t) const -> assignment_t> { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand assignment operand"); return { *this, rhs{t} }; } auto operator =(sqlpp::null_t) const - ->vendor::assignment_t + ->assignment_t { static_assert(can_be_null_t::value, "column cannot be null"); return { *this, {} }; } auto operator =(sqlpp::default_value_t) const - ->vendor::assignment_t + ->assignment_t { return { *this, {} }; } }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = column_t; + + static Context& _(const T& t, Context& context) { - using T = column_t; + 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; - } - }; - - } } #endif diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/concat.h new file mode 100644 index 00000000..ecae74ce --- /dev/null +++ b/include/sqlpp11/concat.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_CONCAT_H +#define SQLPP_CONCAT_H + +#include +#include +#include + +namespace sqlpp +{ + // 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 + { + 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; + }; + + 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 838189a6..af24e47b 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -32,77 +32,71 @@ namespace sqlpp { - namespace vendor - { - template + template struct count_t: public sqlpp::detail::integral::template expression_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 - { - 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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::count_t; + using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; - static Context& _(const T& t, Context& context) + 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 { - context << "COUNT("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + 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; + }; + + template + struct serializer_t> + { + using T = count_t; + + static Context& _(const T& t, Context& context) + { + context << "COUNT("; + if (std::is_same::value) + { + serialize(Flag(), context); + context << ' '; } - }; - } + serialize(t._expr, context); + context << ")"; + return context; + } + }; template - auto count(T t) -> typename vendor::count_t> + auto count(T t) -> count_t> { - static_assert(is_expression_t>::value, "count() requires an expression as argument"); + static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } template - auto count(const sqlpp::distinct_t&, T t) -> typename vendor::count_t> + auto count(const sqlpp::distinct_t&, T t) -> count_t> { - static_assert(is_expression_t>::value, "count() requires an expression as argument"); + static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/default_value.h b/include/sqlpp11/default_value.h index 87c4b523..bb8fce6d 100644 --- a/include/sqlpp11/default_value.h +++ b/include/sqlpp11/default_value.h @@ -39,20 +39,17 @@ namespace sqlpp static constexpr bool _is_trivial() { return false; } }; - namespace vendor - { - 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/detail/column_index_sequence.h b/include/sqlpp11/detail/column_index_sequence.h index 277e85e2..be5a2c49 100644 --- a/include/sqlpp11/detail/column_index_sequence.h +++ b/include/sqlpp11/detail/column_index_sequence.h @@ -49,7 +49,7 @@ namespace sqlpp }; template - struct make_column_index_sequence_impl, vendor::multi_field_t, Rest...> + struct make_column_index_sequence_impl, multi_field_t, Rest...> { using type = typename make_column_index_sequence_impl, Rest...>::type; }; diff --git a/include/sqlpp11/detail/copy_tuple_args.h b/include/sqlpp11/detail/copy_tuple_args.h index 0891e6ac..3496a2be 100644 --- a/include/sqlpp11/detail/copy_tuple_args.h +++ b/include/sqlpp11/detail/copy_tuple_args.h @@ -57,7 +57,7 @@ namespace sqlpp template class Target, typename First, typename T> struct copy_tuple_args_impl { - static_assert(vendor::wrong_t::value, "copy_tuple_args must be called with a tuple"); + static_assert(wrong_t::value, "copy_tuple_args must be called with a tuple"); }; template class Target, typename First, typename... Args> diff --git a/include/sqlpp11/detail/type_set.h b/include/sqlpp11/detail/type_set.h index ecc51a23..9f5f855f 100644 --- a/include/sqlpp11/detail/type_set.h +++ b/include/sqlpp11/detail/type_set.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include namespace sqlpp @@ -73,7 +73,7 @@ namespace sqlpp template struct is_element_of { - static_assert(::sqlpp::vendor::wrong_t::value, "SET has to be a type set"); + static_assert(::sqlpp::wrong_t::value, "SET has to be a type set"); }; template @@ -85,7 +85,7 @@ namespace sqlpp template struct joined_set { - static_assert(::sqlpp::vendor::wrong_t::value, "L and R have to be type sets"); + static_assert(::sqlpp::wrong_t::value, "L and R have to be type sets"); }; template @@ -100,7 +100,7 @@ namespace sqlpp template struct is_superset_of { - static_assert(::sqlpp::vendor::wrong_t::value, "L and R have to be type sets"); + static_assert(::sqlpp::wrong_t::value, "L and R have to be type sets"); }; template @@ -118,7 +118,7 @@ namespace sqlpp template struct is_disjunct_from { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for is_disjunct_from"); + static_assert(::sqlpp::wrong_t::value, "invalid argument for is_disjunct_from"); }; template @@ -174,7 +174,7 @@ namespace sqlpp template struct make_joined_set { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for joined set"); + static_assert(::sqlpp::wrong_t::value, "invalid argument for joined set"); }; template<> @@ -197,7 +197,7 @@ namespace sqlpp template struct make_difference_set { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for difference set"); + static_assert(::sqlpp::wrong_t::value, "invalid argument for difference set"); }; template diff --git a/include/sqlpp11/exists.h b/include/sqlpp11/exists.h index 8d767754..54f28208 100644 --- a/include/sqlpp11/exists.h +++ b/include/sqlpp11/exists.h @@ -31,65 +31,59 @@ namespace sqlpp { - namespace vendor - { - template + template struct exists_t: public boolean::template expression_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 - { - 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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::exists_t; - static Context& _(const T& t, Context& context) + static_assert(is_select_t; + + static Context& _(const T& t, Context& context) + { + context << "EXISTS("; + serialize(t._select, context); + context << ")"; + return context; + } + }; template - auto exists(T t) -> typename vendor::exists_t> + auto exists(T t) -> exists_t> { - static_assert(is_select_t>::value, "exists() requires a select expression as argument"); + static_assert(is_select_t>::value, "exists() requires a select expression as argument"); return { t }; } diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h new file mode 100644 index 00000000..28a72bb3 --- /dev/null +++ b/include/sqlpp11/expression.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_EXPRESSION_H +#define SQLPP_EXPRESSION_H + +#include +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + 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; + + 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; + maybe_tvin_t _rhs; + }; + + template + struct serializer_t> + { + using T = equal_to_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + serialize(t._lhs, context); + if (t._rhs._is_trivial()) + { + 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> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + 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; + maybe_tvin_t _rhs; + }; + + template + struct serializer_t> + { + using T = not_equal_to_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + serialize(t._lhs, context); + if (t._rhs._is_trivial()) + { + 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> + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + + 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 = 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> + { + using _traits = make_traits, sqlpp::tag::expression>; + using _recursive_traits = make_recursive_traits; + + 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; + }; + + template + struct serializer_t> + { + using T = binary_expression_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + serialize(t._lhs, context); + context << O::_name; + serialize(t._rhs, context); + context << ")"; + return context; + } + }; + + 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; + + 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 new file mode 100644 index 00000000..2a389e5b --- /dev/null +++ b/include/sqlpp11/expression_fwd.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_EXPRESSION_FWD_H +#define SQLPP_EXPRESSION_FWD_H + +namespace sqlpp +{ + namespace detail + { + struct boolean; + struct integral; + struct floating_point; + } + + namespace op + { + struct less + { + 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 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 + { + 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_and + { + using _traits = make_traits<::sqlpp::detail::boolean>; + static constexpr const char* _name = " AND "; + }; + + struct logical_not + { + using _traits = make_traits<::sqlpp::detail::boolean>; + }; + + template + struct plus + { + using _traits = make_traits; + static constexpr const char* _name = "+"; + }; + + template + struct minus + { + using _traits = make_traits; + static constexpr const char* _name = "-"; + }; + + 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 modulus + { + using _traits = make_traits<::sqlpp::detail::integral>; + static constexpr const char* _name = "%"; + }; + + template + struct unary_minus + { + using _traits = make_traits; + static constexpr const char* _name = "-"; + }; + + template + struct unary_plus + { + using _traits = make_traits; + static constexpr const char* _name = "+"; + }; + } + + template + struct binary_expression_t; + + template + struct unary_expression_t; + + template + using less_than_t = binary_expression_t; + + template + using less_equal_t = binary_expression_t; + + template + using 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_equal_t = binary_expression_t; + + template + using logical_and_t = binary_expression_t; + + template + using logical_or_t = binary_expression_t; + + template + using plus_t = binary_expression_t, Rhs>; + + template + using minus_t = binary_expression_t, Rhs>; + + template + using multiplies_t = binary_expression_t, Rhs>; + + template + using divides_t = binary_expression_t; + + template + using modulus_t = binary_expression_t; + + template + using logical_not_t = unary_expression_t; + + template + using unary_plus_t = unary_expression_t, Rhs>; + + template + using unary_minus_t = unary_expression_t, Rhs>; + +} + +#endif diff --git a/include/sqlpp11/extra_tables.h b/include/sqlpp11/extra_tables.h new file mode 100644 index 00000000..4b25a04f --- /dev/null +++ b/include/sqlpp11/extra_tables.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_EXTRA_TABLES_H +#define SQLPP_EXTRA_TABLES_H + +#include +#include +#include + +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 + { + 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_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/vendor/field.h b/include/sqlpp11/field.h similarity index 61% rename from include/sqlpp11/vendor/field.h rename to include/sqlpp11/field.h index b843dc8d..1a5db815 100644 --- a/include/sqlpp11/vendor/field.h +++ b/include/sqlpp11/field.h @@ -31,44 +31,41 @@ namespace sqlpp { - namespace vendor - { - 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; + } #endif diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index 48bd70b9..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,134 +96,134 @@ 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 { template - vendor::plus_t> operator +(T t) const + plus_t> operator +(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), rhs{t} }; } template - vendor::minus_t> operator -(T t) const + minus_t> operator -(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), rhs{t} }; } template - vendor::multiplies_t> operator *(T t) const + multiplies_t> operator *(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; return { *static_cast(this), rhs{t} }; } template - vendor::divides_t> operator /(T t) const + divides_t> operator /(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; return { *static_cast(this), rhs{t} }; } - vendor::unary_plus_t operator +() const + unary_plus_t operator +() const { return { *static_cast(this) }; } - vendor::unary_minus_t operator -() const + unary_minus_t operator -() const { return { *static_cast(this) }; } @@ -231,50 +231,50 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> vendor::assignment_t>> - { - using rhs = vendor::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 -> vendor::assignment_t>> - { - using rhs = vendor::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 -> vendor::assignment_t>> - { - using rhs = vendor::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 -> vendor::assignment_t>> - { - using rhs = vendor::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 new file mode 100644 index 00000000..74babb1e --- /dev/null +++ b/include/sqlpp11/from.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_FROM_H +#define SQLPP_FROM_H + +#include +#include +#include +#include +#include + +namespace sqlpp +{ + // FROM DATA + template + struct from_data_t + { + from_data_t(Tables... tables): + _tables(tables...) + {} + + from_data_t(const from_data_t&) = default; + from_data_t(from_data_t&&) = default; + from_data_t& operator=(const from_data_t&) = default; + from_data_t& operator=(from_data_t&&) = default; + ~from_data_t() = default; + + std::tuple _tables; + 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 + { + 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_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 2d8ce0f6..a01aa323 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -30,9 +30,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -46,17 +46,17 @@ namespace sqlpp { template - auto value(T t) -> vendor::wrap_operand_t + auto value(T t) -> wrap_operand_t { using _provided_tables = detail::type_set<>; using _required_tables = ::sqlpp::detail::type_set<>; - static_assert(is_wrapped_value_t>::value, "value() is to be called with non-sql-type like int, or string"); + static_assert(is_wrapped_value_t>::value, "value() is to be called with non-sql-type like int, or string"); return { t }; } 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,20 +71,17 @@ namespace sqlpp std::string _verbatim; }; - namespace vendor - { - 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 @@ -104,7 +101,7 @@ namespace sqlpp template struct value_list_t // to be used in .in() method { - using _traits = make_traits>; + using _traits = make_traits>; using _recursive_traits = make_recursive_traits<>; using _container_t = Container; @@ -122,34 +119,31 @@ namespace sqlpp _container_t _container; }; - namespace vendor - { - 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 { - static_assert(is_wrapped_value_t>::value, "value_list() is to be called with a container of non-sql-type like std::vector, or std::list(string)"); + static_assert(is_wrapped_value_t>::value, "value_list() is to be called with a container of non-sql-type like std::vector, or std::list(string)"); return { c }; } diff --git a/include/sqlpp11/group_by.h b/include/sqlpp11/group_by.h new file mode 100644 index 00000000..8e369b0c --- /dev/null +++ b/include/sqlpp11/group_by.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_GROUP_BY_H +#define SQLPP_GROUP_BY_H + +#include +#include +#include +#include +#include +#include +#include + +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 + { + 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_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 new file mode 100644 index 00000000..d50f5600 --- /dev/null +++ b/include/sqlpp11/having.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_HAVING_H +#define SQLPP_HAVING_H + +#include +#include +#include +#include +#include +#include + +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 + { + 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_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/vendor/in.h b/include/sqlpp11/in.h similarity index 50% rename from include/sqlpp11/vendor/in.h rename to include/sqlpp11/in.h index ea4b9470..5ec661b4 100644 --- a/include/sqlpp11/vendor/in.h +++ b/include/sqlpp11/in.h @@ -29,63 +29,60 @@ #include #include -#include +#include #include namespace sqlpp { - namespace vendor + 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 = vendor::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/vendor/in_fwd.h b/include/sqlpp11/in_fwd.h similarity index 94% rename from include/sqlpp11/vendor/in_fwd.h rename to include/sqlpp11/in_fwd.h index 809c4cc2..3b464307 100644 --- a/include/sqlpp11/vendor/in_fwd.h +++ b/include/sqlpp11/in_fwd.h @@ -29,11 +29,8 @@ namespace sqlpp { - namespace vendor - { - template + template struct in_t; - } } diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index fa9320fb..491d9a8c 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -32,38 +32,35 @@ #include #include #include -#include -#include -#include +#include +#include +#include namespace sqlpp { struct insert_name_t {}; - struct insert_t: public vendor::statement_name_t + struct insert_t: public statement_name_t {}; - namespace vendor - { - 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 new file mode 100644 index 00000000..1be64b10 --- /dev/null +++ b/include/sqlpp11/insert_value.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_INSERT_VALUE_H +#define SQLPP_INSERT_VALUE_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + 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 + { + 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; + } + }; + +} + +#endif diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h new file mode 100644 index 00000000..831a6752 --- /dev/null +++ b/include/sqlpp11/insert_value_list.h @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_INSERT_VALUE_LIST_H +#define SQLPP_INSERT_VALUE_LIST_H + +#include +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + struct insert_default_values_data_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 + { + 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}...) + {} + + 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 + { + 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; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _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 << ")"; + } + return context; + } + }; + +} + +#endif diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index b5e2ad85..2b52fb6e 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include namespace sqlpp { @@ -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,145 +97,145 @@ 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 { template - vendor::plus_t, vendor::wrap_operand_t> operator +(T t) const + plus_t, wrap_operand_t> operator +(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } template - vendor::minus_t, vendor::wrap_operand_t> operator -(T t) const + minus_t, wrap_operand_t> operator -(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } template - vendor::multiplies_t, vendor::wrap_operand_t> operator *(T t) const + multiplies_t, wrap_operand_t> operator *(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } template - vendor::divides_t> operator /(T t) const + divides_t> operator /(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } template - vendor::modulus_t> operator %(T t) const + modulus_t> operator %(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } - vendor::unary_plus_t operator +() const + unary_plus_t operator +() const { return { *static_cast(this) }; } - vendor::unary_minus_t operator -() const + unary_minus_t operator -() const { return { *static_cast(this) }; } @@ -243,50 +243,50 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> vendor::assignment_t, vendor::wrap_operand_t>> - { - using rhs = vendor::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 -> vendor::assignment_t, vendor::wrap_operand_t>> - { - using rhs = vendor::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 -> vendor::assignment_t>> - { - using rhs = vendor::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 -> vendor::assignment_t, vendor::wrap_operand_t>> - { - using rhs = vendor::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.h b/include/sqlpp11/interpret.h index 42cc1524..4d1b2c20 100644 --- a/include/sqlpp11/interpret.h +++ b/include/sqlpp11/interpret.h @@ -27,15 +27,15 @@ #ifndef SQLPP_INTERPRET_H #define SQLPP_INTERPRET_H -#include +#include namespace sqlpp { template auto interpret(const T& t, Context& context) - -> decltype(vendor::interpreter_t::_(t, context)) + -> decltype(interpreter_t::_(t, context)) { - return vendor::interpreter_t::_(t, context); + return interpreter_t::_(t, context); } } diff --git a/include/sqlpp11/vendor/interpret_tuple.h b/include/sqlpp11/interpret_tuple.h similarity index 94% rename from include/sqlpp11/vendor/interpret_tuple.h rename to include/sqlpp11/interpret_tuple.h index aa12c9b8..04ac5d4a 100644 --- a/include/sqlpp11/vendor/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 new file mode 100644 index 00000000..28a2413b --- /dev/null +++ b/include/sqlpp11/interpretable.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_INTERPRETABLE_H +#define SQLPP_INTERPRETABLE_H + +#include +#include +#include +#include +#include + +namespace sqlpp +{ + 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 + { + return _impl->serialize(context); + } + + // 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 + { + return _impl->db_serialize(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; + }; + + 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/vendor/interpretable_list.h b/include/sqlpp11/interpretable_list.h similarity index 51% rename from include/sqlpp11/vendor/interpretable_list.h rename to include/sqlpp11/interpretable_list.h index a6b2d27e..e3641972 100644 --- a/include/sqlpp11/vendor/interpretable_list.h +++ b/include/sqlpp11/interpretable_list.h @@ -28,92 +28,89 @@ #define SQLPP_INTERPRETABLE_LIST_H #include -#include +#include namespace sqlpp { - namespace vendor - { - 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/vendor/interpreter.h b/include/sqlpp11/interpreter.h similarity index 79% rename from include/sqlpp11/vendor/interpreter.h rename to include/sqlpp11/interpreter.h index 17dd6075..cd7c9690 100644 --- a/include/sqlpp11/vendor/interpreter.h +++ b/include/sqlpp11/interpreter.h @@ -24,24 +24,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_VENDOR_INTERPRETER_H -#define SQLPP_VENDOR_INTERPRETER_H +#ifndef SQLPP_INTERPRETER_H +#define SQLPP_INTERPRETER_H -#include +#include namespace sqlpp { - namespace vendor - { - 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 new file mode 100644 index 00000000..9395e840 --- /dev/null +++ b/include/sqlpp11/into.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_INTO_H +#define SQLPP_INTO_H + +#include +#include +#include +#include + +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 + { + 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_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/vendor/is_null.h b/include/sqlpp11/is_null.h similarity index 55% rename from include/sqlpp11/vendor/is_null.h rename to include/sqlpp11/is_null.h index ad212cca..1aedf49a 100644 --- a/include/sqlpp11/vendor/is_null.h +++ b/include/sqlpp11/is_null.h @@ -33,58 +33,55 @@ namespace sqlpp { - namespace vendor - { - 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::vendor::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/vendor/is_null_fwd.h b/include/sqlpp11/is_null_fwd.h similarity index 95% rename from include/sqlpp11/vendor/is_null_fwd.h rename to include/sqlpp11/is_null_fwd.h index 0c8e62f0..8d53cc01 100644 --- a/include/sqlpp11/vendor/is_null_fwd.h +++ b/include/sqlpp11/is_null_fwd.h @@ -29,11 +29,8 @@ namespace sqlpp { - namespace vendor - { - template + template struct is_null_t; - } } #endif diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 926de5c2..9d0a92f4 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -29,7 +29,7 @@ #include #include -#include +#include namespace sqlpp { @@ -74,7 +74,7 @@ namespace sqlpp static constexpr const char* _name = " RIGHT OUTER "; }; - template + template struct join_t { using _traits = make_traits; @@ -83,7 +83,7 @@ namespace sqlpp static_assert(is_table_t::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t::value, "rhs argument for join() has to be a table"); static_assert(not is_join_t::value, "rhs argument for join must not be a join"); - static_assert(vendor::is_noop::value or is_on_t::value, "invalid on expression in join().on()"); + static_assert(is_noop::value or is_on_t::value, "invalid on expression in join().on()"); static_assert(::sqlpp::detail::is_disjunct_from, provided_tables_of>::value, "joined tables must not be identical"); @@ -96,7 +96,7 @@ namespace sqlpp auto on(Expr... expr) -> set_on_t> { - static_assert(vendor::is_noop::value, "cannot call on() twice for a single join()"); + static_assert(is_noop::value, "cannot call on() twice for a single join()"); return { _lhs, _rhs, {std::tuple{expr...}} @@ -106,35 +106,35 @@ namespace sqlpp template join_t join(T t) { - static_assert(not vendor::is_noop::value, "join type requires on()"); + static_assert(not is_noop::value, "join type requires on()"); return { *this, t }; } template join_t inner_join(T t) { - static_assert(not vendor::is_noop::value, "join type requires on()"); + static_assert(not is_noop::value, "join type requires on()"); return { *this, t }; } template join_t outer_join(T t) { - static_assert(not vendor::is_noop::value, "join type requires on()"); + static_assert(not is_noop::value, "join type requires on()"); return { *this, t }; } template join_t left_outer_join(T t) { - static_assert(not vendor::is_noop::value, "join type requires on()"); + static_assert(not is_noop::value, "join type requires on()"); return { *this, t }; } template join_t right_outer_join(T t) { - static_assert(not vendor::is_noop::value, "join type requires on()"); + static_assert(not is_noop::value, "join type requires on()"); return { *this, t }; } @@ -143,26 +143,23 @@ namespace sqlpp On _on; }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = join_t; + + static Context& _(const T& t, Context& context) { - using T = join_t; + 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 vendor::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; - } - }; - - } } #endif diff --git a/include/sqlpp11/vendor/like.h b/include/sqlpp11/like.h similarity index 52% rename from include/sqlpp11/vendor/like.h rename to include/sqlpp11/like.h index bb58030d..46f1572a 100644 --- a/include/sqlpp11/vendor/like.h +++ b/include/sqlpp11/like.h @@ -33,58 +33,55 @@ namespace sqlpp { - namespace vendor + 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 new file mode 100644 index 00000000..99a31928 --- /dev/null +++ b/include/sqlpp11/limit.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_LIMIT_H +#define SQLPP_LIMIT_H + +#include +#include +#include + +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 + { + 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_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; + } + }; + + 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 582d6a9f..a96dfe4d 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -31,64 +31,58 @@ namespace sqlpp { - namespace vendor - { - template + template struct max_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(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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::max_t; + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; - static Context& _(const T& t, Context& context) + 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 { - context << "MAX("; - serialize(t._expr, context); - context << ")"; - return context; - } - }; - } + 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; + }; + + 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 vendor::max_t> + auto max(T t) -> max_t> { - static_assert(is_expression_t>::value, "max() requires a value expression as argument"); + static_assert(is_expression_t>::value, "max() requires a value expression as argument"); return { t }; } diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index 5930a48c..3993bf81 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -31,64 +31,58 @@ namespace sqlpp { - namespace vendor - { - template + template struct min_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(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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::min_t; + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; - static Context& _(const T& t, Context& context) + 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 { - context << "MIN("; - serialize(t._expr, context); - context << ")"; - return context; - } - }; - } + 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; + }; + + 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 vendor::min_t> + auto min(T t) -> min_t> { - static_assert(is_expression_t>::value, "min() requires a value expression as argument"); + static_assert(is_expression_t>::value, "min() requires a value expression as argument"); return { t }; } diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index 650e1bc7..52de9d5f 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -110,31 +110,28 @@ namespace sqlpp std::tuple _columns; }; - namespace vendor - { - 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 new file mode 100644 index 00000000..4aa93fa2 --- /dev/null +++ b/include/sqlpp11/named_interpretable.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_NAMED_SERIALIZABLE_H +#define SQLPP_NAMED_SERIALIZABLE_H + +#include +#include +#include + +namespace sqlpp +{ + 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 + { + return _impl->serialize(context); + } + + // 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 + { + 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 + { + Db::_interpret_interpretable(_t, context); + return context; + } + + std::string _get_name() const + { + return T::_name_t::_get_name(); + } + + T _t; + }; + + std::shared_ptr _impl; + }; + + template + struct serializer_t> + { + using T = named_interpretable_t; + + static Context& _(const T& t, Context& context) + { + t.serialize(context); + return context; + } + }; + +} + +#endif diff --git a/include/sqlpp11/vendor/noop.h b/include/sqlpp11/noop.h similarity index 68% rename from include/sqlpp11/vendor/noop.h rename to include/sqlpp11/noop.h index 8ed22a75..74198fd0 100644 --- a/include/sqlpp11/vendor/noop.h +++ b/include/sqlpp11/noop.h @@ -29,52 +29,49 @@ #include #include -#include +#include namespace sqlpp { - namespace vendor - { #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/vendor/noop_fwd.h b/include/sqlpp11/noop_fwd.h similarity index 94% rename from include/sqlpp11/vendor/noop_fwd.h rename to include/sqlpp11/noop_fwd.h index 243f77a2..0c87c75e 100644 --- a/include/sqlpp11/vendor/noop_fwd.h +++ b/include/sqlpp11/noop_fwd.h @@ -29,12 +29,9 @@ namespace sqlpp { - namespace vendor - { - 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 7119998d..a3309b15 100644 --- a/include/sqlpp11/null.h +++ b/include/sqlpp11/null.h @@ -37,20 +37,17 @@ namespace sqlpp using _recursive_traits = make_recursive_traits<>; }; - namespace vendor - { - 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 new file mode 100644 index 00000000..9d89674c --- /dev/null +++ b/include/sqlpp11/offset.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_OFFSET_H +#define SQLPP_OFFSET_H + +#include +#include +#include + +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 + { + 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; + } + }; +} + +#endif diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index caa23bc6..26b93a9f 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -28,8 +28,8 @@ #define SQLPP_ON_H #include -#include -#include +#include +#include #include namespace sqlpp @@ -53,30 +53,27 @@ namespace sqlpp } std::tuple _expressions; - vendor::interpretable_list_t _dynamic_expressions; + interpretable_list_t _dynamic_expressions; }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = on_t; + + static Context& _(const T& t, Context& context) { - 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); + 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; + } + }; - } } #endif diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h new file mode 100644 index 00000000..0f9fdc75 --- /dev/null +++ b/include/sqlpp11/order_by.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_ORDER_BY_H +#define SQLPP_ORDER_BY_H + +#include +#include +#include +#include +#include +#include +#include + +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 + { + 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_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 565f236a..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,20 +57,17 @@ namespace sqlpp ~parameter_t() = default; }; - namespace vendor - { - 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&) @@ -82,7 +79,7 @@ namespace sqlpp template auto parameter(const ValueType&, const AliasProvider&) - -> parameter_t, AliasProvider> + -> parameter_t, AliasProvider> { static_assert(is_expression_t::value, "first argument is not a value type"); static_assert(is_alias_provider_t::value, "second argument is not an alias provider"); diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index 46e27c0c..e7386d2a 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include namespace sqlpp @@ -37,7 +37,7 @@ namespace sqlpp template struct parameter_list_t { - static_assert(vendor::wrong_t::value, "Template parameter for parameter_list_t has to be a tuple"); + static_assert(wrong_t::value, "Template parameter for parameter_list_t has to be a tuple"); }; template diff --git a/include/sqlpp11/vendor/policy_update.h b/include/sqlpp11/policy_update.h similarity index 61% rename from include/sqlpp11/vendor/policy_update.h rename to include/sqlpp11/policy_update.h index a65c332b..ecb61181 100644 --- a/include/sqlpp11/vendor/policy_update.h +++ b/include/sqlpp11/policy_update.h @@ -24,35 +24,32 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_VENDOR_POLICY_UPDATE_H -#define SQLPP_VENDOR_POLICY_UPDATE_H +#ifndef SQLPP_POLICY_UPDATE_H +#define SQLPP_POLICY_UPDATE_H -#include +#include namespace sqlpp { - namespace vendor - { - 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 671a310f..f3b0a722 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -31,17 +31,17 @@ #include #include #include -#include +#include #warning: need to use another table provider, since delete can be used with several tables -#include -#include -#include -#include +#include +#include +#include +#include namespace sqlpp { struct remove_name_t {}; - struct remove_t: public vendor::statement_name_t + struct remove_t: public statement_name_t { using _traits = make_traits; struct _name_t {}; @@ -79,29 +79,26 @@ namespace sqlpp }; - namespace vendor - { - 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 d09bf79a..ce4d4eb3 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -28,8 +28,8 @@ #define SQLPP_RESULT_ROW_H #include -#include -#include +#include +#include #include #include @@ -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...>> + struct result_field>>: + 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 bda042f9..0c5b320f 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -29,57 +29,54 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace sqlpp { struct select_name_t {}; - struct select_t: public vendor::statement_name_t + struct select_t: public statement_name_t {}; - namespace vendor - { - 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 new file mode 100644 index 00000000..7dc7937c --- /dev/null +++ b/include/sqlpp11/select_column_list.h @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_SELECT_COLUMN_LIST_H +#define SQLPP_SELECT_COLUMN_LIST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace detail + { + template + struct select_traits + { + using _traits = make_traits; + struct _name_t {}; + }; + + template + struct select_traits + { + using _traits = make_traits, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>; + using _name_t = typename Column::_name_t; + }; + } + + 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 + { + 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) + { + 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; } + + template + static auto _get_member(T t) -> decltype(t.selected_columns) + { + return t.selected_columns; + } + }; + + // 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); + } + + 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(); + + return {{}, get_dynamic_names(), db.prepare_select(*this)}; + } +#endif + }; + + }; + + namespace detail + { + template + using make_select_column_list_t = + copy_tuple_args_t::_(std::declval())...))>; + } + + struct no_select_column_list_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + struct _name_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> + { + 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 new file mode 100644 index 00000000..8147e5d2 --- /dev/null +++ b/include/sqlpp11/select_flag_list.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_SELECT_FLAG_LIST_H +#define SQLPP_SELECT_FLAG_LIST_H + +#include +#include +#include +#include +#include +#include + +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 + { + 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_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; + } + }; + + +} + +#endif diff --git a/include/sqlpp11/select_flags.h b/include/sqlpp11/select_flags.h index 3462f224..4b07d6be 100644 --- a/include/sqlpp11/select_flags.h +++ b/include/sqlpp11/select_flags.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include namespace sqlpp @@ -42,18 +42,15 @@ namespace sqlpp }; static constexpr all_t all = {}; - namespace vendor - { - 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 { @@ -62,18 +59,15 @@ namespace sqlpp }; static constexpr distinct_t distinct = {}; - namespace vendor - { - 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 { @@ -82,18 +76,15 @@ namespace sqlpp }; static constexpr straight_join_t straight_join = {}; - namespace vendor - { - 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/vendor/select_pseudo_table.h b/include/sqlpp11/select_pseudo_table.h similarity index 85% rename from include/sqlpp11/vendor/select_pseudo_table.h rename to include/sqlpp11/select_pseudo_table.h index 86e9e4b9..3378035a 100644 --- a/include/sqlpp11/vendor/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> + template + struct serializer_t> + { + using T = select_pseudo_table_t; + + static Context& _(const T& t, Context& context) { - using T = select_pseudo_table_t; + serialize(t._select, context); + return context; + } + }; - static Context& _(const T& t, Context& context) - { - serialize(t._select, context); - return context; - } - }; - - } } #endif diff --git a/include/sqlpp11/serialize.h b/include/sqlpp11/serialize.h index 296ae043..e7331320 100644 --- a/include/sqlpp11/serialize.h +++ b/include/sqlpp11/serialize.h @@ -27,28 +27,25 @@ #ifndef SQLPP_SERIALIZE_H #define SQLPP_SERIALIZE_H -#include +#include namespace sqlpp { template auto serialize(const T& t, Context& context) - -> decltype(vendor::serializer_t::_(t, context)) + -> decltype(serializer_t::_(t, context)) { - return vendor::serializer_t::_(t, context); + return serializer_t::_(t, context); } /* - namespace vendor // Required if you want to call serialize(sqlpp::value(7), printer), for instance - { - template - auto serialize(const T& t, Context& context) - -> decltype(vendor::serializer_t::_(t, context)) - { - return vendor::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/vendor/serializer.h b/include/sqlpp11/serializer.h similarity index 79% rename from include/sqlpp11/vendor/serializer.h rename to include/sqlpp11/serializer.h index 1a5031f9..682c9602 100644 --- a/include/sqlpp11/vendor/serializer.h +++ b/include/sqlpp11/serializer.h @@ -24,24 +24,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_VENDOR_SERIALIZER_H -#define SQLPP_VENDOR_SERIALIZER_H +#ifndef SQLPP_SERIALIZER_H +#define SQLPP_SERIALIZER_H -#include +#include namespace sqlpp { - namespace vendor - { - 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/vendor/simple_column.h b/include/sqlpp11/simple_column.h similarity index 73% rename from include/sqlpp11/vendor/simple_column.h rename to include/sqlpp11/simple_column.h index 56d664bc..34f030e3 100644 --- a/include/sqlpp11/vendor/simple_column.h +++ b/include/sqlpp11/simple_column.h @@ -27,36 +27,33 @@ #ifndef SQLPP_SIMPLE_COLUMN_H #define SQLPP_SIMPLE_COLUMN_H -#include +#include namespace sqlpp { - namespace vendor - { - 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 new file mode 100644 index 00000000..0f760e10 --- /dev/null +++ b/include/sqlpp11/single_table.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_SINGLE_TABLE_H +#define SQLPP_SINGLE_TABLE_H + +#include +#include +#include +#include + +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 + { + 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_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 5fe64cac..41519e5e 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -32,9 +32,7 @@ namespace sqlpp { - namespace vendor - { - template + template struct some_t { using _traits = make_traits, ::sqlpp::tag::multi_expression>; @@ -64,30 +62,26 @@ namespace sqlpp Select _select; }; - } - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = some_t; - - static Context& _(const T& t, Context& context) - { - context << "SOME("; - serialize(t._select, context); - context << ")"; - return context; - } - }; - } + context << "SOME("; + serialize(t._select, context); + context << ")"; + return context; + } + }; template - auto some(T t) -> typename vendor::some_t> + auto some(T t) -> some_t> { - static_assert(is_select_t>::value, "some() requires a single column select expression as argument"); - static_assert(is_expression_t>::value, "some() requires a single column select expression as argument"); + static_assert(is_select_t>::value, "some() requires a single column select expression as argument"); + static_assert(is_expression_t>::value, "some() requires a single column select expression as argument"); return { t }; } diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index 7ef6c238..ae8d92bd 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -46,30 +46,27 @@ namespace sqlpp Expression _expression; }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = sort_order_t; + + static Context& _(const T& t, Context& context) { - using T = sort_order_t; - - 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; + } + }; - } } #endif diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index 2e7f4026..790206a1 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -31,9 +31,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -61,7 +61,7 @@ namespace sqlpp struct _policies_update_t { static_assert(detail::is_element_of>::value, "policies update for non-policy class detected"); - using type = statement_t...>; + using type = statement_t...>; }; template @@ -80,9 +80,9 @@ 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; + using _result_type_provider = detail::get_last_if; struct _result_methods_t: public _result_type_provider::template _result_methods_t {}; @@ -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,84 +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; } - - }; - namespace vendor - { - 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; @@ -238,7 +236,6 @@ namespace sqlpp }; }; - } } #endif diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 7487a5b9..89045be9 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -31,77 +31,71 @@ namespace sqlpp { - namespace vendor - { - template + template struct sum_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(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; - }; - } - - namespace vendor + public alias_operators> { - template - struct serializer_t> - { - using T = vendor::sum_t; + using _traits = make_traits, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>; + using _recursive_traits = make_recursive_traits; - static Context& _(const T& t, Context& context) + 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 { - context << "SUM("; - if (std::is_same::value) - { - serialize(Flag(), context); - context << ' '; - } - serialize(t._expr, context); - context << ")"; - return context; + 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; + }; + + template + struct serializer_t> + { + using T = sum_t; + + static Context& _(const T& t, Context& context) + { + context << "SUM("; + if (std::is_same::value) + { + serialize(Flag(), context); + context << ' '; } - }; - } + serialize(t._expr, context); + context << ")"; + return context; + } + }; template - auto sum(T t) -> typename vendor::sum_t> + auto sum(T t) -> sum_t> { - static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); + static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); return { t }; } template - auto sum(const sqlpp::distinct_t&, T t) -> typename vendor::sum_t> + auto sum(const sqlpp::distinct_t&, T t) -> sum_t> { - static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); + static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); return { t }; } diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 5f74da41..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,22 +101,19 @@ namespace sqlpp } }; - namespace vendor - { - template - struct serializer_t::value and not is_pseudo_table_t::value, void>::type> + template + struct serializer_t::value and not is_pseudo_table_t::value, void>::type> + { + using T = X; + + static Context& _(const T& t, Context& context) { - using T = X; - - static Context& _(const T& t, Context& context) - { - context << T::_name_t::_get_name(); - return context; - } - }; + context << T::_name_t::_get_name(); + return context; + } + }; - } } #endif diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index e357973c..ff1a3e19 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -61,23 +61,20 @@ namespace sqlpp Table _table; }; - namespace vendor - { - template - struct serializer_t> + template + struct serializer_t> + { + using T = table_alias_t; + + static Context& _(const T& t, Context& context) { - using T = table_alias_t; + 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; - } - }; - - } } #endif diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index dbb32118..0e0c6a53 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include namespace sqlpp { @@ -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,111 +96,111 @@ 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 { template - vendor::concat_t> operator+(T t) const + concat_t> operator+(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid rhs operand"); return { *static_cast(this), {t} }; } template - vendor::like_t> like(T t) const + like_t> like(T t) const { - using rhs = vendor::wrap_operand_t; + using rhs = wrap_operand_t; static_assert(_is_valid_operand::value, "invalid argument for like()"); return { *static_cast(this), {t} }; @@ -209,23 +209,23 @@ namespace sqlpp template struct column_operators - { - template - auto operator +=(T t) const -> vendor::assignment_t>> - { - using rhs = vendor::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 255f9d3e..82e23b3d 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -31,8 +31,8 @@ #include #include -#include -#include +#include +#include namespace sqlpp { @@ -61,19 +61,16 @@ namespace sqlpp Operand _value; }; - namespace vendor - { - 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(vendor::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 @@ -121,34 +118,31 @@ namespace sqlpp typename tvin_t::_operand_t _value; }; - namespace vendor - { - 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> + auto tvin(Operand operand) -> tvin_t::type> { - using _operand_t = typename vendor::wrap_operand::type; - static_assert(std::is_same<_operand_t, vendor::text_operand>::value - or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)"); + 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)"); 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 9fd1414d..88e7fdc1 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -32,16 +32,16 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace sqlpp { struct update_name_t {}; - struct update_t: public vendor::statement_name_t + struct update_t: public statement_name_t { using _traits = make_traits; struct _name_t {}; @@ -70,37 +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)}; } */ }; }; - namespace vendor - { - 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 new file mode 100644 index 00000000..e09be547 --- /dev/null +++ b/include/sqlpp11/update_list.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_UPDATE_LIST_H +#define SQLPP_UPDATE_LIST_H + +#include +#include +#include +#include + +namespace sqlpp +{ + // 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; + + std::tuple _assignments; + 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; + + 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(::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 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<>; + + // 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 new file mode 100644 index 00000000..0d345906 --- /dev/null +++ b/include/sqlpp11/using.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_USING_H +#define SQLPP_USING_H + +#include +#include +#include +#include +#include + +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 _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_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/vendor/value_type.h b/include/sqlpp11/value_type.h similarity index 91% rename from include/sqlpp11/vendor/value_type.h rename to include/sqlpp11/value_type.h index 2f9b5188..2fa3bee1 100644 --- a/include/sqlpp11/vendor/value_type.h +++ b/include/sqlpp11/value_type.h @@ -28,14 +28,11 @@ #define SQLPP_VALUE_TYPE_H #include -#include +#include namespace sqlpp { - namespace vendor - { - template - using value_type_t = value_type_of>; - } + template + using value_type_t = value_type_of>; } #endif diff --git a/include/sqlpp11/vendor/assignment.h b/include/sqlpp11/vendor/assignment.h deleted file mode 100644 index e74a6da5..00000000 --- a/include/sqlpp11/vendor/assignment.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_ASSIGNMENT_H -#define SQLPP_ASSIGNMENT_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - template - struct is_trivial_t - { - static constexpr bool _(const T&) - { - return false; - } - }; - - template - struct is_trivial_t::value, void>::type> - { - static bool _(const T& t) - { - return t._is_trivial(); - } - }; - - template - bool is_trivial(const T& t) - { - return is_trivial_t::_(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) - { - 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) - { - 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/vendor/concat.h b/include/sqlpp11/vendor/concat.h deleted file mode 100644 index 7a93c6ad..00000000 --- a/include/sqlpp11/vendor/concat.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_CONCAT_H -#define SQLPP_CONCAT_H - -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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 - { - 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; - }; - - 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/vendor/expression.h b/include/sqlpp11/vendor/expression.h deleted file mode 100644 index e91b2d68..00000000 --- a/include/sqlpp11/vendor/expression.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_EXPRESSION_H -#define SQLPP_EXPRESSION_H - -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - 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; - - 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; - maybe_tvin_t _rhs; - }; - - template - struct serializer_t> - { - using T = equal_to_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - serialize(t._lhs, context); - if (t._rhs._is_trivial()) - { - 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> - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - 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; - maybe_tvin_t _rhs; - }; - - template - struct serializer_t> - { - using T = not_equal_to_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - serialize(t._lhs, context); - if (t._rhs._is_trivial()) - { - 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> - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - 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 = 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> - { - using _traits = make_traits, sqlpp::tag::expression>; - using _recursive_traits = make_recursive_traits; - - 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; - }; - - template - struct serializer_t> - { - using T = binary_expression_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - serialize(t._lhs, context); - context << O::_name; - serialize(t._rhs, context); - context << ")"; - return context; - } - }; - - 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; - - 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/vendor/expression_fwd.h b/include/sqlpp11/vendor/expression_fwd.h deleted file mode 100644 index 796596e5..00000000 --- a/include/sqlpp11/vendor/expression_fwd.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_EXPRESSION_FWD_H -#define SQLPP_EXPRESSION_FWD_H - -namespace sqlpp -{ - namespace detail - { - struct boolean; - struct integral; - struct floating_point; - } - - namespace vendor - { - namespace op - { - struct less - { - 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 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 - { - 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_and - { - using _traits = make_traits<::sqlpp::detail::boolean>; - static constexpr const char* _name = " AND "; - }; - - struct logical_not - { - using _traits = make_traits<::sqlpp::detail::boolean>; - }; - - template - struct plus - { - using _traits = make_traits; - static constexpr const char* _name = "+"; - }; - - template - struct minus - { - using _traits = make_traits; - static constexpr const char* _name = "-"; - }; - - 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 modulus - { - using _traits = make_traits<::sqlpp::detail::integral>; - static constexpr const char* _name = "%"; - }; - - template - struct unary_minus - { - using _traits = make_traits; - static constexpr const char* _name = "-"; - }; - - template - struct unary_plus - { - using _traits = make_traits; - static constexpr const char* _name = "+"; - }; - } - - template - struct binary_expression_t; - - template - struct unary_expression_t; - - template - using less_than_t = binary_expression_t; - - template - using less_equal_t = binary_expression_t; - - template - using 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_equal_t = binary_expression_t; - - template - using logical_and_t = binary_expression_t; - - template - using logical_or_t = binary_expression_t; - - template - using plus_t = binary_expression_t, Rhs>; - - template - using minus_t = binary_expression_t, Rhs>; - - template - using multiplies_t = binary_expression_t, Rhs>; - - template - using divides_t = binary_expression_t; - - template - using modulus_t = binary_expression_t; - - template - using logical_not_t = unary_expression_t; - - template - using unary_plus_t = unary_expression_t, Rhs>; - - template - using unary_minus_t = unary_expression_t, Rhs>; - - } -} - -#endif diff --git a/include/sqlpp11/vendor/extra_tables.h b/include/sqlpp11/vendor/extra_tables.h deleted file mode 100644 index 3feaac4c..00000000 --- a/include/sqlpp11/vendor/extra_tables.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_EXTRA_TABLES_H -#define SQLPP_EXTRA_TABLES_H - -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - 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 - { - 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_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/vendor/from.h b/include/sqlpp11/vendor/from.h deleted file mode 100644 index 308dfed3..00000000 --- a/include/sqlpp11/vendor/from.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_FROM_H -#define SQLPP_FROM_H - -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // FROM DATA - template - struct from_data_t - { - from_data_t(Tables... tables): - _tables(tables...) - {} - - from_data_t(const from_data_t&) = default; - from_data_t(from_data_t&&) = default; - from_data_t& operator=(const from_data_t&) = default; - from_data_t& operator=(from_data_t&&) = default; - ~from_data_t() = default; - - std::tuple _tables; - vendor::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 - { - 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_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/vendor/group_by.h b/include/sqlpp11/vendor/group_by.h deleted file mode 100644 index a3732a5b..00000000 --- a/include/sqlpp11/vendor/group_by.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_GROUP_BY_H -#define SQLPP_GROUP_BY_H - -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - vendor::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 - { - 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_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/vendor/having.h b/include/sqlpp11/vendor/having.h deleted file mode 100644 index 0abdcb72..00000000 --- a/include/sqlpp11/vendor/having.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_HAVING_H -#define SQLPP_HAVING_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - vendor::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 - { - 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_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/vendor/insert_value.h b/include/sqlpp11/vendor/insert_value.h deleted file mode 100644 index b0f4dfea..00000000 --- a/include/sqlpp11/vendor/insert_value.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_INSERT_VALUE_H -#define SQLPP_INSERT_VALUE_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - 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 - { - 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; - } - }; - - } -} - -#endif diff --git a/include/sqlpp11/vendor/insert_value_list.h b/include/sqlpp11/vendor/insert_value_list.h deleted file mode 100644 index f4cb6794..00000000 --- a/include/sqlpp11/vendor/insert_value_list.h +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_INSERT_VALUE_LIST_H -#define SQLPP_INSERT_VALUE_LIST_H - -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - struct insert_default_values_data_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 - { - 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) - typename vendor::interpretable_list_t _dynamic_columns; - typename vendor::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}...) - {} - - 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 - { - 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(vendor::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; - }; - - // Member template for adding the named member to a statement - template - struct _member_t - { - using _data_t = no_data_t; - - _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), vendor::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 << ")"; - } - return context; - } - }; - - } -} - -#endif diff --git a/include/sqlpp11/vendor/interpretable.h b/include/sqlpp11/vendor/interpretable.h deleted file mode 100644 index a190f04e..00000000 --- a/include/sqlpp11/vendor/interpretable.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_INTERPRETABLE_H -#define SQLPP_INTERPRETABLE_H - -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - 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 - { - return _impl->serialize(context); - } - - // 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 - { - return _impl->db_serialize(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; - }; - - 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/vendor/into.h b/include/sqlpp11/vendor/into.h deleted file mode 100644 index 74551017..00000000 --- a/include/sqlpp11/vendor/into.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_VENDOR_INTO_H -#define SQLPP_VENDOR_INTO_H - -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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 - { - 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_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/vendor/limit.h b/include/sqlpp11/vendor/limit.h deleted file mode 100644 index 588b31ee..00000000 --- a/include/sqlpp11/vendor/limit.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_LIMIT_H -#define SQLPP_LIMIT_H - -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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 - { - 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_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; - } - }; - - 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/vendor/named_interpretable.h b/include/sqlpp11/vendor/named_interpretable.h deleted file mode 100644 index 08e4ed68..00000000 --- a/include/sqlpp11/vendor/named_interpretable.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_NAMED_SERIALIZABLE_H -#define SQLPP_NAMED_SERIALIZABLE_H - -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - 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 - { - return _impl->serialize(context); - } - - // 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 - { - 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 - { - Db::_interpret_interpretable(_t, context); - return context; - } - - std::string _get_name() const - { - return T::_name_t::_get_name(); - } - - T _t; - }; - - std::shared_ptr _impl; - }; - - template - struct serializer_t> - { - using T = named_interpretable_t; - - static Context& _(const T& t, Context& context) - { - t.serialize(context); - return context; - } - }; - } - -} - -#endif diff --git a/include/sqlpp11/vendor/offset.h b/include/sqlpp11/vendor/offset.h deleted file mode 100644 index 65113beb..00000000 --- a/include/sqlpp11/vendor/offset.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_OFFSET_H -#define SQLPP_OFFSET_H - -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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 - { - 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; - } - }; - } -} - -#endif diff --git a/include/sqlpp11/vendor/order_by.h b/include/sqlpp11/vendor/order_by.h deleted file mode 100644 index 37e84724..00000000 --- a/include/sqlpp11/vendor/order_by.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_ORDER_BY_H -#define SQLPP_ORDER_BY_H - -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - vendor::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 - { - 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_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/vendor/select_column_list.h b/include/sqlpp11/vendor/select_column_list.h deleted file mode 100644 index 56b512b5..00000000 --- a/include/sqlpp11/vendor/select_column_list.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_SELECT_COLUMN_LIST_H -#define SQLPP_SELECT_COLUMN_LIST_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace detail - { - template - struct select_traits - { - using _traits = make_traits; - struct _name_t {}; - }; - - template - struct select_traits - { - using _traits = make_traits, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>; - using _name_t = typename Column::_name_t; - }; - } - - namespace vendor - { - 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 - { - 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) - { - 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; } - - template - static auto _get_member(T t) -> decltype(t.selected_columns) - { - return t.selected_columns; - } - }; - - // 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); - } - - 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(); - - return {{}, get_dynamic_names(), db.prepare_select(*this)}; - } -#endif - }; - - }; - } - - namespace detail - { - template - using make_select_column_list_t = - copy_tuple_args_t::_(std::declval())...))>; - } - - namespace vendor - { - struct no_select_column_list_t - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; - - struct _name_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> - { - 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/vendor/select_flag_list.h b/include/sqlpp11/vendor/select_flag_list.h deleted file mode 100644 index c458ad6e..00000000 --- a/include/sqlpp11/vendor/select_flag_list.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_VENDOR_SELECT_FLAG_LIST_H -#define SQLPP_VENDOR_SELECT_FLAG_LIST_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - vendor::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 - { - 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_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; - } - }; - - } - -} - -#endif diff --git a/include/sqlpp11/vendor/single_table.h b/include/sqlpp11/vendor/single_table.h deleted file mode 100644 index 9826b35f..00000000 --- a/include/sqlpp11/vendor/single_table.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_VENDOR_SINGLE_TABLE_H -#define SQLPP_VENDOR_SINGLE_TABLE_H - -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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 - { - 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_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/vendor/update_list.h b/include/sqlpp11/vendor/update_list.h deleted file mode 100644 index 8cd99bea..00000000 --- a/include/sqlpp11/vendor/update_list.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_UPDATE_LIST_H -#define SQLPP_UPDATE_LIST_H - -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - - std::tuple _assignments; - typename vendor::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; - - 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(::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 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<>; - - // 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), vendor::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/vendor/using.h b/include/sqlpp11/vendor/using.h deleted file mode 100644 index 3731c3c0..00000000 --- a/include/sqlpp11/vendor/using.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_USING_H -#define SQLPP_USING_H - -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - vendor::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 _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_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/vendor/where.h b/include/sqlpp11/vendor/where.h deleted file mode 100644 index 0dcbd9c2..00000000 --- a/include/sqlpp11/vendor/where.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_WHERE_H -#define SQLPP_WHERE_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace vendor - { - // 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; - - std::tuple _expressions; - vendor::interpretable_list_t _dynamic_expressions; - }; - - // 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; - - 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; - - // 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()"); - - 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 = 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 - { - }; - }; - - 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 - { - 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_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/vendor/wrap_operand.h b/include/sqlpp11/vendor/wrap_operand.h deleted file mode 100644 index 2a832e07..00000000 --- a/include/sqlpp11/vendor/wrap_operand.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_DETAIL_WRAP_OPERAND_H -#define SQLPP_DETAIL_WRAP_OPERAND_H - -#include -#include -#include - -namespace sqlpp -{ - namespace detail - { - struct boolean; - struct integral; - struct floating_point; - struct text; - } - - namespace vendor - { - 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 Operand = boolean_operand; - - static Context& _(const Operand& t, Context& context) - { - context << t._t; - return context; - } - }; - - struct integral_operand - { - using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>; - using _recursive_traits = make_recursive_traits<>; - - 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; - }; - - 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; - - 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 Operand = floating_point_operand; - - static Context& _(const Operand& t, Context& context) - { - context << t._t; - return context; - } - }; - - struct text_operand - { - using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>; - using _recursive_traits = make_recursive_traits<>; - - 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; - }; - - template - struct serializer_t - { - using Operand = text_operand; - - static Context& _(const Operand& t, Context& context) - { - context << '\'' << context.escape(t._t) << '\''; - return context; - } - }; - - template - struct wrap_operand - { - using type = T; - }; - - template<> - struct wrap_operand - { - using type = boolean_operand; - }; - - template - struct wrap_operand::value>::type> - { - using type = integral_operand; - }; - - template - struct wrap_operand::value>::type> - { - using type = floating_point_operand; - }; - - 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; - - } -} - -#endif diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index d4715bf2..7d6d15e4 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -63,20 +63,17 @@ namespace sqlpp std::string _name; }; - namespace vendor - { - 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 new file mode 100644 index 00000000..8c9446e7 --- /dev/null +++ b/include/sqlpp11/where.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_WHERE_H +#define SQLPP_WHERE_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + // 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; + + std::tuple _expressions; + interpretable_list_t _dynamic_expressions; + }; + + // 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; + + 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; + + // 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()"); + + 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 = 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 + { + }; + }; + + 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 + { + 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_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 new file mode 100644 index 00000000..177f9294 --- /dev/null +++ b/include/sqlpp11/wrap_operand.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_DETAIL_WRAP_OPERAND_H +#define SQLPP_DETAIL_WRAP_OPERAND_H + +#include +#include +#include + +namespace sqlpp +{ + namespace detail + { + struct boolean; + struct integral; + struct floating_point; + struct text; + } + + 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 Operand = boolean_operand; + + static Context& _(const Operand& t, Context& context) + { + context << t._t; + return context; + } + }; + + struct integral_operand + { + using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>; + using _recursive_traits = make_recursive_traits<>; + + 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; + }; + + 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; + + 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 Operand = floating_point_operand; + + static Context& _(const Operand& t, Context& context) + { + context << t._t; + return context; + } + }; + + struct text_operand + { + using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>; + using _recursive_traits = make_recursive_traits<>; + + 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; + }; + + template + struct serializer_t + { + using Operand = text_operand; + + static Context& _(const Operand& t, Context& context) + { + context << '\'' << context.escape(t._t) << '\''; + return context; + } + }; + + template + struct wrap_operand + { + using type = T; + }; + + template<> + struct wrap_operand + { + using type = boolean_operand; + }; + + template + struct wrap_operand::value>::type> + { + using type = integral_operand; + }; + + template + struct wrap_operand::value>::type> + { + using type = floating_point_operand; + }; + + 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; + +} + +#endif diff --git a/include/sqlpp11/vendor/wrong.h b/include/sqlpp11/wrong.h similarity index 78% rename from include/sqlpp11/vendor/wrong.h rename to include/sqlpp11/wrong.h index 65a4d181..9249673e 100644 --- a/include/sqlpp11/vendor/wrong.h +++ b/include/sqlpp11/wrong.h @@ -24,28 +24,25 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_VENDOR_WRONG_H -#define SQLPP_VENDOR_WRONG_H +#ifndef SQLPP_WRONG_H +#define SQLPP_WRONG_H #include namespace sqlpp { - namespace vendor + namespace detail { - 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; - }; - } + // 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 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9de5e4e2..9ea24a1f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,9 +8,9 @@ endmacro () #build_and_run(InterpretTest) build_and_run(InsertTest) -#build_and_run(RemoveTest) -#build_and_run(UpdateTest) -#build_and_run(SelectTest) +build_and_run(RemoveTest) +build_and_run(UpdateTest) +build_and_run(SelectTest) #build_and_run(SelectTypeTest) #build_and_run(FunctionTest) #build_and_run(PreparedTest)