diff --git a/include/sqlpp11/custom_query.h b/include/sqlpp11/custom_query.h index 61a3b459..662891dd 100644 --- a/include/sqlpp11/custom_query.h +++ b/include/sqlpp11/custom_query.h @@ -29,6 +29,7 @@ #include #include +#include #include namespace sqlpp @@ -59,6 +60,10 @@ namespace sqlpp _parts(parts...) {} + custom_query_t(std::tuple parts): + _parts(parts) + {} + custom_query_t(const custom_query_t&) = default; custom_query_t(custom_query_t&&) = default; custom_query_t& operator=(const custom_query_t&) = default; @@ -89,6 +94,13 @@ namespace sqlpp return _get_static_no_of_parameters(); } + template + auto with_result_type_of(Part part) + -> custom_query_t + { + return {tuple_cat(std::make_tuple(part), _parts)}; + } + std::tuple _parts; }; diff --git a/include/sqlpp11/hidden.h b/include/sqlpp11/hidden.h new file mode 100644 index 00000000..e9f98cfa --- /dev/null +++ b/include/sqlpp11/hidden.h @@ -0,0 +1,65 @@ +/* + * 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_HIDDEN_H +#define SQLPP_HIDDEN_H + +namespace sqlpp +{ + template + struct hidden_t: + public Part + { + hidden_t(Part part): + Part(part) + {} + + hidden_t(const hidden_t&) = default; + hidden_t(hidden_t&&) = default; + hidden_t& operator=(const hidden_t&) = default; + hidden_t& operator=(hidden_t&&) = default; + ~hidden_t() = default; + }; + + template + struct serializer_t> + { + using T = hidden_t; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + + template + auto hidden(Part part) + -> hidden_t + { + return {part}; + } +} +#endif diff --git a/include/sqlpp11/prepared_execute.h b/include/sqlpp11/prepared_execute.h index a72577ad..e181d37c 100644 --- a/include/sqlpp11/prepared_execute.h +++ b/include/sqlpp11/prepared_execute.h @@ -39,7 +39,7 @@ namespace sqlpp using _prepared_statement_t = typename Db::_prepared_statement_t; auto _run(Db& db) const - -> size_t + -> void { return db.run_prepared_execute(*this); } diff --git a/tests/CustomQueryTest.cpp b/tests/CustomQueryTest.cpp index b5635f37..96870380 100644 --- a/tests/CustomQueryTest.cpp +++ b/tests/CustomQueryTest.cpp @@ -37,19 +37,31 @@ int main() test::TabFoo f; test::TabBar t; - auto c = custom_query(select(all_of(t)).from(t), into(f)); - std::cerr << serialize(c, printer).str() << std::endl; - db(c); - - auto p = db.prepare(custom_query(select(all_of(t)).from(t), where(t.alpha > sqlpp::parameter(t.alpha)))); - p.params.alpha = 8; - + // A void custom query printer.reset(); auto x = custom_query(sqlpp::verbatim("PRAGMA writeable_schema = "), true); std::cerr << serialize(x, printer).str() << std::endl; db(x); - db.run_prepared_execute(db.prepare(x)); + // Syntactically, it is possible to use this void query as a prepared statement, too, not sure, whether this makes sense very often... + db(db.prepare(x)); + + // A prepared custom select + // The return type of the custom query is determined from the first argument which does have a return type, in this case the select + auto p = db.prepare(custom_query(select(all_of(t)).from(t), where(t.alpha > sqlpp::parameter(t.alpha)))); + p.params.alpha = 8; + for (const auto& row : db(p)) + { + std::cerr << row.alpha << std::endl; + } + + // A custom (select ... into) with adjusted return type + // The first argument with a return type is the select, but the custom query is really an insert. Thus, we tell it so. + printer.reset(); + auto c = custom_query(select(all_of(t)).from(t), into(f)).with_result_type_of(insert_into(f)); + std::cerr << serialize(c, printer).str() << std::endl; + auto i = db(c); + static_assert(std::is_integral::value, "insert yields an integral value"); return 0; }