From 312e735d6dabc60d4033715e895fee0dbbec0ebb Mon Sep 17 00:00:00 2001 From: rbock Date: Sat, 18 Jan 2014 15:50:16 +0100 Subject: [PATCH] Moved a bunch of things into namespace vendor This namespace is for things the developer will not get in touch with (normally) but the vendor might need to use for specialization of the interpreter. This separation is not fully completed yet, some changes will have to follow... --- include/sqlpp11/alias.h | 70 +---- include/sqlpp11/alias_provider.h | 82 ++++++ include/sqlpp11/any.h | 8 +- include/sqlpp11/assignment_list.h | 88 ------- include/sqlpp11/avg.h | 8 +- .../sqlpp11/{detail => }/basic_operators.h | 45 ++-- include/sqlpp11/boolean.h | 13 +- include/sqlpp11/column.h | 15 +- include/sqlpp11/count.h | 12 +- include/sqlpp11/detail/wrap_operand.h | 166 ------------ include/sqlpp11/exists.h | 8 +- include/sqlpp11/expression.h | 243 ----------------- include/sqlpp11/floating_point.h | 11 +- include/sqlpp11/from.h | 88 ------- include/sqlpp11/functions.h | 12 +- include/sqlpp11/group_by.h | 90 ------- include/sqlpp11/insert.h | 45 ++-- include/sqlpp11/insert_list.h | 154 ----------- include/sqlpp11/integral.h | 16 +- .../sqlpp11/{interpreter.h => interpret.h} | 20 +- include/sqlpp11/join.h | 117 +++++---- include/sqlpp11/max.h | 8 +- include/sqlpp11/min.h | 8 +- include/sqlpp11/multi_column.h | 2 +- include/sqlpp11/no_value.h | 1 - include/sqlpp11/on.h | 23 +- include/sqlpp11/order_by.h | 88 ------- include/sqlpp11/parameter.h | 4 +- include/sqlpp11/parameter_list.h | 19 -- include/sqlpp11/remove.h | 39 ++- include/sqlpp11/result_row.h | 7 +- include/sqlpp11/select.h | 141 +++++----- include/sqlpp11/select_expression_list.h | 197 -------------- include/sqlpp11/select_fwd.h | 40 +-- include/sqlpp11/some.h | 8 +- include/sqlpp11/sort_order.h | 2 +- include/sqlpp11/sum.h | 8 +- include/sqlpp11/table.h | 6 +- include/sqlpp11/table_alias.h | 9 +- include/sqlpp11/text.h | 10 +- include/sqlpp11/tvin.h | 16 +- include/sqlpp11/type_traits.h | 7 +- include/sqlpp11/update.h | 45 ++-- include/sqlpp11/using.h | 87 ------ .../sqlpp11/{ => vendor}/char_result_row.h | 0 include/sqlpp11/{ => vendor}/concat.h | 37 ++- include/sqlpp11/vendor/expression.h | 248 ++++++++++++++++++ include/sqlpp11/{ => vendor}/expression_fwd.h | 23 +- include/sqlpp11/{ => vendor}/field.h | 56 ++-- include/sqlpp11/vendor/from.h | 91 +++++++ include/sqlpp11/vendor/group_by.h | 90 +++++++ include/sqlpp11/{ => vendor}/having.h | 78 +++--- include/sqlpp11/{ => vendor}/in.h | 39 ++- include/sqlpp11/{ => vendor}/in_fwd.h | 7 +- include/sqlpp11/vendor/insert_list.h | 155 +++++++++++ .../sqlpp11/{ => vendor}/interpret_tuple.h | 0 .../serializable.h => vendor/interpretable.h} | 42 +-- .../interpretable_list.h} | 87 +++--- include/sqlpp11/vendor/interpreter.h | 48 ++++ include/sqlpp11/{ => vendor}/is_null.h | 26 +- include/sqlpp11/{ => vendor}/is_null_fwd.h | 2 +- include/sqlpp11/{ => vendor}/like.h | 96 +++---- include/sqlpp11/{ => vendor}/limit.h | 81 +++--- .../named_interpretable.h} | 38 +-- include/sqlpp11/{ => vendor}/noop.h | 30 ++- include/sqlpp11/{ => vendor}/noop_fwd.h | 9 +- include/sqlpp11/{ => vendor}/offset.h | 83 +++--- include/sqlpp11/vendor/order_by.h | 88 +++++++ .../sqlpp11/vendor/select_expression_list.h | 204 ++++++++++++++ .../sqlpp11/{ => vendor}/select_flag_list.h | 73 +++--- .../{ => vendor}/select_pseudo_table.h | 2 +- include/sqlpp11/vendor/update_list.h | 90 +++++++ include/sqlpp11/vendor/using.h | 87 ++++++ include/sqlpp11/{ => vendor}/where.h | 75 +++--- include/sqlpp11/vendor/wrap_operand.h | 168 ++++++++++++ include/sqlpp11/verbatim_table.h | 2 +- tests/InterpretTest.cpp | 7 +- 77 files changed, 2153 insertions(+), 2095 deletions(-) create mode 100644 include/sqlpp11/alias_provider.h delete mode 100644 include/sqlpp11/assignment_list.h rename include/sqlpp11/{detail => }/basic_operators.h (79%) delete mode 100644 include/sqlpp11/detail/wrap_operand.h delete mode 100644 include/sqlpp11/expression.h delete mode 100644 include/sqlpp11/from.h delete mode 100644 include/sqlpp11/group_by.h delete mode 100644 include/sqlpp11/insert_list.h rename include/sqlpp11/{interpreter.h => interpret.h} (72%) delete mode 100644 include/sqlpp11/order_by.h delete mode 100644 include/sqlpp11/select_expression_list.h delete mode 100644 include/sqlpp11/using.h rename include/sqlpp11/{ => vendor}/char_result_row.h (100%) rename include/sqlpp11/{ => vendor}/concat.h (78%) create mode 100644 include/sqlpp11/vendor/expression.h rename include/sqlpp11/{ => vendor}/expression_fwd.h (81%) rename include/sqlpp11/{ => vendor}/field.h (66%) create mode 100644 include/sqlpp11/vendor/from.h create mode 100644 include/sqlpp11/vendor/group_by.h rename include/sqlpp11/{ => vendor}/having.h (54%) rename include/sqlpp11/{ => vendor}/in.h (78%) rename include/sqlpp11/{ => vendor}/in_fwd.h (94%) create mode 100644 include/sqlpp11/vendor/insert_list.h rename include/sqlpp11/{ => vendor}/interpret_tuple.h (100%) rename include/sqlpp11/{detail/serializable.h => vendor/interpretable.h} (80%) rename include/sqlpp11/{detail/serializable_list.h => vendor/interpretable_list.h} (57%) create mode 100644 include/sqlpp11/vendor/interpreter.h rename include/sqlpp11/{ => vendor}/is_null.h (85%) rename include/sqlpp11/{ => vendor}/is_null_fwd.h (98%) rename include/sqlpp11/{ => vendor}/like.h (57%) rename include/sqlpp11/{ => vendor}/limit.h (63%) rename include/sqlpp11/{detail/named_serializable.h => vendor/named_interpretable.h} (81%) rename include/sqlpp11/{ => vendor}/noop.h (82%) rename include/sqlpp11/{ => vendor}/noop_fwd.h (94%) rename include/sqlpp11/{ => vendor}/offset.h (62%) create mode 100644 include/sqlpp11/vendor/order_by.h create mode 100644 include/sqlpp11/vendor/select_expression_list.h rename include/sqlpp11/{ => vendor}/select_flag_list.h (64%) rename include/sqlpp11/{ => vendor}/select_pseudo_table.h (97%) create mode 100644 include/sqlpp11/vendor/update_list.h create mode 100644 include/sqlpp11/vendor/using.h rename include/sqlpp11/{ => vendor}/where.h (55%) create mode 100644 include/sqlpp11/vendor/wrap_operand.h diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 0205ac37..3d740310 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -30,71 +30,23 @@ #include namespace sqlpp { - namespace alias - { -#define SQLPP_ALIAS_PROVIDER_GENERATOR(name) \ - struct name##_t\ - {\ - struct _name_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; }\ - };\ - };\ - };\ - constexpr name##_t name = {}; - - SQLPP_ALIAS_PROVIDER_GENERATOR(a); - SQLPP_ALIAS_PROVIDER_GENERATOR(b); - SQLPP_ALIAS_PROVIDER_GENERATOR(c); - SQLPP_ALIAS_PROVIDER_GENERATOR(d); - SQLPP_ALIAS_PROVIDER_GENERATOR(e); - SQLPP_ALIAS_PROVIDER_GENERATOR(f); - SQLPP_ALIAS_PROVIDER_GENERATOR(g); - SQLPP_ALIAS_PROVIDER_GENERATOR(h); - SQLPP_ALIAS_PROVIDER_GENERATOR(i); - SQLPP_ALIAS_PROVIDER_GENERATOR(j); - SQLPP_ALIAS_PROVIDER_GENERATOR(k); - SQLPP_ALIAS_PROVIDER_GENERATOR(l); - SQLPP_ALIAS_PROVIDER_GENERATOR(m); - SQLPP_ALIAS_PROVIDER_GENERATOR(n); - SQLPP_ALIAS_PROVIDER_GENERATOR(o); - SQLPP_ALIAS_PROVIDER_GENERATOR(p); - SQLPP_ALIAS_PROVIDER_GENERATOR(q); - SQLPP_ALIAS_PROVIDER_GENERATOR(s); - SQLPP_ALIAS_PROVIDER_GENERATOR(t); - SQLPP_ALIAS_PROVIDER_GENERATOR(u); - SQLPP_ALIAS_PROVIDER_GENERATOR(v); - SQLPP_ALIAS_PROVIDER_GENERATOR(w); - SQLPP_ALIAS_PROVIDER_GENERATOR(x); - SQLPP_ALIAS_PROVIDER_GENERATOR(y); - SQLPP_ALIAS_PROVIDER_GENERATOR(z); - SQLPP_ALIAS_PROVIDER_GENERATOR(left); - SQLPP_ALIAS_PROVIDER_GENERATOR(right); - }; - template struct expression_alias_t - { - struct _value_type: Expression::_value_type { - using _is_expression = std::false_type; - using _is_named_expression = std::true_type; - using _is_alias = std::true_type; + struct _value_type: Expression::_value_type + { + using _is_expression = std::false_type; + using _is_named_expression = std::true_type; + using _is_alias = std::true_type; + }; + + using _name_t = typename AliasProvider::_name_t; + + Expression _expression; }; - using _name_t = typename AliasProvider::_name_t; - - Expression _expression; - }; - template - struct interpreter_t> + struct vendor::interpreter_t> { using T = expression_alias_t; diff --git a/include/sqlpp11/alias_provider.h b/include/sqlpp11/alias_provider.h new file mode 100644 index 00000000..d63ce097 --- /dev/null +++ b/include/sqlpp11/alias_provider.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_ALIAS_PROVIDER_H +#define SQLPP_ALIAS_PROVIDER_H + +#define SQLPP_ALIAS_PROVIDER(name) \ + struct name##_t\ + {\ + struct _name_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; }\ + };\ + };\ + };\ + constexpr name##_t name = {}; + +namespace sqlpp +{ + namespace alias + { + SQLPP_ALIAS_PROVIDER(a); + SQLPP_ALIAS_PROVIDER(b); + SQLPP_ALIAS_PROVIDER(c); + SQLPP_ALIAS_PROVIDER(d); + SQLPP_ALIAS_PROVIDER(e); + SQLPP_ALIAS_PROVIDER(f); + SQLPP_ALIAS_PROVIDER(g); + SQLPP_ALIAS_PROVIDER(h); + SQLPP_ALIAS_PROVIDER(i); + SQLPP_ALIAS_PROVIDER(j); + SQLPP_ALIAS_PROVIDER(k); + SQLPP_ALIAS_PROVIDER(l); + SQLPP_ALIAS_PROVIDER(m); + SQLPP_ALIAS_PROVIDER(n); + SQLPP_ALIAS_PROVIDER(o); + SQLPP_ALIAS_PROVIDER(p); + SQLPP_ALIAS_PROVIDER(q); + SQLPP_ALIAS_PROVIDER(s); + SQLPP_ALIAS_PROVIDER(t); + SQLPP_ALIAS_PROVIDER(u); + SQLPP_ALIAS_PROVIDER(v); + SQLPP_ALIAS_PROVIDER(w); + SQLPP_ALIAS_PROVIDER(x); + SQLPP_ALIAS_PROVIDER(y); + SQLPP_ALIAS_PROVIDER(z); + SQLPP_ALIAS_PROVIDER(left); + SQLPP_ALIAS_PROVIDER(right); + } +} + +#endif + diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index 35883da3..8a2310dc 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct any_t: public boolean::template operators> @@ -76,9 +76,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::any_t; static Context& _(const T& t, Context& context) { @@ -90,7 +90,7 @@ namespace sqlpp }; template - auto any(T&& t) -> typename detail::any_t::type> + auto any(T&& t) -> typename vendor::any_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/assignment_list.h b/include/sqlpp11/assignment_list.h deleted file mode 100644 index 4b20f9b7..00000000 --- a/include/sqlpp11/assignment_list.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_ASSIGNMENT_LIST_H -#define SQLPP_ASSIGNMENT_LIST_H - -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct assignment_list_t - { - using _is_assignment_list = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - // check for at least one order expression - static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()"); - - // check for duplicate assignments - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - - // check for invalid assignments - using _assignment_set = typename detail::make_set_if::type; - static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); - - // check for prohibited assignments - using _prohibited_assignment_set = typename detail::make_set_if::type; - static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); - - template - void add(Assignment&& assignment) - { - static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); - static_assert(not must_not_update_t::type::column_type>::value, "set() argument must not be updated"); - _dynamic_assignments.emplace_back(std::forward(assignment)); - } - - _parameter_tuple_t _assignments; - typename detail::serializable_list _dynamic_assignments; - }; - - template - struct interpreter_t> - { - using T = assignment_list_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_serializable_list(t._dynamic_assignments, ',', context); - return context; - } - }; - -} - -#endif diff --git a/include/sqlpp11/avg.h b/include/sqlpp11/avg.h index fcbddabe..908b361a 100644 --- a/include/sqlpp11/avg.h +++ b/include/sqlpp11/avg.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct avg_t: public floating_point::template operators> @@ -75,9 +75,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::avg_t; + using T = vendor::avg_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp }; template - auto avg(T&& t) -> typename detail::avg_t::type> + auto avg(T&& t) -> typename vendor::avg_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/detail/basic_operators.h b/include/sqlpp11/basic_operators.h similarity index 79% rename from include/sqlpp11/detail/basic_operators.h rename to include/sqlpp11/basic_operators.h index 8587c046..a7340a9f 100644 --- a/include/sqlpp11/detail/basic_operators.h +++ b/include/sqlpp11/basic_operators.h @@ -27,11 +27,11 @@ #ifndef SQLPP_DETAIL_BASIC_OPERATORS_H #define SQLPP_DETAIL_BASIC_OPERATORS_H -#include #include #include -#include -#include +#include +#include +#include namespace sqlpp { @@ -39,84 +39,88 @@ namespace sqlpp namespace detail { struct boolean; + } + namespace vendor + { // operators struct lt_ { - using _value_type = boolean; + using _value_type = detail::boolean; static constexpr const char* _name = "<"; }; struct le_ { - using _value_type = boolean; + using _value_type = detail::boolean; static constexpr const char* _name = "<="; }; struct ge_ { - using _value_type = boolean; + using _value_type = detail::boolean; static constexpr const char* _name = ">="; }; struct gt_ { - using _value_type = boolean; + using _value_type = detail::boolean; static constexpr const char* _name = ">"; }; + } - // basic operators - template class Constraint> - struct basic_operators + // basic operators + template class Constraint> + struct basic_operators { template - equal_t::type> operator==(T&& t) const + vendor::equal_t::type> operator==(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - not_equal_t::type> operator!=(T&& t) const + vendor::not_equal_t::type> operator!=(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - binary_expression_t::type> operator<(T&& t) const + vendor::binary_expression_t::type> operator<(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - binary_expression_t::type> operator<=(T&& t) const + vendor::binary_expression_t::type> operator<=(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - binary_expression_t::type> operator>=(T&& t) const + vendor::binary_expression_t::type> operator>=(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - binary_expression_t::type> operator>(T&& t) const + vendor::binary_expression_t::type> operator>(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } - is_null_t is_null() const + vendor::is_null_t is_null() const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used with is_null()"); return { *static_cast(this) }; } - is_null_t is_not_null() const + vendor::is_null_t is_not_null() const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used with is_not_null()"); return { *static_cast(this) }; @@ -136,14 +140,14 @@ namespace sqlpp // Hint: use value_list wrapper for containers... template - in_t::type...> in(T&&... t) const + vendor::in_t::type...> in(T&&... t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used with in()"); return { *static_cast(this), {std::forward(t)}... }; } template - in_t::type...> not_in(T&&... t) const + vendor::in_t::type...> not_in(T&&... t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot with be used with not_in()"); return { *static_cast(this), {std::forward(t)}... }; @@ -156,7 +160,6 @@ namespace sqlpp return { *static_cast(this) }; } }; - } } #endif diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 828ec5f4..01dc1565 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -28,7 +28,8 @@ #define SQLPP_BOOLEAN_H #include -#include +#include +#include #include #include @@ -40,13 +41,13 @@ namespace sqlpp struct or_ { using _value_type = boolean; - static constexpr const char* _name = "OR"; + static constexpr const char* _name = " OR "; }; struct and_ { using _value_type = boolean; - static constexpr const char* _name = "AND"; + static constexpr const char* _name = " AND "; }; // boolean value type @@ -182,20 +183,20 @@ namespace sqlpp struct operators: public basic_operators { template - binary_expression_t::type> operator and(T&& t) const + vendor::binary_expression_t::type> operator and(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t::type> operator or(T&& t) const + vendor::binary_expression_t::type> operator or(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } - not_t operator not() const + vendor::not_t operator not() const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be as operand for operator not"); return { *static_cast(this) }; diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 16896ecc..397e2fe5 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -27,14 +27,13 @@ #ifndef SQLPP_COLUMN_H #define SQLPP_COLUMN_H -#include -#include -#include #include -#include -#include +#include #include -#include +#include +#include +#include +#include namespace sqlpp { @@ -73,14 +72,14 @@ namespace sqlpp template auto operator =(T&& t) const -> typename std::enable_if::type>::value, - assignment_t::type>>::type + vendor::assignment_t::type>>::type { return { *this, {std::forward(t)} }; } }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = column_t; diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index fe9c59fc..aa25d74d 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -32,14 +32,14 @@ namespace sqlpp { - namespace detail + namespace vendor { template - struct count_t: public integral::template operators> + struct count_t: public sqlpp::detail::integral::template operators> { static_assert(is_value_t::value, "count() requires a sql value as argument"); - struct _value_type: public integral + struct _value_type: public sqlpp::detail::integral { using _is_named_expression = std::true_type; }; @@ -75,9 +75,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::count_t; + using T = vendor::count_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp }; template - auto count(T&& t) -> typename detail::count_t::type> + auto count(T&& t) -> typename vendor::count_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/detail/wrap_operand.h b/include/sqlpp11/detail/wrap_operand.h deleted file mode 100644 index 3ec698f3..00000000 --- a/include/sqlpp11/detail/wrap_operand.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_DETAIL_WRAP_OPERAND_H -#define SQLPP_DETAIL_WRAP_OPERAND_H - -#include - -// FIXME: must leave detail, since it is interpreted (and might require specializations) - -namespace sqlpp -{ - namespace detail - { - struct boolean; - struct integral; - struct floating_point; - struct text; - } - - struct boolean_operand - { - static constexpr bool _is_expression = true; - using _value_type = detail::boolean; - - bool _is_trivial() const { return _t == false; } - - bool _t; - }; - - template - struct interpreter_t - { - using Operand = boolean_operand; - - static Context& _(const Operand& t, Context& context) - { - context << t._t; - return context; - } - }; - - template - struct integral_operand - { - static constexpr bool _is_expression = true; - using _value_type = detail::integral; - - bool _is_trivial() const { return _t == 0; } - - T _t; - }; - - template - struct interpreter_t> - { - using Operand = integral_operand; - - static Context& _(const Operand& t, Context& context) - { - context << t._t; - return context; - } - }; - - - template - struct floating_point_operand - { - static constexpr bool _is_expression = true; - using _value_type = detail::floating_point; - - bool _is_trivial() const { return _t == 0; } - - T _t; - }; - - template - struct interpreter_t> - { - using Operand = floating_point_operand; - - static Context& _(const Operand& t, Context& context) - { - context << t._t; - return context; - } - }; - - struct text_operand - { - static constexpr bool _is_expression = true; - using _value_type = detail::text; - - bool _is_trivial() const { return _t.empty(); } - - std::string _t; - }; - - template - struct interpreter_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; - }; -} - -#endif diff --git a/include/sqlpp11/exists.h b/include/sqlpp11/exists.h index 52de3480..80906208 100644 --- a/include/sqlpp11/exists.h +++ b/include/sqlpp11/exists.h @@ -31,7 +31,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct exists_t: public boolean::template operators> @@ -74,9 +74,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::exists_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp template - auto exists(T&& t) -> typename detail::exists_t::type> + auto exists(T&& t) -> typename vendor::exists_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h deleted file mode 100644 index 786ad0d3..00000000 --- a/include/sqlpp11/expression.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_EXPRESSION_H -#define SQLPP_EXPRESSION_H - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct assignment_t - { - using _is_assignment = std::true_type; - using column_type = Lhs; - using value_type = tvin_wrap_t; - // FIXME: Need parameter_tuple back - - assignment_t(Lhs lhs, Rhs 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; - - Lhs _lhs; - tvin_wrap_t _rhs; - }; - - template - struct interpreter_t> - { - using T = assignment_t; - - static Context& _(const T& t, Context& context) - { - interpret(t._lhs, context); - if (t._rhs._is_trivial()) - { - context << "=NULL"; - } - else - { - context << "="; - interpret(t._rhs, context); - } - return context; - } - }; - - - template - struct equal_t: public detail::boolean::template operators> - { - using _value_type = detail::boolean; - - equal_t(Lhs lhs, Rhs rhs): - _lhs(lhs), - _rhs(rhs) - {} - - equal_t(const equal_t&) = default; - equal_t(equal_t&&) = default; - equal_t& operator=(const equal_t&) = default; - equal_t& operator=(equal_t&&) = default; - ~equal_t() = default; - - Lhs _lhs; - tvin_wrap_t _rhs; - }; - - template - struct interpreter_t> - { - using T = equal_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - interpret(t._lhs, context); - if (t._rhs._is_trivial()) - { - context << " IS NULL"; - } - else - { - context << "="; - interpret(t._rhs, context); - } - context << ")"; - return context; - } - }; - - template - struct not_equal_t: public detail::boolean::template operators> - { - using _value_type = detail::boolean; - - not_equal_t(Lhs lhs, Rhs rhs): - _lhs(lhs), - _rhs(rhs) - {} - - not_equal_t(const not_equal_t&) = default; - not_equal_t(not_equal_t&&) = default; - not_equal_t& operator=(const not_equal_t&) = default; - not_equal_t& operator=(not_equal_t&&) = default; - ~not_equal_t() = default; - - Lhs _lhs; - tvin_wrap_t _rhs; - }; - - template - struct interpreter_t> - { - using T = not_equal_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - interpret(t._lhs, context); - if (t._rhs._is_trivial()) - { - context << " IS NOT NULL"; - } - else - { - context << "!="; - interpret(t._rhs, context); - } - context << ")"; - return context; - } - }; - - template - struct not_t: public detail::boolean::template operators> - { - using _value_type = detail::boolean; - - not_t(Lhs l): - _lhs(l) - {} - - not_t(const not_t&) = default; - not_t(not_t&&) = default; - not_t& operator=(const not_t&) = default; - not_t& operator=(not_t&&) = default; - ~not_t() = default; - - Lhs _lhs; - }; - - template - struct interpreter_t> - { - using T = not_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - context << "NOT "; - interpret(t._lhs, context); - context << ")"; - return context; - } - }; - - template - struct binary_expression_t: public O::_value_type::template operators> - { - using _value_type = typename O::_value_type; - - 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 interpreter_t> - { - using T = binary_expression_t; - - static Context& _(const T& t, Context& context) - { - context << "("; - interpret(t._lhs, context); - context << O::_name; - interpret(t._rhs, context); - context << ")"; - return context; - } - }; - -} - -#endif diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index f9aff2bc..d6a82867 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -28,9 +28,8 @@ #define SQLPP_FLOATING_POINT_H #include -#include +#include #include -#include // FIXME: Need to update floating_point #include namespace sqlpp @@ -193,28 +192,28 @@ namespace sqlpp struct operators: public basic_operators { template - binary_expression_t::type> operator +(T&& t) const + vendor::binary_expression_t::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t::type> operator -(T&& t) const + vendor::binary_expression_t::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t::type> operator *(T&& t) const + vendor::binary_expression_t::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t::type> operator /(T&& t) const + vendor::binary_expression_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; diff --git a/include/sqlpp11/from.h b/include/sqlpp11/from.h deleted file mode 100644 index 91d73c04..00000000 --- a/include/sqlpp11/from.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_FROM_H -#define SQLPP_FROM_H - -#include -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct from_t - { - using _is_from = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - // ensure one argument at least - static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()"); - - // check for duplicate arguments - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in from()"); - - // check for invalid arguments - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()"); - - // FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance - - - template - void add(Table&& table) - { - static_assert(is_table_t::type>::value, "from arguments require to be tables or joins"); - _dynamic_tables.emplace_back(std::forward(table)); - } - - std::tuple _tables; - detail::serializable_list _dynamic_tables; - }; - - template - struct interpreter_t> - { - using T = from_t; - - static Context& _(const T& t, Context& context) - { - if (sizeof...(TableOrJoin) == 0 and t._dynamic_tables.empty()) - return context; - context << " FROM "; - interpret_tuple(t._tables, ',', context); - if (sizeof...(TableOrJoin) and not t._dynamic_tables.empty()) - context << ','; - interpret_serializable_list(t._dynamic_tables, ',', context); - return context; - } - }; - -} - -#endif diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 7059c84e..11ced294 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -40,7 +40,7 @@ #include #include #include -#include +#include // Csaba Csoma suggests: unsafe_sql instead of verbatim namespace sqlpp { @@ -51,7 +51,7 @@ namespace sqlpp return { std::forward(t) }; } - template + template // Csaba Csoma suggests: unsafe_sql instead of verbatim struct verbatim_t: public ValueType::template operators> { using _value_type = ValueType; @@ -68,7 +68,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = verbatim_t; @@ -104,7 +104,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = value_list_t; diff --git a/include/sqlpp11/group_by.h b/include/sqlpp11/group_by.h deleted file mode 100644 index 24d8ad9d..00000000 --- a/include/sqlpp11/group_by.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_GROUP_BY_H -#define SQLPP_GROUP_BY_H - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct group_by_t - { - using _is_group_by = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - // ensure one argument at least - static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()"); - - // check for duplicate expressions - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in group_by()"); - - // check for invalid expressions - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()"); - - template - void add(E&& expr) - { - static_assert(is_table_t::type>::value, "from arguments require to be tables or joins"); - _dynamic_expressions.emplace_back(std::forward(expr)); - } - - _parameter_tuple_t _expressions; - detail::serializable_list _dynamic_expressions; - - }; - - template - struct interpreter_t> - { - using T = group_by_t; - - static Context& _(const T& t, Context& context) - { - if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) - return context; - context << " GROUP BY "; - interpret_tuple(t._expressions, ',', context); - if (sizeof...(Expr) and not t._dynamic_expressions.empty()) - context << ','; - interpret_serializable_list(t._dynamic_expressions, ',', context); - return context; - } - }; - -} - -#endif diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index b3ac108b..12898ebd 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -27,37 +27,28 @@ #ifndef SQLPP_INSERT_H #define SQLPP_INSERT_H -#include -#include -#include -#include #include -#include #include +#include +#include +#include namespace sqlpp { template< typename Database = void, - typename Table = noop, - typename InsertList = noop - > - struct insert_t; - - template< - typename Database, - typename Table, - typename InsertList + typename Table = vendor::noop, + typename InsertList = vendor::noop > struct insert_t { - static_assert(is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); - static_assert(is_noop::value or is_insert_list_t::value, "invalid 'InsertList' argument"); + static_assert(vendor::is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); + static_assert(vendor::is_noop::value or is_insert_list_t::value, "invalid 'InsertList' argument"); template using set_insert_list_t = insert_t; - using use_default_values_t = insert_t; + using use_default_values_t = insert_t; using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; @@ -65,7 +56,7 @@ namespace sqlpp auto default_values() -> use_default_values_t { - static_assert(std::is_same::value, "cannot call default_values() after set() or default_values()"); + static_assert(std::is_same::value, "cannot call default_values() after set() or default_values()"); // FIXME: Need to check if all required columns are set return { _table, @@ -75,24 +66,24 @@ namespace sqlpp template auto set(Assignment&&... assignment) - -> set_insert_list_t::type...>> + -> set_insert_list_t::type...>> { - static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); + static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); // FIXME: Need to check if all required columns are set return { _table, - insert_list_t::type...>{std::forward(assignment)...}, + vendor::insert_list_t::type...>{std::forward(assignment)...}, }; } template auto dynamic_set(Assignment&&... assignment) - -> set_insert_list_t::type...>> + -> set_insert_list_t::type...>> { - static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); + static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); return { _table, - insert_list_t::type...>{std::forward(assignment)...}, + vendor::insert_list_t::type...>{std::forward(assignment)...}, }; } @@ -120,7 +111,7 @@ namespace sqlpp std::size_t run(Db& db) const { // FIXME: check if set or default_values() has ben called - constexpr bool calledSet = not is_noop::value; + constexpr bool calledSet = not vendor::is_noop::value; constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; static_assert(calledSet or not requireSet, "calling set() required for given table"); static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead"); @@ -131,7 +122,7 @@ namespace sqlpp auto prepare(Db& db) const -> prepared_insert_t::type, insert_t> { - constexpr bool calledSet = not is_noop::value; + constexpr bool calledSet = not vendor::is_noop::value; constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; static_assert(calledSet or not requireSet, "calling set() required for given table"); @@ -143,7 +134,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = insert_t; diff --git a/include/sqlpp11/insert_list.h b/include/sqlpp11/insert_list.h deleted file mode 100644 index 082a7d98..00000000 --- a/include/sqlpp11/insert_list.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_INSERT_LIST_H -#define SQLPP_INSERT_LIST_H - -#include -#include -#include -#include - -namespace sqlpp -{ - struct insert_default_values_t - { - using _is_insert_list = std::true_type; - using _is_dynamic = std::false_type; - }; - - template - struct interpreter_t - { - using T = insert_default_values_t; - - static Context& _(const T& t, Context& context) - { - context << " DEFAULT VALUES"; - return context; - } - }; - - template - struct insert_column_t - { - Column _column; - }; - - template - struct interpreter_t> - { - using T = insert_column_t; - - static Context& _(const T& t, Context& context) - { - context << t._column._get_name(); - return context; - } - }; - - - template - struct insert_list_t - { - using _is_insert_list = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - // check for at least one order expression - static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()"); - - // check for duplicate assignments - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - - // check for invalid assignments - using _assignment_set = typename detail::make_set_if::type; - static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); - - // check for prohibited assignments - using _prohibited_assignment_set = typename detail::make_set_if::type; - static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); - - insert_list_t(Assignments... assignment): - _columns({assignment._lhs}...), - _values(assignment._rhs...) - {} - - insert_list_t(const insert_list_t&) = default; - insert_list_t(insert_list_t&&) = default; - insert_list_t& operator=(const insert_list_t&) = default; - insert_list_t& operator=(insert_list_t&&) = default; - ~insert_list_t() = default; - - template - void add(Assignment&& assignment) - { - static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); - static_assert(not must_not_insert_t::type>::value, "set() argument must not be used in insert"); - _dynamic_columns.emplace_back(insert_column_t{std::forward(assignment._lhs)}); - _dynamic_values.emplace_back(std::forward(assignment._rhs)); - } - - - std::tuple...> _columns; - _parameter_tuple_t _values; - typename detail::serializable_list _dynamic_columns; - typename detail::serializable_list _dynamic_values; - }; - - template - struct interpreter_t> - { - using T = insert_list_t; - - static Context& _(const T& t, Context& context) - { - if (sizeof...(Assignments) + t._dynamic_columns.size() == 0) - { - interpret(insert_default_values_t(), context); - } - else - { - context << " ("; - interpret_tuple(t._columns, ",", context); - if (sizeof...(Assignments) and not t._dynamic_columns.empty()) - context << ','; - interpret_serializable_list(t._dynamic_columns, ',', context); - context << ") VALUES("; - interpret_tuple(t._values, ",", context); - if (sizeof...(Assignments) and not t._dynamic_values.empty()) - context << ','; - interpret_serializable_list(t._dynamic_values, ',', context); - context << ")"; - } - return context; - } - }; - - -} - -#endif diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index 37ab4a11..0a3afe4d 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -28,7 +28,7 @@ #define SQLPP_INTEGRAL_H #include -#include +#include #include #include @@ -168,21 +168,21 @@ namespace sqlpp template struct plus_ { - using _value_type = typename wrap_operand::type>::type::_value_type; + using _value_type = typename vendor::wrap_operand::type>::type::_value_type; static constexpr const char* _name = "+"; }; template struct minus_ { - using _value_type = typename wrap_operand::type>::type::_value_type; + using _value_type = typename vendor::wrap_operand::type>::type::_value_type; static constexpr const char* _name = "-"; }; template struct multiplies_ { - using _value_type = typename wrap_operand::type>::type::_value_type; + using _value_type = typename vendor::wrap_operand::type>::type::_value_type; static constexpr const char* _name = "*"; }; @@ -199,28 +199,28 @@ namespace sqlpp struct operators: public basic_operators { template - binary_expression_t, typename _constraint::type> operator +(T&& t) const + vendor::binary_expression_t, typename _constraint::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t, typename _constraint::type> operator -(T&& t) const + vendor::binary_expression_t, typename _constraint::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t, typename _constraint::type> operator *(T&& t) const + vendor::binary_expression_t, typename _constraint::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; } template - binary_expression_t::type> operator /(T&& t) const + vendor::binary_expression_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), std::forward(t) }; diff --git a/include/sqlpp11/interpreter.h b/include/sqlpp11/interpret.h similarity index 72% rename from include/sqlpp11/interpreter.h rename to include/sqlpp11/interpret.h index 7bd1c206..abbb3143 100644 --- a/include/sqlpp11/interpreter.h +++ b/include/sqlpp11/interpret.h @@ -24,28 +24,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_INTERPRETER_H -#define SQLPP_INTERPRETER_H +#ifndef SQLPP_INTERPRET_H +#define SQLPP_INTERPRET_H -#include -#include +#include namespace sqlpp { - template - struct interpreter_t - { - static void _(const T& t, Context& context) - { - static_assert(detail::wrong::value, "missing interpreter specialization"); - } - }; - template auto interpret(const T& t, Context& context) - -> decltype(interpreter_t::type, typename std::decay::type>::_(t, context)) + -> decltype(vendor::interpreter_t::type, typename std::decay::type>::_(t, context)) { - return interpreter_t::type, typename std::decay::type>::_(t, context); + return vendor::interpreter_t::type, typename std::decay::type>::_(t, context); } } diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index d9dbadd1..64f1f107 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -29,6 +29,7 @@ #include #include +#include namespace sqlpp { @@ -73,84 +74,84 @@ namespace sqlpp static constexpr const char* _name = " RIGHT OUTER "; }; - template - struct join_t - { - static_assert(is_table_t::value, "invalid lhs argument for join()"); - static_assert(is_table_t::value, "invalid rhs argument for join()"); - static_assert(is_noop::value or is_on_t::value, "invalid on expression in join().on()"); + template + struct join_t + { + static_assert(is_table_t::value, "invalid lhs argument for join()"); + static_assert(is_table_t::value, "invalid rhs argument for join()"); + static_assert(vendor::is_noop::value or is_on_t::value, "invalid on expression in join().on()"); - static_assert(Lhs::_table_set::template is_disjunct_from::value, "joined tables must not be identical"); + static_assert(Lhs::_table_set::template is_disjunct_from::value, "joined tables must not be identical"); - using _is_table = std::true_type; - using _table_set = typename Lhs::_table_set::template join::type; + using _is_table = std::true_type; + using _table_set = typename Lhs::_table_set::template join::type; - template - using set_on_t = join_t; + template + using set_on_t = join_t; - template - auto on(Expr&&... expr) - -> set_on_t::type...>> - { - static_assert(is_noop::value, "cannot call on() twice for a single join()"); - return { _lhs, - _rhs, - {std::tuple::type...>{std::forward(expr)...}} - }; - } + template + auto on(Expr&&... expr) + -> set_on_t::type...>> + { + static_assert(vendor::is_noop::value, "cannot call on() twice for a single join()"); + return { _lhs, + _rhs, + {std::tuple::type...>{std::forward(expr)...}} + }; + } - template - join_t::type> join(T&& t) - { - static_assert(not is_noop::value, "join type requires on()"); - return { *this, std::forward(t) }; - } + template + join_t::type> join(T&& t) + { + static_assert(not vendor::is_noop::value, "join type requires on()"); + return { *this, std::forward(t) }; + } - template - join_t::type> inner_join(T&& t) - { - static_assert(not is_noop::value, "join type requires on()"); - return { *this, std::forward(t) }; - } + template + join_t::type> inner_join(T&& t) + { + static_assert(not vendor::is_noop::value, "join type requires on()"); + return { *this, std::forward(t) }; + } - template - join_t::type> outer_join(T&& t) - { - static_assert(not is_noop::value, "join type requires on()"); - return { *this, std::forward(t) }; - } + template + join_t::type> outer_join(T&& t) + { + static_assert(not vendor::is_noop::value, "join type requires on()"); + return { *this, std::forward(t) }; + } - template - join_t::type> left_outer_join(T&& t) - { - static_assert(not is_noop::value, "join type requires on()"); - return { *this, std::forward(t) }; - } + template + join_t::type> left_outer_join(T&& t) + { + static_assert(not vendor::is_noop::value, "join type requires on()"); + return { *this, std::forward(t) }; + } - template - join_t::type> right_outer_join(T&& t) - { - static_assert(not is_noop::value, "join type requires on()"); - return { *this, std::forward(t) }; - } + template + join_t::type> right_outer_join(T&& t) + { + static_assert(not vendor::is_noop::value, "join type requires on()"); + return { *this, std::forward(t) }; + } - Lhs _lhs; - Rhs _rhs; - On _on; - }; + Lhs _lhs; + Rhs _rhs; + On _on; + }; // FIXME: Need to check if db supports the join type. e.g. sqlite does not support right outer or full outer join template - struct interpreter_t> + struct vendor::interpreter_t> { using T = join_t; static Context& _(const T& t, Context& context) { - static_assert(not is_noop::value, "joined tables require on()"); + static_assert(not vendor::is_noop::value, "joined tables require on()"); interpret(t._lhs, context); context << JoinType::_name; - context << " JOIN "; + context << " JOIN "; context << "("; interpret(t._rhs, context); interpret(t._on, context); diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index 524d84e8..d737ea48 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct max_t: public boolean::template operators> @@ -75,9 +75,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::max_t; + using T = vendor::max_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp }; template - auto max(T&& t) -> typename detail::max_t::type> + auto max(T&& t) -> typename vendor::max_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index 20ca7f54..969f6fdd 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct min_t: public boolean::template operators> @@ -75,9 +75,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::min_t; + using T = vendor::min_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp }; template - auto min(T&& t) -> typename detail::min_t::type> + auto min(T&& t) -> typename vendor::min_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index 398ff341..a4abd36e 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -56,7 +56,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = multi_column_t; diff --git a/include/sqlpp11/no_value.h b/include/sqlpp11/no_value.h index aac10366..2f330147 100644 --- a/include/sqlpp11/no_value.h +++ b/include/sqlpp11/no_value.h @@ -31,7 +31,6 @@ namespace sqlpp { - // boolean value type struct no_value_t { template diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index f5827210..bf6beeb7 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -27,10 +27,9 @@ #ifndef SQLPP_ON_H #define SQLPP_ON_H -#include #include -#include -#include +#include +#include namespace sqlpp { @@ -52,24 +51,24 @@ namespace sqlpp } std::tuple _expressions; - detail::serializable_list _dynamic_expressions; + vendor::interpretable_list_t _dynamic_expressions; }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = on_t; static Context& _(const T& t, Context& context) { - if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) - return context; - context << " ON "; - interpret_tuple(t._expressions, " AND ", context); - if (sizeof...(Expr) and not t._dynamic_expressions.empty()) - context << " AND "; - interpret_serializable_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; } }; diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h deleted file mode 100644 index 7591d4e8..00000000 --- a/include/sqlpp11/order_by.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_ORDER_BY_H -#define SQLPP_ORDER_BY_H - -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct order_by_t - { - using _is_order_by = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - // check for at least one order expression - static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()"); - - // check for duplicate order expressions - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in order_by()"); - - // check for invalid order expressions - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()"); - - template - void add(E&& expr) - { - static_assert(is_sort_order_t::type>::value, "order_by arguments require to be sort-order expressions"); - _dynamic_expressions.push_back(std::forward(expr)); - } - - _parameter_tuple_t _expressions; - detail::serializable_list _dynamic_expressions; - }; - - template - struct interpreter_t> - { - using T = order_by_t; - - static Context& _(const T& t, Context& context) - { - if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) - return context; - context << " ORDER BY "; - interpret_tuple(t._expressions, ',', context); - if (sizeof...(Expr) and not t._dynamic_expressions.empty()) - context << ','; - interpret_serializable_list(t._dynamic_expressions, ',', context); - return context; - } - }; - - -} - -#endif diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 3f056bb8..6cb9730c 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -27,8 +27,6 @@ #ifndef SQLPP_PARAMETER_H #define SQLPP_PARAMETER_H -#include -#include #include namespace sqlpp @@ -52,7 +50,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = parameter_t; diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index ac109cf1..06b18c08 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -32,25 +32,6 @@ namespace sqlpp { - namespace detail - { - template - struct or_t; - - template - struct or_t - { - static constexpr bool value = T::value or or_t::value; - }; - - template<> - struct or_t<> - { - static constexpr bool value = false; - }; - - } - template struct parameter_list_t { diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index 0a27a726..2d5d7566 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -27,21 +27,20 @@ #ifndef SQLPP_REMOVE_H #define SQLPP_REMOVE_H -#include -#include -#include -#include #include #include #include +#include +#include +#include namespace sqlpp { template< typename Database, typename Table, - typename Using = noop, - typename Where = noop + typename Using = vendor::noop, + typename Where = vendor::noop > struct remove_t; @@ -53,9 +52,9 @@ namespace sqlpp > struct remove_t { - static_assert(is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); - static_assert(is_noop::value or is_using_t::value, "invalid 'Using' argument"); - static_assert(is_noop::value or is_where_t::value, "invalid 'Where' argument"); + static_assert(vendor::is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); + static_assert(vendor::is_noop::value or is_using_t::value, "invalid 'Using' argument"); + static_assert(vendor::is_noop::value or is_where_t::value, "invalid 'Where' argument"); // FIXME: We might want to have everywhere() or all() to indicate that everything is to be removed, same with update and select @@ -70,10 +69,10 @@ namespace sqlpp template auto using_(Tab&&... tab) - -> set_using_t::type...>> + -> set_using_t::type...>> { - static_assert(std::is_same::value, "cannot call using() twice"); - static_assert(std::is_same::value, "cannot call using() after where()"); + static_assert(vendor::is_noop::value, "cannot call using() twice"); + static_assert(vendor::is_noop::value, "cannot call using() after where()"); return { _table, {std::tuple::type...>{std::forward(tab)...}}, @@ -83,10 +82,10 @@ namespace sqlpp template auto dynamic_using_(Tab&&... tab) - -> set_using_t::type...>> + -> set_using_t::type...>> { - static_assert(std::is_same::value, "cannot call using() twice"); - static_assert(std::is_same::value, "cannot call using() after where()"); + static_assert(vendor::is_noop::value, "cannot call using() twice"); + static_assert(vendor::is_noop::value, "cannot call using() after where()"); return { _table, {std::tuple::type...>{std::forward(tab)...}}, @@ -105,9 +104,9 @@ namespace sqlpp template auto where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(std::is_same::value, "cannot call where() twice"); + static_assert(vendor::is_noop::value, "cannot call where() twice"); return { _table, _using, @@ -117,9 +116,9 @@ namespace sqlpp template auto dynamic_where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(std::is_same::value, "cannot call where() twice"); + static_assert(vendor::is_noop::value, "cannot call where() twice"); return { _table, _using, @@ -167,7 +166,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = remove_t; diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 32518e12..b3cd937b 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -27,10 +27,9 @@ #ifndef SQLPP_RESULT_ROW_H #define SQLPP_RESULT_ROW_H -#include -#include +#include +#include #include -#include #include namespace sqlpp @@ -87,7 +86,7 @@ namespace sqlpp }; template - struct result_row_impl>, Rest...>: + struct result_row_impl>, Rest...>: public AliasProvider::_name_t::template _member_t>, // level prevents identical closures to be present twice in the inheritance tree public result_row_impl { diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 13703cba..9c00882d 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -29,20 +29,21 @@ #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 +#include #include #include @@ -80,15 +81,15 @@ namespace sqlpp using _Database = Database; using _From = From; - static_assert(is_noop::value or is_select_flag_list_t::value, "invalid list of select flags"); + static_assert(vendor::is_noop::value or is_select_flag_list_t::value, "invalid list of select flags"); static_assert(is_select_expression_list_t::value, "invalid list of select expressions"); - static_assert(is_noop::value or is_from_t::value, "invalid 'from' argument"); - static_assert(is_noop::value or is_where_t::value, "invalid 'where' argument"); - static_assert(is_noop::value or is_group_by_t::value, "invalid 'group by' arguments"); - static_assert(is_noop::value or is_having_t::value, "invalid 'having' arguments"); - static_assert(is_noop::value or is_order_by_t::value, "invalid 'order by' arguments"); - static_assert(is_noop::value or is_limit_t::value, "invalid 'limit' arguments"); - static_assert(is_noop::value or is_offset_t::value, "invalid 'offset' arguments"); + static_assert(vendor::is_noop::value or is_from_t::value, "invalid 'from' argument"); + static_assert(vendor::is_noop::value or is_where_t::value, "invalid 'where' argument"); + static_assert(vendor::is_noop::value or is_group_by_t::value, "invalid 'group by' arguments"); + static_assert(vendor::is_noop::value or is_having_t::value, "invalid 'having' arguments"); + static_assert(vendor::is_noop::value or is_order_by_t::value, "invalid 'order by' arguments"); + static_assert(vendor::is_noop::value or is_limit_t::value, "invalid 'limit' arguments"); + static_assert(vendor::is_noop::value or is_offset_t::value, "invalid 'offset' arguments"); using _is_select = std::true_type; using _requires_braces = std::true_type; @@ -117,7 +118,7 @@ namespace sqlpp // Indicators using _value_type = typename std::conditional< - is_noop::value, + vendor::is_noop::value, no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing) typename ExpressionList::_value_type>::type; @@ -174,7 +175,7 @@ namespace sqlpp -> set_expression_list_t> { static_assert(not std::is_same::value, "cannot call dynamic_from() in a non-dynamic select"); - static_assert(is_noop::value, "cannot call dynamic_columns() after from()"); + static_assert(vendor::is_noop::value, "cannot call dynamic_columns() after from()"); return { _flags, {_expression_list._expressions}, @@ -201,10 +202,10 @@ namespace sqlpp // sqlpp functions template auto from(Table&&... table) - -> set_from_t::type...>> + -> set_from_t::type...>> { - static_assert(not is_noop::value, "cannot call from() without having selected anything"); - static_assert(is_noop::value, "cannot call from() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call from() without having selected anything"); + static_assert(vendor::is_noop::value, "cannot call from() twice for a single select"); return { _flags, _expression_list, @@ -220,11 +221,11 @@ namespace sqlpp template auto dynamic_from(Table&&... table) - -> set_from_t::type...>> + -> set_from_t::type...>> { static_assert(not std::is_same::value, "cannot call dynamic_from() in a non-dynamic select"); - static_assert(not is_noop::value, "cannot call from() without having selected anything"); - static_assert(is_noop::value, "cannot call from() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call from() without having selected anything"); + static_assert(vendor::is_noop::value, "cannot call from() twice for a single select"); return { _flags, _expression_list, @@ -241,7 +242,7 @@ namespace sqlpp template select_t& add_from(Table&& table) { - static_assert(not is_noop::value, "cannot call add_from() without having selected anything"); + static_assert(not vendor::is_noop::value, "cannot call add_from() without having selected anything"); static_assert(is_dynamic_t::value, "cannot call add_from() in a non-dynamic from"); _from.add(std::forward
(table)); @@ -251,10 +252,10 @@ namespace sqlpp template auto where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(not is_noop::value, "cannot call where() without a from()"); - static_assert(is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call where() without a from()"); + static_assert(vendor::is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); return { _flags, _expression_list, @@ -270,10 +271,10 @@ namespace sqlpp template auto dynamic_where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(not is_noop::value, "cannot call dynamic_where() without a from()"); - static_assert(is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call dynamic_where() without a from()"); + static_assert(vendor::is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); return { _flags, _expression_list, @@ -299,10 +300,10 @@ namespace sqlpp template auto group_by(Col&&... column) - -> set_group_by_t::type...>> + -> set_group_by_t::type...>> { - static_assert(not is_noop::value, "cannot call group_by() without a from()"); - static_assert(is_noop::value, "cannot call group_by() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call group_by() without a from()"); + static_assert(vendor::is_noop::value, "cannot call group_by() twice for a single select"); return { _flags, _expression_list, @@ -318,10 +319,10 @@ namespace sqlpp template auto dynamic_group_by(Col&&... column) - -> set_group_by_t::type...>> + -> set_group_by_t::type...>> { - static_assert(not is_noop::value, "cannot call group_by() without a from()"); - static_assert(is_noop::value, "cannot call group_by() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call group_by() without a from()"); + static_assert(vendor::is_noop::value, "cannot call group_by() twice for a single select"); return { _flags, _expression_list, @@ -347,10 +348,10 @@ namespace sqlpp template auto having(Expr&&... expr) - -> set_having_t::type...>> + -> set_having_t::type...>> { - static_assert(not is_noop::value, "cannot call having() without a group_by"); - static_assert(is_noop::value, "cannot call having() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call having() without a group_by"); + static_assert(vendor::is_noop::value, "cannot call having() twice for a single select"); return { _flags, _expression_list, @@ -366,10 +367,10 @@ namespace sqlpp template auto dynamic_having(Expr&&... expr) - -> set_having_t::type...>> + -> set_having_t::type...>> { - static_assert(not is_noop::value, "cannot call having() without a group_by"); - static_assert(is_noop::value, "cannot call having() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call having() without a group_by"); + static_assert(vendor::is_noop::value, "cannot call having() twice for a single select"); return { _flags, _expression_list, @@ -395,10 +396,10 @@ namespace sqlpp template auto order_by(OrderExpr&&... expr) - -> set_order_by_t::type...>> + -> set_order_by_t::type...>> { - static_assert(not is_noop::value, "cannot call order_by() without a from()"); - static_assert(is_noop::value, "cannot call order_by() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call order_by() without a from()"); + static_assert(vendor::is_noop::value, "cannot call order_by() twice for a single select"); return { _flags, _expression_list, @@ -414,10 +415,10 @@ namespace sqlpp template auto dynamic_order_by(OrderExpr&&... expr) - -> set_order_by_t::type...>> + -> set_order_by_t::type...>> { - static_assert(not is_noop::value, "cannot call order_by() without a from()"); - static_assert(is_noop::value, "cannot call order_by() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call order_by() without a from()"); + static_assert(vendor::is_noop::value, "cannot call order_by() twice for a single select"); return { _flags, _expression_list, @@ -443,10 +444,10 @@ namespace sqlpp template auto limit(Expr limit) - -> set_limit_t::type>::type>> + -> set_limit_t::type>::type>> { - static_assert(not is_noop::value, "cannot call limit() without a from()"); - static_assert(is_noop::value, "cannot call limit() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call limit() without a from()"); + static_assert(vendor::is_noop::value, "cannot call limit() twice for a single select"); return { _flags, _expression_list, @@ -461,10 +462,10 @@ namespace sqlpp } auto dynamic_limit(std::size_t limit = 0) - ->set_limit_t + ->set_limit_t { - static_assert(not is_noop::value, "cannot call limit() without a from()"); - static_assert(is_noop::value, "cannot call limit() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call limit() without a from()"); + static_assert(vendor::is_noop::value, "cannot call limit() twice for a single select"); return { _flags, _expression_list, @@ -489,10 +490,10 @@ namespace sqlpp template auto offset(Expr offset) - -> set_offset_t::type>::type>> + -> set_offset_t::type>::type>> { - static_assert(not is_noop::value, "cannot call offset() without a limit"); - static_assert(is_noop::value, "cannot call offset() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call offset() without a limit"); + static_assert(vendor::is_noop::value, "cannot call offset() twice for a single select"); return { _flags, _expression_list, @@ -507,10 +508,10 @@ namespace sqlpp } auto dynamic_offset(std::size_t offset = 0) - -> set_offset_t + -> set_offset_t { - static_assert(not is_noop::value, "cannot call offset() without a limit"); - static_assert(is_noop::value, "cannot call offset() twice for a single select"); + static_assert(not vendor::is_noop::value, "cannot call offset() without a limit"); + static_assert(vendor::is_noop::value, "cannot call offset() twice for a single select"); return { _flags, _expression_list, @@ -572,7 +573,7 @@ namespace sqlpp auto run(Db& db) const -> result_t { - static_assert(not is_noop::value, "cannot run select without having selected anything"); + static_assert(not vendor::is_noop::value, "cannot run select without having selected anything"); static_assert(is_from_t::value, "cannot run select without a from()"); static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead"); // FIXME: Check for missing aliases (if references are used) @@ -586,7 +587,7 @@ namespace sqlpp auto prepare(Db& db) -> prepared_select_t::type, select_t> const { - static_assert(not is_noop::value, "cannot run select without having selected anything"); + static_assert(not vendor::is_noop::value, "cannot run select without having selected anything"); static_assert(is_from_t::value, "cannot run select without a from()"); // FIXME: Check for missing aliases (if references are used) // FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc. @@ -617,7 +618,7 @@ namespace sqlpp typename Limit, typename Offset > - struct interpreter_t using make_select_flag_list_t = - select_flag_list_t()...))>; + vendor::select_flag_list_t()...))>; } // construct select expression list @@ -671,7 +672,7 @@ namespace sqlpp { template using make_select_expression_list_t = - select_expression_list_t()...))>; + vendor::select_expression_list_t()...))>; } template diff --git a/include/sqlpp11/select_expression_list.h b/include/sqlpp11/select_expression_list.h deleted file mode 100644 index e7191c7f..00000000 --- a/include/sqlpp11/select_expression_list.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_SELECT_EXPRESSION_LIST_H -#define SQLPP_SELECT_EXPRESSION_LIST_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sqlpp -{ - namespace detail - { - template - struct get_first_argument_if_unique - { - using _value_type = no_value_t; - struct _name_t {}; - }; - - template - struct get_first_argument_if_unique - { - using _value_type = typename T::_value_type; - using _name_t = typename T::_name_t; - }; - } - - template - struct dynamic_select_expression_list - { - using _names_t = std::vector; - std::vector> _dynamic_expressions; - _names_t _dynamic_expression_names; - - template - void push_back(Expr&& expr) - { - _dynamic_expression_names.push_back(std::decay::type::_name_t::_get_name()); - _dynamic_expressions.emplace_back(std::forward(expr)); - } - - bool empty() const - { - return _dynamic_expressions.empty(); - } - }; - - template<> - struct dynamic_select_expression_list - { - struct _names_t {}; - _names_t _dynamic_expression_names; - - template - void push_back(const T&) {} - - static constexpr bool empty() - { - return true; - } - }; - - template - struct interpreter_t> - { - using T = dynamic_select_expression_list; - - static Context& _(const T& t, Context& context) - { - for (const auto column : t._dynamic_expressions) - { - interpret(column, context); - } - return context; - } - }; - - template - struct interpreter_t> - { - using T = dynamic_select_expression_list; - - static Context& _(const T& t, Context& context) - { - return context; - } - }; - - - template - struct select_expression_list_t> - { - using _is_select_expression_list = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - // check for at least one expression - static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required"); - - // check for duplicate select expressions - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected"); - - // check for invalid select expressions - template - struct is_valid_expression_t: public std::integral_constant::value or is_multi_column_t::value> {}; - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression"); - - // check for duplicate select expression names - static_assert(not detail::has_duplicates::value, "at least one duplicate name detected"); - - // provide type information for sub-selects that are used as expressions - struct _column_type {}; - struct _value_type: detail::get_first_argument_if_unique::_value_type - { - using _is_expression = typename std::conditional::type; - using _is_named_expression = typename std::conditional::type; - using _is_alias = std::false_type; - }; - using _name_t = typename detail::get_first_argument_if_unique::_name_t; - - 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_expression_list::_names_t; - - template - using _pseudo_table_t = select_pseudo_table_t; - - template - using _dynamic_t = select_expression_list_t>; - - template - void add(Expr&& namedExpr) - { - static_assert(is_named_expression_t::type>::value, "select() arguments require to be named expressions"); - static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list"); - _dynamic_expressions.push_back(std::forward(namedExpr)); - } - - _parameter_tuple_t _expressions; - dynamic_select_expression_list _dynamic_expressions; - }; - - template - struct interpreter_t> - { - using T = select_expression_list_t; - - static Context& _(const T& t, Context& context) - { - interpret_tuple(t._expressions, ',', context); - if (sizeof...(NamedExpr) and not t._dynamic_expressions.empty()) - context << ','; - interpret(t._dynamic_expressions, context); - return context; - } - }; - -} - -#endif diff --git a/include/sqlpp11/select_fwd.h b/include/sqlpp11/select_fwd.h index ec50ce1d..884bcd9e 100644 --- a/include/sqlpp11/select_fwd.h +++ b/include/sqlpp11/select_fwd.h @@ -27,7 +27,8 @@ #ifndef SQLPP_SELECT_FWD_H #define SQLPP_SELECT_FWD_H -#include +// FIXME: Do we really need this file? +#include #include namespace sqlpp @@ -37,36 +38,17 @@ namespace sqlpp struct distinct_t; struct straight_join_t; - template struct select_flag_list_t; - template struct select_expression_list_t; - - template struct from_t; - - template struct where_t; - - template struct group_by_t; - - template struct having_t; - - template struct order_by_t; - - template - struct limit_t; - - template - struct offset_t; - template< typename Db, - typename Flags = noop, - typename ExpressionList = noop, - typename From = noop, - typename Where = noop, - typename GroupBy = noop, - typename Having = noop, - typename OrderBy = noop, - typename Limit = noop, - typename Offset = noop + typename Flags = vendor::noop, + typename ExpressionList = vendor::noop, + typename From = vendor::noop, + typename Where = vendor::noop, + typename GroupBy = vendor::noop, + typename Having = vendor::noop, + typename OrderBy = vendor::noop, + typename Limit = vendor::noop, + typename Offset = vendor::noop > struct select_t; } diff --git a/include/sqlpp11/some.h b/include/sqlpp11/some.h index 768279c9..5a1a19c8 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct some_t: public boolean::template operators> @@ -76,9 +76,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::some_t; static Context& _(const T& t, Context& context) { @@ -90,7 +90,7 @@ namespace sqlpp }; template - auto some(T&& t) -> typename detail::some_t::type> + auto some(T&& t) -> typename vendor::some_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index 30c85d3b..d2e11c66 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -44,7 +44,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = sort_order_t; diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 0e260b3b..56a20ddd 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -32,7 +32,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct sum_t: public boolean::template operators> @@ -75,9 +75,9 @@ namespace sqlpp } template - struct interpreter_t> + struct vendor::interpreter_t> { - using T = detail::sum_t; + using T = vendor::sum_t; static Context& _(const T& t, Context& context) { @@ -89,7 +89,7 @@ namespace sqlpp }; template - auto sum(T&& t) -> typename detail::sum_t::type> + auto sum(T&& t) -> typename vendor::sum_t::type> { return { std::forward(t) }; } diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 6c549aa0..0e502981 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -27,12 +27,12 @@ #ifndef SQLPP_TABLE_H #define SQLPP_TABLE_H +#include #include -#include #include #include -#include #include +#include namespace sqlpp { @@ -100,7 +100,7 @@ namespace sqlpp } template - struct interpreter_t::value and not is_pseudo_table_t::value, void>::type> + struct vendor::interpreter_t::value and not is_pseudo_table_t::value, void>::type> { using T = X; diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index c84e189b..0588c6a5 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -27,12 +27,11 @@ #ifndef SQLPP_TABLE_ALIAS_H #define SQLPP_TABLE_ALIAS_H -#include -#include -#include +#include +#include +#include #include #include -#include namespace sqlpp { @@ -63,7 +62,7 @@ namespace sqlpp }; template - struct interpreter_t::value, void>::type> + struct vendor::interpreter_t::value, void>::type> { using T = X; diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 36098e39..f2baaa8d 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -28,11 +28,11 @@ #define SQLPP_TEXT_H #include -#include +#include #include #include -#include -#include +#include +#include namespace sqlpp { @@ -177,14 +177,14 @@ namespace sqlpp struct operators: public basic_operators { template - concat_t::type> operator+(T&& t) const + vendor::concat_t::type> operator+(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - like_t::type> like(T&& t) const + vendor::like_t::type> like(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h index 6f77085b..91eff115 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -30,16 +30,16 @@ // TVIN: Trivial value is NULL #include -#include +#include namespace sqlpp { template struct tvin_t { - using _wrapped_t = typename wrap_operand::type; - static_assert(not std::is_same<_wrapped_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)"); - using _value_type = typename _wrapped_t::_value_type; + using _operand_t = typename vendor::wrap_operand::type; + static_assert(not std::is_same<_operand_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)"); + using _value_type = typename _operand_t::_value_type; tvin_t(T t): _value({t}) @@ -50,11 +50,11 @@ namespace sqlpp tvin_t& operator=(tvin_t&&) = default; ~tvin_t() = default; - _wrapped_t _value; + _operand_t _value; }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = tvin_t; @@ -101,11 +101,11 @@ namespace sqlpp tvin_wrap_t& operator=(tvin_wrap_t&&) = default; ~tvin_wrap_t() = default; - typename tvin_t::_wrapped_t _value; + typename tvin_t::_operand_t _value; }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = tvin_wrap_t; diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 56000008..3cba4240 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -28,7 +28,7 @@ #define SQLPP_TYPE_TRAITS_H #include -#include +#include namespace sqlpp { @@ -112,7 +112,7 @@ namespace sqlpp SQLPP_TYPE_TRAIT_GENERATOR(is_multi_column); SQLPP_TYPE_TRAIT_GENERATOR(is_value_list); SQLPP_TYPE_TRAIT_GENERATOR(is_assignment); - SQLPP_TYPE_TRAIT_GENERATOR(is_assignment_list); + SQLPP_TYPE_TRAIT_GENERATOR(is_update_list); SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list); SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order); SQLPP_TYPE_TRAIT_GENERATOR(requires_braces); @@ -126,12 +126,11 @@ namespace sqlpp template class IsCorrectType> struct operand_t { - using type = typename wrap_operand::type>::type; + using type = typename vendor::wrap_operand::type>::type; static_assert(not is_alias_t::value, "expression operand must not be an alias"); static_assert(is_expression_t::value, "expression required"); static_assert(IsCorrectType::value, "invalid operand type"); }; - } diff --git a/include/sqlpp11/update.h b/include/sqlpp11/update.h index 20ed06ef..f8234640 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -27,21 +27,20 @@ #ifndef SQLPP_UPDATE_H #define SQLPP_UPDATE_H -#include -#include -#include -#include #include #include #include +#include +#include +#include namespace sqlpp { template< typename Database = void, - typename Table = noop, - typename Assignments = noop, - typename Where = noop + typename Table = vendor::noop, + typename Assignments = vendor::noop, + typename Where = vendor::noop > struct update_t; @@ -53,9 +52,9 @@ namespace sqlpp > struct update_t { - static_assert(is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); - static_assert(is_noop::value or is_assignment_list_t::value, "invalid 'Assignments' arguments"); - static_assert(is_noop::value or is_where_t::value, "invalid 'Where' argument"); + static_assert(vendor::is_noop
::value or is_table_t
::value, "invalid 'Table' argument"); + static_assert(vendor::is_noop::value or is_update_list_t::value, "invalid 'Assignments' arguments"); + static_assert(vendor::is_noop::value or is_where_t::value, "invalid 'Where' argument"); template using set_assignments_t = update_t; @@ -68,9 +67,9 @@ namespace sqlpp template auto set(Assignment&&... assignment) - -> set_assignments_t::type...>> + -> set_assignments_t::type...>> { - static_assert(std::is_same::value, "cannot call set() twice"); + static_assert(vendor::is_noop::value, "cannot call set() twice"); return { _table, {std::tuple::type...>{std::forward(assignment)...}}, @@ -80,9 +79,9 @@ namespace sqlpp template auto dynamic_set(Assignment&&... assignment) - -> set_assignments_t::type...>> + -> set_assignments_t::type...>> { - static_assert(std::is_same::value, "cannot call set() twice"); + static_assert(vendor::is_noop::value, "cannot call set() twice"); return { _table, {std::tuple::type...>{std::forward(assignment)...}}, @@ -102,10 +101,10 @@ namespace sqlpp template auto where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(not std::is_same::value, "cannot call where() if set() hasn't been called yet"); - static_assert(std::is_same::value, "cannot call where() twice"); + static_assert(not vendor::is_noop::value, "cannot call where() if set() hasn't been called yet"); + static_assert(vendor::is_noop::value, "cannot call where() twice"); return { _table, _assignments, @@ -115,10 +114,10 @@ namespace sqlpp template auto dynamic_where(Expr&&... expr) - -> set_where_t::type...>> + -> set_where_t::type...>> { - static_assert(not std::is_same::value, "cannot call where() if set() hasn't been called yet"); - static_assert(std::is_same::value, "cannot call where() twice"); + static_assert(not vendor::is_noop::value, "cannot call where() if set() hasn't been called yet"); + static_assert(vendor::is_noop::value, "cannot call where() twice"); return { _table, _assignments, @@ -149,7 +148,7 @@ namespace sqlpp template std::size_t run(Db& db) const { - static_assert(not is_noop::value, "calling set() required before running update"); + static_assert(not vendor::is_noop::value, "calling set() required before running update"); static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead"); return db.update(*this); } @@ -158,7 +157,7 @@ namespace sqlpp auto prepare(Db& db) -> prepared_update_t::type, update_t> { - static_assert(not is_noop::value, "calling set() required before running update"); + static_assert(not vendor::is_noop::value, "calling set() required before running update"); return {{}, db.prepare_update(*this)}; } @@ -174,7 +173,7 @@ namespace sqlpp typename Assignments, typename Where > - struct interpreter_t> + struct vendor::interpreter_t> { using T = update_t; diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h deleted file mode 100644 index 8371833c..00000000 --- a/include/sqlpp11/using.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_USING_H -#define SQLPP_USING_H - -#include -#include -#include -#include -#include - -namespace sqlpp -{ - template - struct using_t - { - using _is_using = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()"); - - // check for duplicate arguments - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in using()"); - - // check for invalid arguments - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()"); - - - template - void add(T&& table) - { - static_assert(is_table_t::type>::value, "using() arguments require to be tables"); - _dynamic_tables.emplace_back(std::forward(table)); - } - - _parameter_tuple_t _tables; - detail::serializable_list _dynamic_tables; - }; - - template - struct interpreter_t> - { - using T = using_t; - - static Context& _(const T& t, Context& context) - { - if (sizeof...(Table) == 0 and t._dynamic_tables.empty()) - return context; - context << " USING "; - interpret_tuple(t._tables, ',', context); - if (sizeof...(Table) and not t._dynamic_tables.empty()) - context << ','; - interpret_serializable_list(t._dynamic_tables, ',', context); - return context; - } - }; - - -} - -#endif diff --git a/include/sqlpp11/char_result_row.h b/include/sqlpp11/vendor/char_result_row.h similarity index 100% rename from include/sqlpp11/char_result_row.h rename to include/sqlpp11/vendor/char_result_row.h diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/vendor/concat.h similarity index 78% rename from include/sqlpp11/concat.h rename to include/sqlpp11/vendor/concat.h index 89e576ae..01e7e752 100644 --- a/include/sqlpp11/concat.h +++ b/include/sqlpp11/vendor/concat.h @@ -27,15 +27,16 @@ #ifndef SQLPP_CONCAT_H #define SQLPP_CONCAT_H -#include #include -#include +#include #include namespace sqlpp { + namespace vendor + { template - struct concat_t: public First::_value_type::template operators> + struct concat_t: public First::_value_type::template operators> { static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); using _valid_args = typename detail::make_set_if_not::type; @@ -69,28 +70,20 @@ namespace sqlpp std::tuple _args; }; - //FIXME: Write partial specialization for mysql - template - struct interpreter_t> - { - using T = concat_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t> { - context << "("; - interpret_tuple(t._args, "||", context); - context << ")"; - return context; - } - }; + using T = concat_t; - - template - auto concat(T&&... t) -> concat_t::type...> - { - return { std::forward(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 new file mode 100644 index 00000000..5d63e506 --- /dev/null +++ b/include/sqlpp11/vendor/expression.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_EXPRESSION_H +#define SQLPP_EXPRESSION_H + +#include +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct assignment_t + { + using _is_assignment = std::true_type; + using column_type = Lhs; + using value_type = tvin_wrap_t; + using _parameter_tuple_t = std::tuple; + + assignment_t(Lhs lhs, Rhs 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; + + Lhs _lhs; + tvin_wrap_t _rhs; + }; + + template + struct interpreter_t> + { + using T = assignment_t; + + static Context& _(const T& t, Context& context) + { + interpret(t._lhs, context); + if (t._rhs._is_trivial()) + { + context << "=NULL"; + } + else + { + context << "="; + interpret(t._rhs, context); + } + return context; + } + }; + + + template + struct equal_t: public detail::boolean::template operators> + { + using _value_type = detail::boolean; + using _parameter_tuple_t = std::tuple; + + equal_t(Lhs lhs, Rhs rhs): + _lhs(lhs), + _rhs(rhs) + {} + + equal_t(const equal_t&) = default; + equal_t(equal_t&&) = default; + equal_t& operator=(const equal_t&) = default; + equal_t& operator=(equal_t&&) = default; + ~equal_t() = default; + + Lhs _lhs; + tvin_wrap_t _rhs; + }; + + template + struct interpreter_t> + { + using T = equal_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + interpret(t._lhs, context); + if (t._rhs._is_trivial()) + { + context << " IS NULL"; + } + else + { + context << "="; + interpret(t._rhs, context); + } + context << ")"; + return context; + } + }; + + template + struct not_equal_t: public detail::boolean::template operators> + { + using _value_type = detail::boolean; + using _parameter_tuple_t = std::tuple; + + not_equal_t(Lhs lhs, Rhs rhs): + _lhs(lhs), + _rhs(rhs) + {} + + not_equal_t(const not_equal_t&) = default; + not_equal_t(not_equal_t&&) = default; + not_equal_t& operator=(const not_equal_t&) = default; + not_equal_t& operator=(not_equal_t&&) = default; + ~not_equal_t() = default; + + Lhs _lhs; + tvin_wrap_t _rhs; + }; + + template + struct interpreter_t> + { + using T = not_equal_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + interpret(t._lhs, context); + if (t._rhs._is_trivial()) + { + context << " IS NOT NULL"; + } + else + { + context << "!="; + interpret(t._rhs, context); + } + context << ")"; + return context; + } + }; + + template + struct not_t: public detail::boolean::template operators> + { + using _value_type = detail::boolean; + using _parameter_tuple_t = std::tuple; + + not_t(Lhs l): + _lhs(l) + {} + + not_t(const not_t&) = default; + not_t(not_t&&) = default; + not_t& operator=(const not_t&) = default; + not_t& operator=(not_t&&) = default; + ~not_t() = default; + + Lhs _lhs; + }; + + template + struct interpreter_t> + { + using T = not_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + context << "NOT "; + interpret(t._lhs, context); + context << ")"; + return context; + } + }; + + template + struct binary_expression_t: public O::_value_type::template operators> + { + using _value_type = typename O::_value_type; + using _parameter_tuple_t = std::tuple; + + 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 interpreter_t> + { + using T = binary_expression_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + interpret(t._lhs, context); + context << O::_name; + interpret(t._rhs, context); + context << ")"; + return context; + } + }; + } +} + +#endif diff --git a/include/sqlpp11/expression_fwd.h b/include/sqlpp11/vendor/expression_fwd.h similarity index 81% rename from include/sqlpp11/expression_fwd.h rename to include/sqlpp11/vendor/expression_fwd.h index cdab55bc..9fef78fc 100644 --- a/include/sqlpp11/expression_fwd.h +++ b/include/sqlpp11/vendor/expression_fwd.h @@ -29,20 +29,23 @@ namespace sqlpp { - template - struct assignment_t; + namespace vendor + { + template + struct assignment_t; - template - struct equal_t; + template + struct equal_t; - template - struct not_equal_t; + template + struct not_equal_t; - template - struct not_t; + template + struct not_t; - template - struct binary_expression_t; + template + struct binary_expression_t; + } } #endif diff --git a/include/sqlpp11/field.h b/include/sqlpp11/vendor/field.h similarity index 66% rename from include/sqlpp11/field.h rename to include/sqlpp11/vendor/field.h index f4ca0cf9..cf816b77 100644 --- a/include/sqlpp11/field.h +++ b/include/sqlpp11/vendor/field.h @@ -27,41 +27,43 @@ #ifndef SQLPP_FIELD_H #define SQLPP_FIELD_H -#include #include namespace sqlpp { - template - struct field_t - { - using _name_t = NameType; - using _value_type = ValueType; - }; - - template - struct multi_field_t - { - }; - - namespace detail + namespace vendor { + template + struct field_t + { + using _name_t = NameType; + using _value_type = ValueType; + }; + + template + struct multi_field_t + { + }; + + namespace detail + { + template + struct make_field_t_impl + { + using type = field_t; + }; + + template + struct make_field_t_impl>> + { + using type = multi_field_t::type...>>; + }; + } + template - struct make_field_t_impl - { - using type = field_t; - }; - - template - struct make_field_t_impl>> - { - using type = multi_field_t::type...>>; - }; + using make_field_t = typename detail::make_field_t_impl::type; } - template - using make_field_t = typename detail::make_field_t_impl::type; - } #endif diff --git a/include/sqlpp11/vendor/from.h b/include/sqlpp11/vendor/from.h new file mode 100644 index 00000000..3d533eab --- /dev/null +++ b/include/sqlpp11/vendor/from.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_FROM_H +#define SQLPP_FROM_H + +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct from_t + { + using _is_from = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + + // ensure one argument at least + static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()"); + + // check for duplicate arguments + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in from()"); + + // check for invalid arguments + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()"); + + // FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance + + + template + void add(Table&& table) + { + static_assert(is_table_t::type>::value, "from arguments require to be tables or joins"); + _dynamic_tables.emplace_back(std::forward
(table)); + } + + std::tuple _tables; + vendor::interpretable_list_t _dynamic_tables; + }; + + template + struct interpreter_t> + { + using T = from_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(TableOrJoin) == 0 and t._dynamic_tables.empty()) + return context; + context << " FROM "; + interpret_tuple(t._tables, ',', context); + if (sizeof...(TableOrJoin) 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 new file mode 100644 index 00000000..a01a77e2 --- /dev/null +++ b/include/sqlpp11/vendor/group_by.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_GROUP_BY_H +#define SQLPP_GROUP_BY_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct group_by_t + { + using _is_group_by = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + // ensure one argument at least + static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()"); + + // check for duplicate expressions + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in group_by()"); + + // check for invalid expressions + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()"); + + template + void add(E&& expr) + { + static_assert(is_table_t::type>::value, "from arguments require to be tables or joins"); + _dynamic_expressions.emplace_back(std::forward(expr)); + } + + _parameter_tuple_t _expressions; + vendor::interpretable_list_t _dynamic_expressions; + + }; + + template + struct interpreter_t> + { + using T = group_by_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) + return context; + context << " GROUP BY "; + interpret_tuple(t._expressions, ',', context); + if (sizeof...(Expr) 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/vendor/having.h similarity index 54% rename from include/sqlpp11/having.h rename to include/sqlpp11/vendor/having.h index 1ba4c6ba..df5d0503 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/vendor/having.h @@ -27,58 +27,58 @@ #ifndef SQLPP_HAVING_H #define SQLPP_HAVING_H -#include #include -#include +#include +#include +#include #include -#include -#include namespace sqlpp { - template - struct having_t - { - using _is_having = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()"); - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()"); - - using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; - - template - void add(E&& expr) - { - static_assert(is_expression_t::type>::value, "invalid expression argument in add_having()"); - _dynamic_expressions.emplace_back(std::forward(expr)); - } - - _parameter_tuple_t _expressions; - detail::serializable_list _dynamic_expressions; - }; - - template - struct interpreter_t> - { - using T = having_t; - - static Context& _(const T& t, Context& context) + namespace vendor + { + template + struct having_t { + using _is_having = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()"); + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()"); + + using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; + + template + void add(E&& expr) + { + static_assert(is_expression_t::type>::value, "invalid expression argument in add_having()"); + _dynamic_expressions.emplace_back(std::forward(expr)); + } + + _parameter_tuple_t _expressions; + vendor::interpretable_list_t _dynamic_expressions; + }; + + template + struct interpreter_t> + { + using T = having_t; + + static Context& _(const T& t, Context& context) + { if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) return context; context << " HAVING "; interpret_tuple(t._expressions, " AND ", context); if (sizeof...(Expr) and not t._dynamic_expressions.empty()) context << " AND "; - interpret_serializable_list(t._dynamic_expressions, " AND ", context); + interpret_list(t._dynamic_expressions, " AND ", context); return context; - } - }; - - + } + }; + } } #endif diff --git a/include/sqlpp11/in.h b/include/sqlpp11/vendor/in.h similarity index 78% rename from include/sqlpp11/in.h rename to include/sqlpp11/vendor/in.h index 6d188f98..a7d9ecff 100644 --- a/include/sqlpp11/in.h +++ b/include/sqlpp11/vendor/in.h @@ -24,21 +24,20 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_IN_FWD_H -#define SQLPP_IN_FWD_H +#ifndef SQLPP_IN_H +#define SQLPP_IN_H -#include #include #include +#include #include namespace sqlpp { - // FIXME: Move to vendor namespace - namespace detail + namespace vendor { template - struct in_t: public boolean::template operators> + struct in_t: public boolean::template operators> { static constexpr bool _inverted = not NotInverted; static_assert(sizeof...(Args) > 0, "in() requires at least one argument"); @@ -77,22 +76,22 @@ namespace sqlpp Operand _operand; std::tuple _args; }; - } - template - struct interpreter_t> - { - using T = detail::in_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t> { - interpret(t._operand, context); - context << (t._inverted ? " NOT IN(" : " IN("); - interpret_tuple(t._args, ',', context); - context << ')'; - return context; - } - }; + using T = vendor::in_t; + + static Context& _(const T& t, Context& context) + { + interpret(t._operand, context); + context << (t._inverted ? " NOT IN(" : " IN("); + interpret_tuple(t._args, ',', context); + context << ')'; + return context; + } + }; + } } diff --git a/include/sqlpp11/in_fwd.h b/include/sqlpp11/vendor/in_fwd.h similarity index 94% rename from include/sqlpp11/in_fwd.h rename to include/sqlpp11/vendor/in_fwd.h index 98c45464..b33aee1c 100644 --- a/include/sqlpp11/in_fwd.h +++ b/include/sqlpp11/vendor/in_fwd.h @@ -24,13 +24,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_IN_H -#define SQLPP_IN_H +#ifndef SQLPP_IN_FWD_H +#define SQLPP_IN_FWD_H namespace sqlpp { - // FIXME: Move to vendor namespace - namespace detail + namespace vendor { template struct in_t; diff --git a/include/sqlpp11/vendor/insert_list.h b/include/sqlpp11/vendor/insert_list.h new file mode 100644 index 00000000..d8af1f49 --- /dev/null +++ b/include/sqlpp11/vendor/insert_list.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_INSERT_LIST_H +#define SQLPP_INSERT_LIST_H + +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + struct insert_default_values_t + { + using _is_insert_list = std::true_type; + using _is_dynamic = std::false_type; + }; + + template + struct interpreter_t + { + using T = insert_default_values_t; + + static Context& _(const T& t, Context& context) + { + context << " DEFAULT VALUES"; + return context; + } + }; + + template + struct insert_column_t + { + Column _column; + }; + + template + struct interpreter_t> + { + using T = insert_column_t; + + static Context& _(const T& t, Context& context) + { + context << t._column._get_name(); + return context; + } + }; + + + template + struct insert_list_t + { + using _is_insert_list = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + // check for at least one order expression + static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()"); + + // check for duplicate assignments + static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in set()"); + + // check for invalid assignments + using _assignment_set = typename detail::make_set_if::type; + static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); + + // check for prohibited assignments + using _prohibited_assignment_set = typename detail::make_set_if::type; + static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); + + insert_list_t(Assignments... assignment): + _columns({assignment._lhs}...), + _values(assignment._rhs...) + {} + + insert_list_t(const insert_list_t&) = default; + insert_list_t(insert_list_t&&) = default; + insert_list_t& operator=(const insert_list_t&) = default; + insert_list_t& operator=(insert_list_t&&) = default; + ~insert_list_t() = default; + + template + void add(Assignment&& assignment) + { + static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); + static_assert(not must_not_insert_t::type>::value, "set() argument must not be used in insert"); + _dynamic_columns.emplace_back(insert_column_t{std::forward(assignment._lhs)}); + _dynamic_values.emplace_back(std::forward(assignment._rhs)); + } + + + std::tuple...> _columns; + _parameter_tuple_t _values; + typename vendor::interpretable_list_t _dynamic_columns; + typename vendor::interpretable_list_t _dynamic_values; + }; + + template + struct interpreter_t> + { + using T = insert_list_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(Assignments) + t._dynamic_columns.size() == 0) + { + interpret(insert_default_values_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/interpret_tuple.h b/include/sqlpp11/vendor/interpret_tuple.h similarity index 100% rename from include/sqlpp11/interpret_tuple.h rename to include/sqlpp11/vendor/interpret_tuple.h diff --git a/include/sqlpp11/detail/serializable.h b/include/sqlpp11/vendor/interpretable.h similarity index 80% rename from include/sqlpp11/detail/serializable.h rename to include/sqlpp11/vendor/interpretable.h index 6734e479..3eb5265f 100644 --- a/include/sqlpp11/detail/serializable.h +++ b/include/sqlpp11/vendor/interpretable.h @@ -24,8 +24,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_SERIALIZABLE_H -#define SQLPP_SERIALIZABLE_H +#ifndef SQLPP_INTERPRETABLE_H +#define SQLPP_INTERPRETABLE_H #include #include @@ -33,23 +33,23 @@ namespace sqlpp { - namespace detail + namespace vendor { template - struct serializable_t + struct interpretable_t { using _context_t = typename Db::context; template - serializable_t(T t): + interpretable_t(T t): _impl(std::make_shared<_impl_t::type>>(t)) {} - serializable_t(const serializable_t&) = default; - serializable_t(serializable_t&&) = default; - serializable_t& operator=(const serializable_t&) = default; - serializable_t& operator=(serializable_t&&) = default; - ~serializable_t() = default; + 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& interpret(sqlpp::serializer& context) const { @@ -97,20 +97,20 @@ namespace sqlpp std::shared_ptr _impl; }; - } - template - struct interpreter_t> - { - using T = detail::serializable_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t> { - t.interpret(context); - return context; - } - }; + using T = interpretable_t; + static Context& _(const T& t, Context& context) + { + t.interpret(context); + return context; + } + }; + + } } #endif diff --git a/include/sqlpp11/detail/serializable_list.h b/include/sqlpp11/vendor/interpretable_list.h similarity index 57% rename from include/sqlpp11/detail/serializable_list.h rename to include/sqlpp11/vendor/interpretable_list.h index 215497ed..855951aa 100644 --- a/include/sqlpp11/detail/serializable_list.h +++ b/include/sqlpp11/vendor/interpretable_list.h @@ -24,22 +24,20 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_SERIALIZABLE_LIST_H -#define SQLPP_SERIALIZABLE_LIST_H +#ifndef SQLPP_INTERPRETABLE_LIST_H +#define SQLPP_INTERPRETABLE_LIST_H #include -#include +#include -// FIXME: Needs to leave detail namespace -// FIXME: serializable is not a very good name any more... namespace sqlpp { - namespace detail + namespace vendor { template - struct serializable_list + struct interpretable_list_t { - std::vector> _serializables; + std::vector> _serializables; std::size_t size() const { @@ -60,7 +58,7 @@ namespace sqlpp }; template<> - struct serializable_list + struct interpretable_list_t { template void emplace_back(const T&) {} @@ -77,49 +75,48 @@ namespace sqlpp }; - } - - template - struct serializable_list_interpreter_t - { - using T = List; - - template - static Context& _(const T& t, const Separator& separator, Context& context) + template + struct serializable_list_interpreter_t { - bool first = true; - for (const auto entry : t._serializables) - { - if (not first) + using T = List; + + template + static Context& _(const T& t, const Separator& separator, Context& context) { - context << separator; - first = false; + bool first = true; + for (const auto entry : t._serializables) + { + if (not first) + { + context << separator; + first = false; + } + interpret(t, context); + } + return context; } - interpret(t, context); - } - return context; - } - }; + }; - template - struct serializable_list_interpreter_t> - { - using T = detail::serializable_list; - - template - static Context& _(const T& t, const Separator& separator, Context& context) + template + struct serializable_list_interpreter_t> { - return context; + 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::type, typename std::decay::type>::_(t, separator, context)) + { + return serializable_list_interpreter_t::type, typename std::decay::type>::_(t, separator, context); } - }; - - template - auto interpret_serializable_list(const T& t, const Separator& separator, Context& context) - -> decltype(serializable_list_interpreter_t::type, typename std::decay::type>::_(t, separator, context)) - { - return serializable_list_interpreter_t::type, typename std::decay::type>::_(t, separator, context); - } + } } #endif diff --git a/include/sqlpp11/vendor/interpreter.h b/include/sqlpp11/vendor/interpreter.h new file mode 100644 index 00000000..37df5cd7 --- /dev/null +++ b/include/sqlpp11/vendor/interpreter.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_VENDOR_INTERPRET_H +#define SQLPP_VENDOR_INTERPRET_H + +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct interpreter_t + { + static void _(const T& t, Context& context) + { + static_assert(detail::wrong::value, "missing interpreter specialization"); + } + }; + } + +} + +#endif diff --git a/include/sqlpp11/is_null.h b/include/sqlpp11/vendor/is_null.h similarity index 85% rename from include/sqlpp11/is_null.h rename to include/sqlpp11/vendor/is_null.h index 9f5ea931..78b96deb 100644 --- a/include/sqlpp11/is_null.h +++ b/include/sqlpp11/vendor/is_null.h @@ -33,7 +33,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct is_null_t: public boolean::template operators> @@ -71,20 +71,20 @@ namespace sqlpp Operand _operand; }; - } - template - struct interpreter_t> - { - using T = detail::is_null_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t> { - interpret(t._operand, context); - context << (t._inverted ? " IS NOT NULL" : " IS NULL"); - return context; - } - }; + using T = ::sqlpp::vendor::is_null_t; + + static Context& _(const T& t, Context& context) + { + interpret(t._operand, context); + context << (t._inverted ? " IS NOT NULL" : " IS NULL"); + return context; + } + }; + } } diff --git a/include/sqlpp11/is_null_fwd.h b/include/sqlpp11/vendor/is_null_fwd.h similarity index 98% rename from include/sqlpp11/is_null_fwd.h rename to include/sqlpp11/vendor/is_null_fwd.h index 472ea58e..8ef3e8a4 100644 --- a/include/sqlpp11/is_null_fwd.h +++ b/include/sqlpp11/vendor/is_null_fwd.h @@ -29,7 +29,7 @@ namespace sqlpp { - namespace detail + namespace vendor { template struct is_null_t; diff --git a/include/sqlpp11/like.h b/include/sqlpp11/vendor/like.h similarity index 57% rename from include/sqlpp11/like.h rename to include/sqlpp11/vendor/like.h index 2b72b6be..08dba1f2 100644 --- a/include/sqlpp11/like.h +++ b/include/sqlpp11/vendor/like.h @@ -33,62 +33,64 @@ namespace sqlpp { - template - struct like_t: public boolean::template operators> + namespace vendor { - 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 _value_type: public boolean + template + struct like_t: public boolean::template operators> { - using _is_named_expression = std::true_type; - }; + 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(std::move(operand)), - _pattern(std::move(pattern)) - {} - - like_t(const Operand& operand, const 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; - }; - - template - struct interpreter_t> - { - using T = like_t; - - static Context& _(const T& t, Context& context) + struct _value_type: public boolean { + using _is_named_expression = std::true_type; + }; + + struct _name_t + { + static constexpr const char* _get_name() { return "LIKE"; } + template + struct _member_t + { + T like; + }; + }; + + like_t(Operand&& operand, Pattern&& pattern): + _operand(std::move(operand)), + _pattern(std::move(pattern)) + {} + + like_t(const Operand& operand, const 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; + }; + + template + struct interpreter_t> + { + using T = like_t; + + static Context& _(const T& t, Context& context) + { interpret(t._operand, context); context << " LIKE("; interpret(t._pattern, context); context << ")"; return context; - } - }; - + } + }; + } } #endif diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/vendor/limit.h similarity index 63% rename from include/sqlpp11/limit.h rename to include/sqlpp11/vendor/limit.h index d61a6691..fdee2700 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/vendor/limit.h @@ -33,53 +33,56 @@ namespace sqlpp { - template - struct limit_t + namespace vendor + { + template + struct limit_t + { + using _is_limit = std::true_type; + static_assert(is_integral_t::value, "limit requires an integral value or integral parameter"); + + Limit _limit; + }; + + template + struct interpreter_t> + { + using T = limit_t; + + static Context& _(const T& t, Context& context) + { + context << " LIMIT "; + interpret(t._limit, context); + return context; + } + }; + + struct dynamic_limit_t { using _is_limit = std::true_type; - static_assert(is_integral_t::value, "limit requires an integral value or integral parameter"); + using _is_dynamic = std::true_type; - Limit _limit; - }; - - template - struct interpreter_t> - { - using T = limit_t; - - static Context& _(const T& t, Context& context) + void set(std::size_t limit) { - context << " LIMIT "; - interpret(t._limit, context); - return context; + _limit = limit; } + + std::size_t _limit; }; - struct dynamic_limit_t - { - using _is_limit = std::true_type; - using _is_dynamic = std::true_type; - - void set(std::size_t limit) - { - _limit = limit; - } - - std::size_t _limit; - }; - - template - struct interpreter_t - { - using T = dynamic_limit_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t { - if (t._limit > 0) - context << " LIMIT " << t._limit; - return context; - } - }; + using T = dynamic_limit_t; + + static Context& _(const T& t, Context& context) + { + if (t._limit > 0) + context << " LIMIT " << t._limit; + return context; + } + }; + } } diff --git a/include/sqlpp11/detail/named_serializable.h b/include/sqlpp11/vendor/named_interpretable.h similarity index 81% rename from include/sqlpp11/detail/named_serializable.h rename to include/sqlpp11/vendor/named_interpretable.h index cb9dc3da..febea4db 100644 --- a/include/sqlpp11/detail/named_serializable.h +++ b/include/sqlpp11/vendor/named_interpretable.h @@ -33,23 +33,23 @@ namespace sqlpp { - namespace detail + namespace vendor { template - struct named_serializable_t + struct named_interpretable_t { using _context_t = typename Db::context; template - named_serializable_t(T t): + named_interpretable_t(T t): _impl(std::make_shared<_impl_t::type>>(t)) {} - named_serializable_t(const named_serializable_t&) = default; - named_serializable_t(named_serializable_t&&) = default; - named_serializable_t& operator=(const named_serializable_t&) = default; - named_serializable_t& operator=(named_serializable_t&&) = default; - ~named_serializable_t() = default; + 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& interpret(sqlpp::serializer& context) const { @@ -108,19 +108,19 @@ namespace sqlpp std::shared_ptr _impl; }; - } - template - struct interpreter_t> - { - using T = detail::named_serializable_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t> { - t.interpret(context); - return context; - } - }; + using T = named_interpretable_t; + + static Context& _(const T& t, Context& context) + { + t.interpret(context); + return context; + } + }; + } } diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/vendor/noop.h similarity index 82% rename from include/sqlpp11/noop.h rename to include/sqlpp11/vendor/noop.h index 09124887..603fa65f 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/vendor/noop.h @@ -28,26 +28,30 @@ #define SQLPP_NOOP_H #include +#include namespace sqlpp { - struct noop + namespace vendor { - }; - - template - struct interpreter_t + struct noop { - using T = noop; - - static Context& _(const T& t, Context& context) - { - return context; - } }; - template - struct is_noop: std::is_same {}; + template + struct interpreter_t + { + using T = noop; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + + template + struct is_noop: std::is_same {}; + } } #endif diff --git a/include/sqlpp11/noop_fwd.h b/include/sqlpp11/vendor/noop_fwd.h similarity index 94% rename from include/sqlpp11/noop_fwd.h rename to include/sqlpp11/vendor/noop_fwd.h index dccb845b..704cdc99 100644 --- a/include/sqlpp11/noop_fwd.h +++ b/include/sqlpp11/vendor/noop_fwd.h @@ -29,9 +29,12 @@ namespace sqlpp { - struct noop; + namespace vendor + { + struct noop; - template - struct is_noop; + template + struct is_noop; + } } #endif diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/vendor/offset.h similarity index 62% rename from include/sqlpp11/offset.h rename to include/sqlpp11/vendor/offset.h index 764778df..a7af759a 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/vendor/offset.h @@ -27,60 +27,61 @@ #ifndef SQLPP_OFFSET_H #define SQLPP_OFFSET_H -#include -#include #include namespace sqlpp { - template - struct offset_t + namespace vendor + { + template + struct offset_t + { + using _is_offset = std::true_type; + static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); + + Offset _offset; + }; + + template + struct interpreter_t> + { + using T = offset_t; + + static Context& _(const T& t, Context& context) + { + context << " OFFSET "; + interpret(t._offset, context); + return context; + } + }; + + struct dynamic_offset_t { using _is_offset = std::true_type; - static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); + using _is_dynamic = std::true_type; - Offset _offset; - }; - - template - struct interpreter_t> - { - using T = offset_t; - - static Context& _(const T& t, Context& context) + void set(std::size_t offset) { - context << " OFFSET "; - interpret(t._offset, context); - return context; + _offset = offset; } + + std::size_t _offset; }; - struct dynamic_offset_t - { - using _is_offset = std::true_type; - using _is_dynamic = std::true_type; - - void set(std::size_t offset) - { - _offset = offset; - } - - std::size_t _offset; - }; - - template - struct interpreter_t - { - using T = dynamic_offset_t; - - static Context& _(const T& t, Context& context) + template + struct interpreter_t { - if (t._offset > 0) - context << " OFFSET " << t._offset; - return context; - } - }; + using T = dynamic_offset_t; + static Context& _(const T& t, Context& context) + { + if (t._offset > 0) + context << " OFFSET " << t._offset; + return context; + } + }; + + } } #endif diff --git a/include/sqlpp11/vendor/order_by.h b/include/sqlpp11/vendor/order_by.h new file mode 100644 index 00000000..876d9173 --- /dev/null +++ b/include/sqlpp11/vendor/order_by.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_ORDER_BY_H +#define SQLPP_ORDER_BY_H + +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct order_by_t + { + using _is_order_by = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + // check for at least one order expression + static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()"); + + // check for duplicate order expressions + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in order_by()"); + + // check for invalid order expressions + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()"); + + template + void add(E&& expr) + { + static_assert(is_sort_order_t::type>::value, "order_by arguments require to be sort-order expressions"); + _dynamic_expressions.push_back(std::forward(expr)); + } + + _parameter_tuple_t _expressions; + vendor::interpretable_list_t _dynamic_expressions; + }; + + template + struct interpreter_t> + { + using T = order_by_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) + return context; + context << " ORDER BY "; + interpret_tuple(t._expressions, ',', context); + if (sizeof...(Expr) and not t._dynamic_expressions.empty()) + context << ','; + interpret_list(t._dynamic_expressions, ',', context); + return context; + } + }; + } +} + +#endif diff --git a/include/sqlpp11/vendor/select_expression_list.h b/include/sqlpp11/vendor/select_expression_list.h new file mode 100644 index 00000000..6a1c7545 --- /dev/null +++ b/include/sqlpp11/vendor/select_expression_list.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_SELECT_EXPRESSION_LIST_H +#define SQLPP_SELECT_EXPRESSION_LIST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + namespace detail + { + template + struct get_first_argument_if_unique + { + using _value_type = no_value_t; + struct _name_t {}; + }; + + template + struct get_first_argument_if_unique + { + using _value_type = typename T::_value_type; + using _name_t = typename T::_name_t; + }; + } + + namespace vendor + { + template + struct dynamic_select_expression_list + { + using _names_t = std::vector; + std::vector> _dynamic_expressions; + _names_t _dynamic_expression_names; + + template + void push_back(Expr&& expr) + { + _dynamic_expression_names.push_back(std::decay::type::_name_t::_get_name()); + _dynamic_expressions.emplace_back(std::forward(expr)); + } + + bool empty() const + { + return _dynamic_expressions.empty(); + } + }; + + template<> + struct dynamic_select_expression_list + { + struct _names_t {}; + _names_t _dynamic_expression_names; + + template + void push_back(const T&) {} + + static constexpr bool empty() + { + return true; + } + }; + + template + struct interpreter_t> + { + using T = dynamic_select_expression_list; + + static Context& _(const T& t, Context& context) + { + for (const auto column : t._dynamic_expressions) + { + interpret(column, context); + } + return context; + } + }; + + template + struct interpreter_t> + { + using T = dynamic_select_expression_list; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + + + template + struct select_expression_list_t + { + static_assert(::sqlpp::detail::wrong::value, "invalid template argument for select_expression_list"); + }; + + template + struct select_expression_list_t> + { + using _is_select_expression_list = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + // check for at least one expression + static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required"); + + // check for duplicate select expressions + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected"); + + // check for invalid select expressions + template + struct is_valid_expression_t: public std::integral_constant::value or is_multi_column_t::value> {}; + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression"); + + // check for duplicate select expression names + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate name detected"); + + // provide type information for sub-selects that are used as expressions + struct _column_type {}; + struct _value_type: ::sqlpp::detail::get_first_argument_if_unique::_value_type + { + using _is_expression = typename std::conditional::type; + using _is_named_expression = typename std::conditional::type; + using _is_alias = std::false_type; + }; + using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique::_name_t; + + 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_expression_list::_names_t; + + template + using _pseudo_table_t = select_pseudo_table_t; + + template + using _dynamic_t = select_expression_list_t>; + + template + void add(Expr&& namedExpr) + { + static_assert(is_named_expression_t::type>::value, "select() arguments require to be named expressions"); + static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list"); + _dynamic_expressions.push_back(std::forward(namedExpr)); + } + + _parameter_tuple_t _expressions; + dynamic_select_expression_list _dynamic_expressions; + }; + + template + struct interpreter_t> + { + using T = select_expression_list_t; + + static Context& _(const T& t, Context& context) + { + interpret_tuple(t._expressions, ',', context); + if (sizeof...(NamedExpr) and not t._dynamic_expressions.empty()) + context << ','; + interpret(t._dynamic_expressions, context); + return context; + } + }; + } +} + +#endif diff --git a/include/sqlpp11/select_flag_list.h b/include/sqlpp11/vendor/select_flag_list.h similarity index 64% rename from include/sqlpp11/select_flag_list.h rename to include/sqlpp11/vendor/select_flag_list.h index 666c78e4..63508674 100644 --- a/include/sqlpp11/select_flag_list.h +++ b/include/sqlpp11/vendor/select_flag_list.h @@ -30,9 +30,8 @@ #include #include #include -#include +#include #include -#include namespace sqlpp { @@ -47,7 +46,7 @@ namespace sqlpp static constexpr all_t all = {}; template - struct interpreter_t + struct vendor::interpreter_t { static Context& _(const all_t&, Context& context) { @@ -66,7 +65,7 @@ namespace sqlpp static constexpr distinct_t distinct = {}; template - struct interpreter_t + struct vendor::interpreter_t { static Context& _(const distinct_t&, Context& context) { @@ -85,7 +84,7 @@ namespace sqlpp static constexpr straight_join_t straight_join = {}; template - struct interpreter_t + struct vendor::interpreter_t { static Context& _(const straight_join_t&, Context& context) { @@ -94,36 +93,44 @@ namespace sqlpp } }; - // select_flag_list_t - template - struct select_flag_list_t> - { - // check for duplicate order expressions - static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in select flag list"); - - // check for invalid order expressions - using _valid_flags = typename detail::make_set_if::type; - static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list"); - - using _is_select_flag_list = std::true_type; - - std::tuple _flags; - }; - - template - struct interpreter_t>> - { - using T = select_flag_list_t>; - - static Context& _(const T& t, Context& context) + namespace vendor + { + template + struct select_flag_list_t { - interpret_tuple(t._flags, ' ', context); - if (sizeof...(Flag)) - context << ' '; - return context; - } - }; + static_assert(detail::wrong::value, "invalid argument for select_flag_list"); + }; + // select_flag_list_t + template + struct select_flag_list_t> + { + // check for duplicate order expressions + static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in select flag list"); + + // check for invalid order expressions + using _valid_flags = typename detail::make_set_if::type; + static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list"); + + using _is_select_flag_list = std::true_type; + + std::tuple _flags; + }; + + template + struct interpreter_t>> + { + using T = select_flag_list_t>; + + static Context& _(const T& t, Context& context) + { + interpret_tuple(t._flags, ' ', context); + if (sizeof...(Flag)) + context << ' '; + return context; + } + }; + } } diff --git a/include/sqlpp11/select_pseudo_table.h b/include/sqlpp11/vendor/select_pseudo_table.h similarity index 97% rename from include/sqlpp11/select_pseudo_table.h rename to include/sqlpp11/vendor/select_pseudo_table.h index 9389cb96..7c388699 100644 --- a/include/sqlpp11/select_pseudo_table.h +++ b/include/sqlpp11/vendor/select_pseudo_table.h @@ -71,7 +71,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct vendor::interpreter_t> { using T = select_pseudo_table_t; diff --git a/include/sqlpp11/vendor/update_list.h b/include/sqlpp11/vendor/update_list.h new file mode 100644 index 00000000..89b347d0 --- /dev/null +++ b/include/sqlpp11/vendor/update_list.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_UPDATE_LIST_H +#define SQLPP_UPDATE_LIST_H + +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct update_list_t + { + using _is_update_list = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + // check for at least one order expression + static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()"); + + // check for duplicate assignments + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); + + // check for invalid assignments + using _assignment_set = typename ::sqlpp::detail::make_set_if::type; + static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); + + // check for prohibited assignments + using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if::type; + static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); + + template + void add(Assignment&& assignment) + { + static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); + static_assert(not must_not_update_t::type::column_type>::value, "set() argument must not be updated"); + _dynamic_assignments.emplace_back(std::forward(assignment)); + } + + _parameter_tuple_t _assignments; + typename vendor::interpretable_list_t _dynamic_assignments; + }; + + template + struct interpreter_t> + { + using T = update_list_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 new file mode 100644 index 00000000..5a899809 --- /dev/null +++ b/include/sqlpp11/vendor/using.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_USING_H +#define SQLPP_USING_H + +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct using_t + { + using _is_using = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()"); + + // check for duplicate arguments + static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in using()"); + + // check for invalid arguments + using _valid_expressions = typename ::sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()"); + + + template + void add(T&& table) + { + static_assert(is_table_t::type>::value, "using() arguments require to be tables"); + _dynamic_tables.emplace_back(std::forward(table)); + } + + _parameter_tuple_t _tables; + vendor::interpretable_list_t _dynamic_tables; + }; + + template + struct interpreter_t> + { + using T = using_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(Table) == 0 and t._dynamic_tables.empty()) + return context; + context << " USING "; + interpret_tuple(t._tables, ',', context); + if (sizeof...(Table) and not t._dynamic_tables.empty()) + context << ','; + interpret_list(t._dynamic_tables, ',', context); + return context; + } + }; + } +} + +#endif diff --git a/include/sqlpp11/where.h b/include/sqlpp11/vendor/where.h similarity index 55% rename from include/sqlpp11/where.h rename to include/sqlpp11/vendor/where.h index df927fa3..f9251f2b 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/vendor/where.h @@ -29,57 +29,60 @@ #include #include -#include +#include #include #include -#include -#include +#include +#include #include namespace sqlpp { - template - struct where_t - { - using _is_where = std::true_type; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; - - static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()"); - using _valid_expressions = typename detail::make_set_if::type; - static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()"); - - using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; - - template - void add(E&& expr) - { - static_assert(is_expression_t::type>::value, "invalid expression argument in add_where()"); - _dynamic_expressions.emplace_back(std::forward(expr)); - } - - _parameter_tuple_t _expressions; - detail::serializable_list _dynamic_expressions; - }; - - template - struct interpreter_t> - { - using T = where_t; - - static Context& _(const T& t, Context& context) + namespace vendor + { + template + struct where_t { + using _is_where = std::true_type; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; + + static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()"); + using _valid_expressions = typename sqlpp::detail::make_set_if::type; + static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()"); + + using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; + + template + void add(E&& expr) + { + static_assert(is_expression_t::type>::value, "invalid expression argument in add_where()"); + _dynamic_expressions.emplace_back(std::forward(expr)); + } + + _parameter_tuple_t _expressions; + vendor::interpretable_list_t _dynamic_expressions; + }; + + template + struct interpreter_t> + { + using T = where_t; + + static Context& _(const T& t, Context& context) + { if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) return context; context << " WHERE "; interpret_tuple(t._expressions, " AND ", context); if (sizeof...(Expr) and not t._dynamic_expressions.empty()) context << " AND "; - interpret_serializable_list(t._dynamic_expressions, " AND ", context); + interpret_list(t._dynamic_expressions, " AND ", context); return context; - } - }; + } + }; + } } #endif diff --git a/include/sqlpp11/vendor/wrap_operand.h b/include/sqlpp11/vendor/wrap_operand.h new file mode 100644 index 00000000..96edd920 --- /dev/null +++ b/include/sqlpp11/vendor/wrap_operand.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_DETAIL_WRAP_OPERAND_H +#define SQLPP_DETAIL_WRAP_OPERAND_H + +#include +#include + +namespace sqlpp +{ + namespace detail + { + struct boolean; + struct integral; + struct floating_point; + struct text; + } + + namespace vendor + { + struct boolean_operand + { + static constexpr bool _is_expression = true; + using _value_type = detail::boolean; + + bool _is_trivial() const { return _t == false; } + + bool _t; + }; + + template + struct interpreter_t + { + using Operand = boolean_operand; + + static Context& _(const Operand& t, Context& context) + { + context << t._t; + return context; + } + }; + + template + struct integral_operand + { + static constexpr bool _is_expression = true; + using _value_type = detail::integral; + + bool _is_trivial() const { return _t == 0; } + + T _t; + }; + + template + struct interpreter_t> + { + using Operand = integral_operand; + + static Context& _(const Operand& t, Context& context) + { + context << t._t; + return context; + } + }; + + + template + struct floating_point_operand + { + static constexpr bool _is_expression = true; + using _value_type = detail::floating_point; + + bool _is_trivial() const { return _t == 0; } + + T _t; + }; + + template + struct interpreter_t> + { + using Operand = floating_point_operand; + + static Context& _(const Operand& t, Context& context) + { + context << t._t; + return context; + } + }; + + struct text_operand + { + static constexpr bool _is_expression = true; + using _value_type = detail::text; + + bool _is_trivial() const { return _t.empty(); } + + std::string _t; + }; + + template + struct interpreter_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; + }; + } +} + +#endif diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index 67851a7f..f5c47182 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -66,7 +66,7 @@ namespace sqlpp }; template - struct interpreter_t + struct vendor::interpreter_t { using T = verbatim_table_t; diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index ebd6b2f2..298524d3 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -25,6 +25,7 @@ #include "TabSample.h" #include "MockDb.h" +#include #include #include #include @@ -35,7 +36,7 @@ DbMock db = {}; DbMock::context printer(std::cerr); -SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen); +SQLPP_ALIAS_PROVIDER(kaesekuchen); int main() { @@ -61,6 +62,7 @@ int main() interpret(parameter(t.alpha), printer).flush(); interpret(t.alpha == parameter(t.alpha), printer).flush(); + interpret(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).flush(); interpret(insert_into(t), printer).flush(); interpret(insert_into(t).default_values(), printer).flush(); @@ -76,7 +78,7 @@ int main() interpret(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush(); // functions - interpret(sqlpp::value(7), printer).flush(); + sqlpp::interpret(sqlpp::value(7), printer).flush(); // FIXME: Why is the namespace specifier required? interpret(sqlpp::verbatim("irgendwas integrales"), printer).flush(); interpret(sqlpp::value_list(std::vector({1,2,3,4,5,6,8})), printer).flush(); interpret(exists(select(t.alpha).from(t)), printer).flush(); @@ -107,6 +109,5 @@ int main() // dynamic select interpret(dynamic_select(db, t.alpha).dynamic_columns().add_column(t.beta), printer).flush(); - return 0; }