From 0db405c28c65efda216826d8aa6b1b60e4a528c3 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Thu, 19 Sep 2013 09:04:07 +0200 Subject: [PATCH] Rewrote like() member function, added more type control to concat() --- include/sqlpp11/concat.h | 25 +++++------ include/sqlpp11/like.h | 95 ++++++++++++++++++++++++++++++++++++++++ include/sqlpp11/text.h | 13 ++---- tests/SelectTest.cpp | 1 + 4 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 include/sqlpp11/like.h diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/concat.h index 5557e99f..0070b6dd 100644 --- a/include/sqlpp11/concat.h +++ b/include/sqlpp11/concat.h @@ -28,22 +28,21 @@ #define SQLPP_CONCAT_H #include -#include +#include #include namespace sqlpp { namespace detail { - struct text; - - template - struct concat_t: public Text::template operators> + template + struct concat_t: public First::_value_type::template operators> { - using _valid_args = typename detail::make_set_if_not::type; + static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); + using _valid_args = typename detail::make_set_if_not::type; static_assert(_valid_args::size::value == 0, "at least one non-text argument detected in concat()"); - using _value_type = Text; + using _value_type = typename First::_value_type::_base_value_type; struct _name_t { static constexpr const char* _get_name() { return "CONCAT"; } @@ -54,12 +53,12 @@ namespace sqlpp }; }; - concat_t(Args&&... args): - _args(std::move(args)...) + concat_t(First&& first, Args&&... args): + _args(std::move(first), std::move(args)...) {} - concat_t(const Args&... args): - _args(args...) + concat_t(const First& first, const Args&... args): + _args(first, args...) {} concat_t(const concat_t&) = default; @@ -77,12 +76,12 @@ namespace sqlpp } private: - std::tuple _args; + std::tuple _args; }; } template - auto concat(T&&... t) -> typename detail::concat_t::type...>::type + auto concat(T&&... t) -> typename detail::concat_t::type...> { return { std::forward(t)... }; } diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h new file mode 100644 index 00000000..6551e71d --- /dev/null +++ b/include/sqlpp11/like.h @@ -0,0 +1,95 @@ +/* + * 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_LIKE_H +#define SQLPP_LIKE_H + +#include +#include +#include + +namespace sqlpp +{ + namespace detail + { + struct text; + + template + struct like_t: public Operand::_value_type::template operators> + { + 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"); + + using _value_type = typename Operand::_value_type::_base_value_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; + + template + void serialize(std::ostream& os, Db& db) const + { + _operand.serialize(os, db); + os << " LIKE("; + _pattern.serialize(os, db); + os << ")"; + } + + private: + Operand _operand; + Pattern _pattern; + }; + } + + template + auto like(T&&... t) -> typename detail::like_t::type...> + { + return { std::forward(t)... }; + } +} + +#endif diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index c5c7959d..b172b1e1 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -33,19 +33,12 @@ #include #include #include +#include namespace sqlpp { namespace detail { - struct text; - - struct like_ - { - using _value_type = boolean; - static constexpr const char* _name = "LIKE"; - }; - // text value type struct text { @@ -111,13 +104,13 @@ namespace sqlpp struct operators: public basic_operators { template - detail::concat_t::type> operator+(T&& t) const + detail::concat_t::type> operator+(T&& t) const { return { *static_cast(this), std::forward(t) }; } template - nary_member_function_t::type> like(T&& t) const + detail::like_t::type> like(T&& t) const { return { *static_cast(this), std::forward(t) }; } diff --git a/tests/SelectTest.cpp b/tests/SelectTest.cpp index 9d4fb378..a0c4f4e2 100644 --- a/tests/SelectTest.cpp +++ b/tests/SelectTest.cpp @@ -276,6 +276,7 @@ int main() !t.gamma; t.beta < "kaesekuchen"; (t.beta + "hallenhalma").serialize(std::cerr, db); + concat(t.beta, "hallenhalma").serialize(std::cerr, db); static_assert(sqlpp::must_not_insert_t::value, "alpha must not be inserted"); t.alpha.serialize(std::cerr, db); std::cerr << "\n" << sizeof(TabSample) << std::endl;