From f6ae27b0fe18f288dee803d209f7d5d68c382022 Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 17 Aug 2014 20:45:27 +0200 Subject: [PATCH 1/5] Made "where" non-mandatory if there are no tables involved. --- include/sqlpp11/where.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index cd2b924b..dfcf0260 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -181,7 +181,7 @@ namespace sqlpp }; // NO WHERE YET - template + template struct no_where_t { using _traits = make_traits; @@ -224,7 +224,9 @@ namespace sqlpp static void _check_consistency() { - static_assert(Required ? wrong_t<_methods_t>::value : true, "where expression required, e.g. where(true)"); + static constexpr bool _tables_provided = (Policies::_all_provided_tables::size::value > 0); + static constexpr bool _required = WhereRequired and _tables_provided; + static_assert(not _required, "where expression required, e.g. where(true)"); } template From d0d5e94bf193f1edc00c0200a847973b20b3bc33 Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 18 Aug 2014 10:46:24 +0200 Subject: [PATCH 2/5] Added eval function for both strings and expressions. eval wraps whatever you give to it into a select call, sends it to the database and returns the value as a result field. --- include/sqlpp11/eval.h | 62 ++++++++++++++++++++++++++++ include/sqlpp11/functions.h | 42 ++----------------- include/sqlpp11/result_field.h | 2 +- include/sqlpp11/verbatim.h | 75 ++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 40 deletions(-) create mode 100644 include/sqlpp11/eval.h create mode 100644 include/sqlpp11/verbatim.h diff --git a/include/sqlpp11/eval.h b/include/sqlpp11/eval.h new file mode 100644 index 00000000..116b19f0 --- /dev/null +++ b/include/sqlpp11/eval.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_EVAL_H +#define SQLPP_EVAL_H + +#include +#include +#include +#include + +namespace sqlpp +{ + template + struct eval_t + { + static_assert(is_database::value, "Db parameter of eval has to be a database connection"); + static_assert(is_expression_t::value, "Expression parameter of eval has to be an sqlpp expression or a string"); + static_assert(required_tables_of::size::value == 0, "Expression cannot be used in eval because it requires tables"); + using _name_type = alias::a_t::_name_t; + using _value_type = value_type_of; + using _field_spec = field_spec_t<_name_type, _value_type, true, false>; + using type = result_field_t<_value_type, Db, _field_spec>; + }; + + template::value, int>::type = 0> + auto eval(Db& db, Expr expr) -> typename eval_t::type + { + return db(select(expr.as(alias::a))).front().a; + } + + template + auto eval(Db& db, std::string sql_code) -> decltype(eval(db, verbatim(sql_code))) + { + return eval(db, verbatim(sql_code)); + } +} + +#endif diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 65fabab0..ca32b9b4 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -41,8 +41,10 @@ #include #include #include -#include // Csaba Csoma suggests: unsafe_sql instead of verbatim +#include // Csaba Csoma suggests: unsafe_sql instead of verbatim +#include #include +#include namespace sqlpp { @@ -53,44 +55,6 @@ namespace sqlpp return { t }; } - template // Csaba Csoma suggests: unsafe_sql instead of verbatim - struct verbatim_t: public ValueType::template expression_operators>, - public alias_operators> - { - using _traits = make_traits; - struct _recursive_traits : public make_recursive_traits<> - { - using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null - }; - - verbatim_t(std::string verbatim): _verbatim(verbatim) {} - verbatim_t(const verbatim_t&) = default; - verbatim_t(verbatim_t&&) = default; - verbatim_t& operator=(const verbatim_t&) = default; - verbatim_t& operator=(verbatim_t&&) = default; - ~verbatim_t() = default; - - std::string _verbatim; - }; - - template - struct serializer_t> - { - using T = verbatim_t; - - static Context& _(const T& t, Context& context) - { - context << t._verbatim; - return context; - } - }; - - template - auto verbatim(StringType s) -> verbatim_t - { - return { s }; - } - template auto flatten(const Expression& exp, Db& db) -> verbatim_t> { diff --git a/include/sqlpp11/result_field.h b/include/sqlpp11/result_field.h index e78b3938..476ca3ea 100644 --- a/include/sqlpp11/result_field.h +++ b/include/sqlpp11/result_field.h @@ -32,7 +32,7 @@ namespace sqlpp { - template + template struct result_field_t { static_assert(wrong_t::value, "Missing specialization for result_field_t"); diff --git a/include/sqlpp11/verbatim.h b/include/sqlpp11/verbatim.h new file mode 100644 index 00000000..a148519b --- /dev/null +++ b/include/sqlpp11/verbatim.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_VERBATIM_H +#define SQLPP_VERBATIM_H + +#include +#include + +namespace sqlpp +{ + template // Csaba Csoma suggests: unsafe_sql instead of verbatim + struct verbatim_t: public ValueType::template expression_operators>, + public alias_operators> + { + using _traits = make_traits; + struct _recursive_traits : public make_recursive_traits<> + { + using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null + }; + + verbatim_t(std::string verbatim): _verbatim(verbatim) {} + verbatim_t(const verbatim_t&) = default; + verbatim_t(verbatim_t&&) = default; + verbatim_t& operator=(const verbatim_t&) = default; + verbatim_t& operator=(verbatim_t&&) = default; + ~verbatim_t() = default; + + std::string _verbatim; + }; + + template + struct serializer_t> + { + using T = verbatim_t; + + static Context& _(const T& t, Context& context) + { + context << t._verbatim; + return context; + } + }; + + template + auto verbatim(StringType s) -> verbatim_t + { + return { s }; + } + +} + +#endif From 13c1b5d8f3da48cad2e81edb01457c3be1a64286 Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 18 Aug 2014 15:09:27 +0200 Subject: [PATCH 3/5] Fix to make sqlpp11 compile with clang-3.1 --- include/sqlpp11/select_column_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index f986a6fd..b2609987 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -310,7 +310,7 @@ namespace sqlpp { _statement_t::_check_consistency(); - return {{}, get_dynamic_names(), db.prepare_select(_get_statement())}; + return {make_parameter_list_t<_statement_t>{}, get_dynamic_names(), db.prepare_select(_get_statement())}; } }; From f859f7fe4a95d4261c9a526d4ad9eb6410a80220 Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 18 Aug 2014 19:17:59 +0200 Subject: [PATCH 4/5] Added must_not_update-test --- test_constraints/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_constraints/CMakeLists.txt b/test_constraints/CMakeLists.txt index bdb60f10..6b4693d5 100644 --- a/test_constraints/CMakeLists.txt +++ b/test_constraints/CMakeLists.txt @@ -22,10 +22,10 @@ function(test_constraint name pattern) add_dependencies(test_sqlpp_constraints test_${name}) -endfunction(testconstraint) - +endfunction(test_constraint) test_constraint(no_conversion_operator_if_null_not_trivial "int i = row.alpha") test_constraint(require_insert "required column is missing") test_constraint(must_not_insert "one assignment is prohibited") +test_constraint(must_not_update "one assignment is prohibited") From e5e97d10b66fa6e8dcb3ee12303d6a2dd8cb559d Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 18 Aug 2014 21:10:58 +0200 Subject: [PATCH 5/5] Added alias operators to wrapped value operands --- include/sqlpp11/basic_expression_operators.h | 2 +- include/sqlpp11/wrap_operand.h | 17 ++++----- include/sqlpp11/wrap_operand_fwd.h | 40 ++++++++++++++++++++ tests/SelectTest.cpp | 2 + 4 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 include/sqlpp11/wrap_operand_fwd.h diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index 710ea844..fc54a876 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include namespace sqlpp diff --git a/include/sqlpp11/wrap_operand.h b/include/sqlpp11/wrap_operand.h index ffab6e94..f4b28022 100644 --- a/include/sqlpp11/wrap_operand.h +++ b/include/sqlpp11/wrap_operand.h @@ -28,8 +28,10 @@ #define SQLPP_DETAIL_WRAP_OPERAND_H #include +#include #include #include +#include namespace sqlpp { @@ -38,7 +40,7 @@ namespace sqlpp struct floating_point; struct text; - struct boolean_operand + struct boolean_operand: public alias_operators { using _traits = make_traits<::sqlpp::boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>; using _recursive_traits = make_recursive_traits<>; @@ -76,7 +78,7 @@ namespace sqlpp } }; - struct integral_operand + struct integral_operand: public alias_operators { using _traits = make_traits<::sqlpp::integral, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>; using _recursive_traits = make_recursive_traits<>; @@ -115,7 +117,7 @@ namespace sqlpp }; - struct floating_point_operand + struct floating_point_operand: public alias_operators { using _traits = make_traits<::sqlpp::floating_point, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>; using _recursive_traits = make_recursive_traits<>; @@ -153,7 +155,7 @@ namespace sqlpp } }; - struct text_operand + struct text_operand: public alias_operators { using _traits = make_traits<::sqlpp::text, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_wrapped_value>; using _recursive_traits = make_recursive_traits<>; @@ -191,7 +193,7 @@ namespace sqlpp } }; - template + template struct wrap_operand { using type = T; @@ -221,11 +223,6 @@ namespace sqlpp using type = text_operand; }; - // FIXME: Need to allow std::ref arguments - - template - using wrap_operand_t = typename wrap_operand::type; - } #endif diff --git a/include/sqlpp11/wrap_operand_fwd.h b/include/sqlpp11/wrap_operand_fwd.h new file mode 100644 index 00000000..f7f60def --- /dev/null +++ b/include/sqlpp11/wrap_operand_fwd.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_DETAIL_WRAP_OPERAND_FWD_H +#define SQLPP_DETAIL_WRAP_OPERAND_FWD_H + +namespace sqlpp +{ + template + struct wrap_operand; + + template + using wrap_operand_t = typename wrap_operand::type; + +} + +#endif diff --git a/tests/SelectTest.cpp b/tests/SelectTest.cpp index 1e97562c..9fd040af 100644 --- a/tests/SelectTest.cpp +++ b/tests/SelectTest.cpp @@ -92,5 +92,7 @@ int main() printer.reset(); std::cerr << serialize(stat, printer).str() << std::endl; + select(sqlpp::value(7).as(t.alpha)); + return 0; }