diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..39ee5821 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: cpp + +os: + - linux + +compiler: + # - clang # disabled clang due to missing libc++ + - gcc + +notifications: + email: + on_success: change + on_failure: always + +before_install: + - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + - sudo apt-get update + - if [ "$CXX" = "g++" ]; then sudo apt-get install g++-4.8; fi + - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi + + +install: + - "mkdir -p $TRAVIS_BUILD_DIR/build/scripts" + - "cd $TRAVIS_BUILD_DIR/build/scripts" + - "cmake $TRAVIS_BUILD_DIR" + +script: + - "cd $TRAVIS_BUILD_DIR/build/scripts" + - "make -j3" + # test compile-time constraints + - "make test_sqlpp_constraints" + diff --git a/CMakeLists.txt b/CMakeLists.txt index 32fd43cc..b1116b7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,10 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cmake_minimum_required(VERSION 2.6) + +# Cygwin does not define WIN32 and warn if not use with this flag +set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required + project (sqlpp11) enable_testing() @@ -34,10 +38,11 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") endif () set(include_dir "${PROJECT_SOURCE_DIR}/include") -file(GLOB_RECURSE sqlpp_headers ${include_dir}/*.h) -include_directories(${include_dir}) +file(GLOB_RECURSE sqlpp_headers "${include_dir}/*.h") +include_directories("${include_dir}") add_subdirectory(tests) add_subdirectory(test_constraints) +add_subdirectory(examples) install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/sqlpp11" DESTINATION include) diff --git a/CREDITS b/CREDITS index 6ad7db8e..3675cef0 100644 --- a/CREDITS +++ b/CREDITS @@ -7,8 +7,12 @@ This library evolved through several stages and would probably not exist without * Peter Knoblach: Initial ideas * Ulrich Küttler: Feedback and extensions + * Metafeed GmbH: Production code using a forerunner version * PPRO Financial Ltd: Production code using sqlpp11 and a forerunner version + * The boost community: Invaluable suggestions and critiques + + * Meeting C++ Munich: Hosted the first talk about sqlpp11 If you miss your name of this list, please let me know. diff --git a/README.md b/README.md index f25797ba..7e3020ed 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,11 @@ A type safe embedded domain specific language for SQL queries and results in C++ Extensive documentation is found in the wiki, https://github.com/rbock/sqlpp11/wiki -Upcoming talks at +Upcoming talks/workshops) at * CppCon (Bellevue, Washington, USA): http://cppcon.org - * 2014-09-11: http://sched.co/1r4lue3 + * 2014-09-08: http://sched.co/1qhngYK (Workshop Part 1) + * 2014-09-11: http://sched.co/1r4lue3 (Talk) + * 2014-09-12: http://sched.co/Wi8aWM (Workshop Part 2) * MeetingC++ (Berlin, Germany): http://meetingcpp.com/index.php/mcpp2014.html * 2014-12-05:http://meetingcpp.com/index.php/tv14/items/4.html @@ -105,6 +107,7 @@ sqlpp11 makes heavy use of C++11 and requires a recent compiler and STL. The fol * clang-3.2 on Ubuntu-12.4 * clang-3.4 on Ubuntu-12.4 * g++-4.8 on Ubuntu-12.4 + * g++-4.8 on cygwin 64bit * g++-4.9 on Debian Unstable __Database Connector:__ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..1ab2fd65 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,22 @@ + +macro (build arg) + # Add headers to sources to enable file browsing in IDEs + include_directories("${CMAKE_SOURCE_DIR}/tests") + add_executable("Sqlpp11Example${arg}" "${arg}.cpp" ${sqlpp_headers} "${CMAKE_SOURCE_DIR}/tests/MockDb.h" "${CMAKE_CURRENT_LIST_DIR}/Sample.h") + add_test("${arg}" "${arg}") +endmacro () + +#build(sample) +build(insert) +build(update) +build(remove) +build(select) + +#find_package(PythonInterp REQUIRED) + +#add_custom_command( +# OUTPUT ${CMAKE_CURRENT_LIST_DIR}/Sample.h +# COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/ddl2cpp ${CMAKE_CURRENT_LIST_DIR}/sample.sql Sample test +# DEPENDS ${CMAKE_CURRENT_LIST_DIR}/sample.sql +# ) + diff --git a/examples/Sample.h b/examples/Sample.h new file mode 100644 index 00000000..43aa3dc2 --- /dev/null +++ b/examples/Sample.h @@ -0,0 +1,142 @@ +#ifndef TEST_SAMPLE_H +#define TEST_SAMPLE_H + +#include +#include + +namespace test +{ + namespace TabPerson_ + { + struct Id + { + struct _name_t + { + static constexpr const char* _get_name() { return "id"; } + template + struct _member_t + { + T id; + T& operator()() { return id; } + const T& operator()() const { return id; } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct Name + { + 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; } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct Feature + { + struct _name_t + { + static constexpr const char* _get_name() { return "feature"; } + template + struct _member_t + { + T feature; + T& operator()() { return feature; } + const T& operator()() const { return feature; } + }; + }; + using _traits = sqlpp::make_traits; + }; + } + + struct TabPerson: sqlpp::table_t + { + struct _name_t + { + static constexpr const char* _get_name() { return "tab_person"; } + template + struct _member_t + { + T tabPerson; + T& operator()() { return tabPerson; } + const T& operator()() const { return tabPerson; } + }; + }; + }; + namespace TabFeature_ + { + struct Id + { + struct _name_t + { + static constexpr const char* _get_name() { return "id"; } + template + struct _member_t + { + T id; + T& operator()() { return id; } + const T& operator()() const { return id; } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct Name + { + 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; } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct Fatal + { + struct _name_t + { + static constexpr const char* _get_name() { return "fatal"; } + template + struct _member_t + { + T fatal; + T& operator()() { return fatal; } + const T& operator()() const { return fatal; } + }; + }; + using _traits = sqlpp::make_traits; + }; + } + + struct TabFeature: sqlpp::table_t + { + struct _name_t + { + static constexpr const char* _get_name() { return "tab_feature"; } + template + struct _member_t + { + T tabFeature; + T& operator()() { return tabFeature; } + const T& operator()() const { return tabFeature; } + }; + }; + }; +} +#endif diff --git a/examples/TabSample.h b/examples/TabSample.h new file mode 100644 index 00000000..377f9c2f --- /dev/null +++ b/examples/TabSample.h @@ -0,0 +1,177 @@ +/* + * 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_TAB_SAMPLE_H +#define SQLPP_TAB_SAMPLE_H + +#include +#include + + +namespace TabFoo_ +{ + struct Omega + { + struct _name_t + { + static constexpr const char* _get_name() { return "omega"; } + }; + template + struct _member_t + { + /* + template + _name_t(TT&&... t): omega(std::forward(t)...) {} + + template + _name_t& operator=(TT&& t) { omega = std::forward(t); return *this; } + */ + + T omega; + }; + using _value_type = sqlpp::bigint; + struct _column_type + { + }; + }; +} + +struct TabFoo: sqlpp::table_base_t< + TabFoo, + TabFoo_::Omega + > +{ + using _value_type = sqlpp::no_value_t; + struct _name_t + { + static constexpr const char* _get_name() { return "tab_foo"; } + }; + template + struct _member_t + { + T tabFoo; + }; + template + void serialize(std::ostream& os, Db& db) const + { + os << _name_t::_get_name(); + } +}; + +namespace TabSample_ +{ + struct Alpha + { + struct _name_t + { + static constexpr const char* _get_name() { return "alpha"; } + }; + template + struct _member_t + { + /* + template + _name_t(TT&&... t): alpha(std::forward(t)...) {} + + template + _name_t& operator=(TT&& t) { alpha = std::forward(t); return *this; } + */ + + T alpha; + }; + using _value_type = sqlpp::bigint; + struct _column_type + { + using _must_not_insert = sqlpp::tag_yes; + using _must_not_update = sqlpp::tag_yes; + using _can_be_null = sqlpp::tag_yes; + using _foreign_key = decltype(TabFoo::omega); + }; + }; + + struct Beta + { + struct _name_t + { + static constexpr const char* _get_name() { return "beta"; } + }; + template + struct _member_t + { + T beta; + }; + using _value_type = sqlpp::varchar; + struct _column_type + { + using _can_be_null = sqlpp::tag_yes; + using _must_not_update = sqlpp::tag_yes; + }; + }; + + struct Gamma + { + struct _name_t + { + static constexpr const char* _get_name() { return "gamma"; } + }; + template + struct _member_t + { + T gamma; + }; + using _value_type = sqlpp::boolean; + struct _column_type + { + using _require_insert = sqlpp::tag_yes; + }; + }; +} + +struct TabSample: sqlpp::table_base_t< + TabSample, + TabSample_::Alpha, + TabSample_::Beta, + TabSample_::Gamma + > +{ + using _value_type = sqlpp::no_value_t; + struct _name_t + { + static constexpr const char* _get_name() { return "tab_sample"; } + }; + template + struct _member_t + { + T tabSample; + }; + template + void serialize(std::ostream& os, Db& db) const + { + os << _name_t::_get_name(); + } +}; + +#endif diff --git a/examples/insert.cpp b/examples/insert.cpp new file mode 100644 index 00000000..5c79d5f9 --- /dev/null +++ b/examples/insert.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include + +MockDb db; + +test::TabPerson p; +test::TabFeature f; + +int main() +{ + db(insert_into(f).set(f.name = "loves c++", f.fatal = false)); + + //db(insert_into(f).set(f.nahme = "loves c++", f.fatal = false)); + + //db(insert_into(f).set(f.name == "loves c++", f.fatal = false)); + + //db(insert_into(f).set(f.name = "loves c++", f.fatal = "false")); + + //db(insert_into(p).set(f.name = "loves c++", f.fatal = false)); + + //db(insert_into(f).set(f.name = "loves c++", p.feature = 7)); + + //db(insert_into(f).set(f.id = 42, f.name = "loves c++", f.fatal = false)); + + //db(insert_into(f).set(f.name = "loves c++")); + + + db(insert_into(f).default_values()); + + auto i = insert_into(p).columns(p.name, p.feature); + i.values.add(p.name = "Roland", p.feature = 1); + i.values.add(p.name = "Zaphod", p.feature = sqlpp::default_value); + db(i); + + + auto pi = db.prepare(insert_into(p).set(p.name = parameter(f.name), p.feature = parameter(p.feature))); + pi.params.name = "likes java"; + pi.params.feature = true; + + db(pi); +} diff --git a/examples/remove.cpp b/examples/remove.cpp new file mode 100644 index 00000000..49b93799 --- /dev/null +++ b/examples/remove.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include + +MockDb db; + +test::TabPerson p; +test::TabFeature q; + +int main() +{ + db(remove_from(p) + .using_(p, q) + .where(p.feature == q.id and q.fatal == true)); +} diff --git a/examples/sample.cpp b/examples/sample.cpp new file mode 100644 index 00000000..5328df05 --- /dev/null +++ b/examples/sample.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include + +MockDb db; + +test::TabPerson p; +test::TabFeature f; + +int main() +{ + db(insert_into(f).set(f.name = "Loves C++", p.fatal = false)); + + db(insert_into(f).set(p.name = "Roland", p.feature = 1)); + + auto s = select(all_of(p)) + .from(p, q) + .where(p.name == any(select(q.name) + .from(q) + .where(true))) + .group_by(q.name) + .having(p.name.like("%Bee%")) + .order_by(p.name.asc()) + .limit(3).offset(7); + + auto x = s.as(sqlpp::alias::x); + for (const auto& row : db(select(p.id, x.name) + .from(p.join(x).on(p.feature == x.feature)) + .where(true))) + { + int id = row.id; + std::string name = row.name; + } +} diff --git a/examples/sample.sql b/examples/sample.sql new file mode 100644 index 00000000..adc255d6 --- /dev/null +++ b/examples/sample.sql @@ -0,0 +1,40 @@ +/* + * 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. + */ + +CREATE TABLE tab_person +( + id int AUTO_INCREMENT PRIMARY KEY, + name varchar(255) NOT NULL, + feature int NOT NULL +); + +CREATE TABLE tab_feature +( + id int AUTO_INCREMENT PRIMARY KEY, + name varchar(255) NULL DEFAULT "", + fatal bool NOT NULL +); + diff --git a/examples/select.cpp b/examples/select.cpp new file mode 100644 index 00000000..3bcba136 --- /dev/null +++ b/examples/select.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 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. + */ + +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wunused-variable" +#endif +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +#include "Sample.h" +#include "MockDb.h" +#include + +SQLPP_ALIAS_PROVIDER(cheesecake); + +MockDb db; + +test::TabPerson p; +test::TabFeature f; + +int main() +{ + for (const auto& row : db(select(all_of(p)).from(p).where(p.id > 7))) + { + int64_t id = row.id; + std::string name = row.name; + int64_t feature = row.feature; + } + + +#if 0 + for (const auto& row : db(select(p.name).from(p).where(p.name.like("Herb%")))) + { + int64_t id = row.id; + std::string name = row.name; + int64_t feature = row.feature; + } +#endif + + + +#if 0 + for (const auto& row : db(select(p.name, f.name.as(cheesecake)).from(p,f).where(p.id > 7 and p.feature == 3))) + { + //int64_t id = row.id; + //std::string a = row.a; + std::string name = row.name; + std::string feature = row.cheesecake; + } +#endif + + + +#if 0 + for (const auto& row : db(select(multi_column(all_of(p)).as(p), multi_column(f.name, f.id).as(f)).from(p,f).where(true))) + { + //int64_t id = row.id; + //std::string a = row.a; + std::string name = row.tabPerson.name; + std::string name1 = row.tabFeature.name; + //int64_t feature = row.feature; + } +#endif + + + + + + + +#if !0 + auto s = select(all_of(p)) + .from(p, f) + .where(p.name == any(select(f.name) + .from(f) + .where(true))) + .group_by(f.name) + .having(p.name.like("%Bee%")) + .order_by(p.name.asc()) + .limit(3).offset(7); + + auto x = s.as(sqlpp::alias::x); + for (const auto& row : db(select(p.id, x.name) + .from(p.join(x).on(p.feature == x.feature)) + .where(true))) + { + int id = row.id; + std::string name = row.name; + } +#endif + + + + + + + + + + + + + + + + + + + + + +} diff --git a/examples/update.cpp b/examples/update.cpp new file mode 100644 index 00000000..82ffa37e --- /dev/null +++ b/examples/update.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include + +MockDb db; + +test::TabPerson p; +test::TabFeature q; + +int main() +{ + db(update(p).set(p.feature = 7).where(p.id == 23)); +} diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 99909bb5..61cccb04 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -35,7 +35,7 @@ namespace sqlpp template struct expression_alias_t { - using _traits = make_traits, tag::is_named_expression, tag::is_alias>; + using _traits = make_traits, tag::is_selectable, tag::is_alias>; using _recursive_traits = make_recursive_traits; static_assert(is_expression_t::value, "invalid argument for an expression alias"); diff --git a/include/sqlpp11/all_of.h b/include/sqlpp11/all_of.h index 0af691a4..021da0a8 100644 --- a/include/sqlpp11/all_of.h +++ b/include/sqlpp11/all_of.h @@ -41,7 +41,7 @@ namespace sqlpp template detail::copy_tuple_args_t as(const AliasProvider& alias) { - return ::sqlpp::multi_column(_column_tuple_t{}).as(alias); + return multi_column(_column_tuple_t{}).as(alias); } }; diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index 708911d9..79d6aada 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -35,7 +35,7 @@ namespace sqlpp template struct any_t { - using _traits = make_traits, ::sqlpp::tag::is_multi_expression>; + using _traits = make_traits, tag::is_multi_expression>; using _recursive_traits = make_recursive_traits; static_assert(is_select_t; struct _name_t diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index 0a5053f2..fbb1a1d8 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -41,7 +41,7 @@ namespace sqlpp template struct sort_order_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits; Expression _expression; diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index 615a50cb..0ba602f6 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -98,6 +98,13 @@ namespace sqlpp no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value >::type; + using _can_be_null = detail::any_t< + can_be_null_t<_result_type_provider>::value, + detail::make_intersect_set_t< + required_tables_of<_result_type_provider>, + _all_provided_outer_tables + >::size::value != 0>; + using _traits = make_traits<_value_type, tag_if::value>>; struct _recursive_traits @@ -107,12 +114,9 @@ namespace sqlpp using _provided_outer_tables = detail::type_set<>; using _extra_tables = detail::type_set<>; using _parameters = detail::make_parameter_tuple_t...>; - using _can_be_null = detail::any_t< - can_be_null_t<_result_type_provider>::value, - ::sqlpp::detail::make_intersect_set_t< - required_tables_of<_result_type_provider>, - provided_outer_tables_of - >::size::value != 0>; + using _tags = typename std::conditional<_can_be_null::value, + detail::type_set, + detail::type_set<>>::type; }; }; } @@ -122,16 +126,16 @@ namespace sqlpp > struct statement_t: public Policies::template _member_t>..., - public detail::statement_policies_t::_value_type::template expression_operators>, + public expression_operators, value_type_of>>, public detail::statement_policies_t::_result_methods_t, public Policies::template _methods_t>... { using _policies_t = typename detail::statement_policies_t; using _traits = make_traits, - ::sqlpp::tag::is_select, + tag::is_select, tag_if::value>, - tag_if::value>, + tag_if::value>, tag::requires_braces>; using _recursive_traits = typename _policies_t::_recursive_traits; using _used_outer_tables = typename _policies_t::_all_provided_outer_tables; @@ -184,7 +188,7 @@ namespace sqlpp struct serializer_t> { using T = statement_t; - using P = ::sqlpp::detail::statement_policies_t; + using P = detail::statement_policies_t; static Context& _(const T& t, Context& context) { @@ -198,7 +202,7 @@ namespace sqlpp template struct statement_name_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 8e3553f3..6a5bf1be 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -32,13 +32,14 @@ namespace sqlpp { template - struct sum_t: public value_type_of::template expression_operators>, - public alias_operators> + struct sum_t: + public expression_operators, value_type_of>, + public alias_operators> { - using _traits = make_traits, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>; - using _recursive_traits = make_recursive_traits; + using _traits = make_traits, tag::is_expression, tag::is_selectable>; + using _recursive_traits = make_recursive_traits; - static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); + static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); struct _name_t @@ -74,7 +75,7 @@ namespace sqlpp static Context& _(const T& t, Context& context) { context << "SUM("; - if (std::is_same::value) + if (std::is_same::value) { serialize(Flag(), context); context << ' '; @@ -88,13 +89,15 @@ namespace sqlpp template auto sum(T t) -> sum_t> { + static_assert(not contains_aggregate_function_t>::value, "sum() cannot be used on an aggregate function"); static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); return { t }; } template - auto sum(const sqlpp::distinct_t&, T t) -> sum_t> + auto sum(const distinct_t&, T t) -> sum_t> { + static_assert(not contains_aggregate_function_t>::value, "sum() cannot be used on an aggregate function"); static_assert(is_numeric_t>::value, "sum() requires a numeric expression as argument"); return { t }; } diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 52f747f3..a90605be 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -40,7 +40,9 @@ namespace sqlpp struct table_base_t {}; template - struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t>... + struct table_t: + public table_base_t, + public member_t>... { using _traits = make_traits; @@ -51,7 +53,7 @@ namespace sqlpp using _provided_tables = detail::type_set; using _provided_outer_tables = detail::type_set<>; using _extra_tables = detail::type_set<>; - using _can_be_null = std::false_type; + using _tags = detail::type_set<>; }; static_assert(sizeof...(ColumnSpec), "at least one column required per table"); @@ -62,31 +64,31 @@ namespace sqlpp template - join_t join(T t) + join_t join(T t) const { return { *static_cast(this), t }; } template - join_t inner_join(T t) + join_t inner_join(T t) const { return { *static_cast(this), t }; } template - join_t outer_join(T t) + join_t outer_join(T t) const { return { *static_cast(this), t }; } template - join_t left_outer_join(T t) + join_t left_outer_join(T t) const { return { *static_cast(this), t }; } template - join_t right_outer_join(T t) + join_t right_outer_join(T t) const { return { *static_cast(this), t }; } diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index 7cc58a9f..d35245be 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -36,10 +36,11 @@ namespace sqlpp { template - struct table_alias_t: public ColumnSpec::_name_t::template _member_t>... + struct table_alias_t: + public member_t>... { //FIXME: Need to add join functionality - using _traits = make_traits, tag::is_table, tag::is_alias, tag_if::value>>; + using _traits = make_traits, tag::is_table, tag::is_alias, tag_if::value>>; struct _recursive_traits { @@ -48,13 +49,13 @@ namespace sqlpp using _provided_tables = detail::type_set; using _provided_outer_tables = detail::type_set<>; using _extra_tables = detail::type_set<>; - using _can_be_null = std::false_type; + using _tags = detail::type_set<>; }; static_assert(required_tables_of
::size::value == 0, "table aliases must not depend on external tables"); using _name_t = typename AliasProvider::_name_t; - using _column_tuple_t = std::tuple...>; + using _column_tuple_t = std::tuple...>; table_alias_t(Table table): _table(table) diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index d707d5a1..c42dea5d 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -39,32 +39,39 @@ namespace sqlpp // text value type struct text { - using _traits = make_traits; - using _tag = ::sqlpp::tag::is_text; + using _traits = make_traits; + using _tag = tag::is_text; using _cpp_value_type = std::string; - struct _parameter_t + template + using _is_valid_operand = is_text_t; + }; + + // text parameter type + template<> + struct parameter_value_t { using _value_type = text; + using _cpp_value_type = typename _value_type::_cpp_value_type; - _parameter_t(): + parameter_value_t(): _value(""), _is_null(true) {} - _parameter_t(const _cpp_value_type& value): + parameter_value_t(const _cpp_value_type& value): _value(value), _is_null(false) {} - _parameter_t& operator=(const _cpp_value_type& value) + parameter_value_t& operator=(const _cpp_value_type& value) { _value = value; _is_null = false; return *this; } - _parameter_t& operator=(const tvin_t>& t) + parameter_value_t& operator=(const tvin_t>& t) { if (t._is_trivial()) { @@ -79,7 +86,7 @@ namespace sqlpp return *this; } - _parameter_t& operator=(const std::nullptr_t&) + parameter_value_t& operator=(const std::nullptr_t&) { _value = ""; _is_null = true; @@ -110,51 +117,50 @@ namespace sqlpp }; + // text expression operators + template + struct expression_operators: public basic_expression_operators + { template - struct _is_valid_operand - { - static constexpr bool value = - is_expression_t::value // expressions are OK - and is_text_t::value // the correct value type is required, of course - ; - }; + using _is_valid_operand = is_valid_operand; - template - struct expression_operators: public basic_expression_operators + template + concat_t> operator+(T t) const + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid rhs operand"); + + return { *static_cast(this), {t} }; + } + + template + like_t> like(T t) const + { + using rhs = wrap_operand_t; + static_assert(_is_valid_operand::value, "invalid argument for like()"); + + return { *static_cast(this), {t} }; + } + }; + + // text column operators + template + struct column_operators { template - concat_t> operator+(T t) const - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs operand"); - - return { *static_cast(this), {t} }; - } + using _is_valid_operand = is_valid_operand; template - like_t> like(T t) const + auto operator +=(T t) const -> assignment_t>> { using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid argument for like()"); + static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - return { *static_cast(this), {t} }; + return { *static_cast(this), concat_t>{ *static_cast(this), rhs{t} } }; } }; - template - struct column_operators - { - template - auto operator +=(T t) const -> assignment_t>> - { - using rhs = wrap_operand_t; - static_assert(_is_valid_operand::value, "invalid rhs assignment operand"); - - return { *static_cast(this), { *static_cast(this), rhs{t} } }; - } - }; - }; - + // text result field template struct result_field_t: public result_field_methods_t> { diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 9b30d438..a0714bdc 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -32,30 +32,59 @@ namespace sqlpp { + namespace tag + { + struct can_be_null{}; + struct contains_aggregate_function{}; + }; + namespace detail { template struct can_be_null_impl { using type = std::false_type; }; template - struct can_be_null_impl::type> { using type = std::true_type; }; + struct can_be_null_impl::value>::type> { using type = std::true_type; }; } template using can_be_null_t = typename detail::can_be_null_impl::type; - namespace tag\ - {\ - struct can_be_null{};\ - };\ - namespace detail\ - {\ - template\ - struct column_spec_can_be_null_impl { using type = std::false_type; };\ - template\ - struct column_spec_can_be_null_impl::value>::type> { using type = std::true_type; };\ - }\ - template\ + namespace detail + { + template + struct contains_aggregate_function_impl { using type = std::false_type; }; + template + struct contains_aggregate_function_impl::value>::type> { using type = std::true_type; }; + } + template + using contains_aggregate_function_t = typename detail::contains_aggregate_function_impl::type; + + namespace detail + { + template + struct column_spec_can_be_null_impl { using type = std::false_type; }; + template + struct column_spec_can_be_null_impl::value>::type> { using type = std::true_type; }; + } + template using column_spec_can_be_null_t = typename detail::column_spec_can_be_null_impl::type; + namespace tag + { + struct is_expression{}; + }; + namespace detail + { + template + struct is_expression_impl { using type = std::false_type; }; + template + struct is_expression_impl::value + and not detail::is_element_of::value + >::type> { using type = std::true_type; }; + } + template + using is_expression_t = typename detail::is_expression_impl::type; + #define SQLPP_VALUE_TRAIT_GENERATOR(name) \ namespace tag\ {\ @@ -82,8 +111,7 @@ namespace sqlpp detail::is_element_of::value>; SQLPP_VALUE_TRAIT_GENERATOR(is_text); SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value); - SQLPP_VALUE_TRAIT_GENERATOR(is_expression); - SQLPP_VALUE_TRAIT_GENERATOR(is_named_expression); + SQLPP_VALUE_TRAIT_GENERATOR(is_selectable); SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression); SQLPP_VALUE_TRAIT_GENERATOR(is_alias); SQLPP_VALUE_TRAIT_GENERATOR(is_select_flag); @@ -140,80 +168,35 @@ namespace sqlpp namespace detail { - template - struct value_type_of_impl - { - using type = typename T::_traits::_value_type; - }; - - template - struct required_table_of_impl - { - using type = typename T::_recursive_traits::_required_tables; - }; - - template - struct provided_table_of_impl - { - using type = typename T::_recursive_traits::_provided_tables; - }; - - template - struct provided_outer_table_of_impl - { - using type = typename T::_recursive_traits::_provided_outer_tables; - }; - - template - struct extra_table_of_impl - { - using type = typename T::_recursive_traits::_extra_tables; - }; - - template - struct parameters_of_impl - { - using type = typename T::_recursive_traits::_parameters; - }; - - template - struct name_of_impl - { - using type = typename T::_name_t; - }; - template - struct make_parameter_tuple_impl - { - using type = decltype(std::tuple_cat(std::declval()...)); - }; - - template - using make_parameter_tuple_t = typename make_parameter_tuple_impl::type; + using make_parameter_tuple_t = decltype(std::tuple_cat(std::declval()...)); } template - using value_type_of = typename detail::value_type_of_impl::type; + using value_type_of = typename T::_traits::_value_type; template using cpp_value_type_of = typename value_type_of::_cpp_value_type; template - using required_tables_of = typename detail::required_table_of_impl::type; + using required_tables_of = typename T::_recursive_traits::_required_tables; template - using provided_tables_of = typename detail::provided_table_of_impl::type; + using provided_tables_of = typename T::_recursive_traits::_provided_tables; template - using provided_outer_tables_of = typename detail::provided_outer_table_of_impl::type; + using provided_outer_tables_of = typename T::_recursive_traits::_provided_outer_tables; template - using extra_tables_of = typename detail::extra_table_of_impl::type; + using extra_tables_of = typename T::_recursive_traits::_extra_tables; template - using parameters_of = typename detail::parameters_of_impl::type; + using parameters_of = typename T::_recursive_traits::_parameters; template - using name_of = typename detail::name_of_impl::type; + using recursive_tags_of = typename T::_recursive_traits::_tags; + + template + using name_of = typename T::_name_t; template struct make_traits @@ -221,6 +204,7 @@ namespace sqlpp using _value_type = ValueType; using _tags = detail::make_type_set_t; }; + template struct make_recursive_traits { @@ -229,9 +213,31 @@ namespace sqlpp using _provided_outer_tables = detail::make_joined_set_t...>; using _extra_tables = detail::make_joined_set_t...>; using _parameters = detail::make_parameter_tuple_t...>; - using _can_be_null = detail::any_t::value...>; + using _tags = detail::make_joined_set_t...>; }; + template + struct recursive_tags + { + using _required_tables = detail::type_set<>; + using _provided_tables = detail::type_set<>; + using _provided_outer_tables = detail::type_set<>; + using _extra_tables = detail::type_set<>; + using _parameters = std::tuple<>; + using _tags = detail::type_set; + }; + + struct aggregate_function + { + struct _traits { using _value_type = void; using _tags = detail::type_set<>; }; + using _recursive_traits = recursive_tags; + }; + + template + using member_t = typename NameProvider::_name_t::template _member_t; + + template + using derived_statement_t = typename Policies::_statement_t; } #endif diff --git a/include/sqlpp11/update.h b/include/sqlpp11/update.h index e017865a..492f0791 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -28,7 +28,7 @@ #define SQLPP_UPDATE_H #include - +#include #include #include #include @@ -49,7 +49,7 @@ namespace sqlpp template struct _result_methods_t { - using _statement_t = typename Policies::_statement_t; + using _statement_t = derived_statement_t; const _statement_t& _get_statement() const { @@ -109,6 +109,7 @@ namespace sqlpp constexpr auto dynamic_update(const Database&, Table table) -> decltype(blank_update_t().from(table)) { + static_assert(std::is_base_of::value, "Invalid database parameter"); return { blank_update_t().from(table) }; } } diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index 1ee40173..425b8b8f 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -56,7 +56,7 @@ namespace sqlpp template struct update_list_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits; using _is_dynamic = is_database; @@ -78,12 +78,12 @@ namespace sqlpp { static_assert(_is_dynamic::value, "add must not be called for static from()"); static_assert(is_assignment_t::value, "invalid assignment argument in add()"); - using _assigned_columns = detail::make_type_set_t; - static_assert(not detail::is_element_of::value, "Must not assign value to column twice"); - static_assert(sqlpp::detail::not_t::value, "add() argument must not be updated"); + using _assigned_columns = detail::make_type_set_t...>; + static_assert(not detail::is_element_of, _assigned_columns>::value, "Must not assign value to column twice"); + static_assert(detail::not_t>::value, "add() argument must not be updated"); static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "assignment uses tables unknown to this statement in add()"); - using ok = ::sqlpp::detail::all_t< + using ok = detail::all_t< _is_dynamic::value, is_assignment_t::value>; @@ -130,7 +130,7 @@ namespace sqlpp struct no_update_list_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data @@ -165,7 +165,7 @@ namespace sqlpp { using _database_t = typename Policies::_database_t; template - using _new_statement_t = typename Policies::template _new_statement_t; + using _new_statement_t = new_statement; static void _check_consistency() { @@ -173,7 +173,7 @@ namespace sqlpp } template - auto set(Assignments... assignments) + auto set(Assignments... assignments) const -> _new_statement_t> { static_assert(sizeof...(Assignments), "at least one assignment expression required in set()"); @@ -181,7 +181,7 @@ namespace sqlpp } template - auto dynamic_set(Assignments... assignments) + auto dynamic_set(Assignments... assignments) const -> _new_statement_t> { static_assert(not std::is_same<_database_t, void>::value, "dynamic_set() must not be called in a static statement"); @@ -190,17 +190,17 @@ namespace sqlpp private: template - auto _set_impl(Assignments... assignments) + auto _set_impl(Assignments... assignments) const -> _new_statement_t> { - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); - static_assert(::sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); + static_assert(not detail::has_duplicates...>::value, "at least one duplicate column detected in set()"); + static_assert(detail::none_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()"); - using _column_required_tables = ::sqlpp::detail::make_joined_set_t...>; + using _column_required_tables = detail::make_joined_set_t>...>; static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from more than one table"); - return { *static_cast(this), update_list_data_t{assignments...} }; + return { static_cast&>(*this), update_list_data_t{assignments...} }; } }; }; diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h index a4897474..c704dfc4 100644 --- a/include/sqlpp11/using.h +++ b/include/sqlpp11/using.h @@ -57,16 +57,16 @@ namespace sqlpp template struct using_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits; using _is_dynamic = is_database; static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()"); - static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in using()"); + static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected in using()"); - static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an table in using()"); + static_assert(detail::all_t::value...>::value, "at least one argument is not an table in using()"); // Data using _data_t = using_data_t; @@ -81,7 +81,7 @@ namespace sqlpp static_assert(_is_dynamic::value, "add must not be called for static using()"); static_assert(is_table_t
::value, "invalid table argument in add()"); - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t
::value>; + using ok = detail::all_t<_is_dynamic::value, is_table_t
::value>; _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert } @@ -128,7 +128,7 @@ namespace sqlpp // NO USING YET struct no_using_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data @@ -163,23 +163,23 @@ namespace sqlpp { using _database_t = typename Policies::_database_t; template - using _new_statement_t = typename Policies::template _new_statement_t; + using _new_statement_t = new_statement; static void _check_consistency() {} template - auto using_(Args... args) + auto using_(Args... args) const -> _new_statement_t> { - return { *static_cast(this), using_data_t{args...} }; + return { static_cast&>(*this), using_data_t{args...} }; } template - auto dynamic_using(Args... args) + auto dynamic_using(Args... args) const -> _new_statement_t> { static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement"); - return { *static_cast(this), using_data_t<_database_t, Args...>{args...} }; + return { static_cast&>(*this), using_data_t<_database_t, Args...>{args...} }; } }; }; diff --git a/include/sqlpp11/value_type_fwd.h b/include/sqlpp11/value_type_fwd.h new file mode 100644 index 00000000..805e5662 --- /dev/null +++ b/include/sqlpp11/value_type_fwd.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_VALUE_TYPE_FWD_H +#define SQLPP_VALUE_TYPE_FWD_H + +#include +#include + +namespace sqlpp +{ + template + struct parameter_value_t + { + static_assert(wrong_t::value, "Missing parameter value type for ValueType"); + }; + + template + struct column_operators + { + static_assert(wrong_t::value, "Missing column operators for ValueType"); + }; + + template + struct expression_operators + { + static_assert(wrong_t::value, "Missing expression operators for ValueType"); + }; + + template + struct is_valid_operand + { + static constexpr bool value = + is_expression_t::value // expressions are OK + and ValueType::template _is_valid_operand::value // the correct value type is required, of course + ; + }; +} + +#endif + + diff --git a/include/sqlpp11/verbatim.h b/include/sqlpp11/verbatim.h new file mode 100644 index 00000000..d1b43006 --- /dev/null +++ b/include/sqlpp11/verbatim.h @@ -0,0 +1,76 @@ +/* + * 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 expression_operators, ValueType>, + public alias_operators> + { + using _traits = make_traits; + struct _recursive_traits : public make_recursive_traits<> + { + using _tags = detail::type_set; // 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 diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index e0c248cd..fc53af7f 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -46,9 +46,9 @@ namespace sqlpp }; } - struct verbatim_table_t: public sqlpp::table_t + struct verbatim_table_t: public table_t { - struct _recursive_traits: public sqlpp::table_t::_recursive_traits + struct _recursive_traits: public table_t::_recursive_traits { using _provided_outer_tables = detail::type_set; }; diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index cd2b924b..7fb09551 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -58,14 +58,14 @@ namespace sqlpp template struct where_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits; using _is_dynamic = is_database; static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()"); - static_assert(sqlpp::detail::none_t::value...>::value, "at least one argument is an assignment in where()"); - static_assert(sqlpp::detail::all_t::value...>::value, "at least one argument is not valid expression in where()"); + static_assert(detail::none_t::value...>::value, "at least one argument is an assignment in where()"); + static_assert(detail::all_t::value...>::value, "at least one argument is not valid expression in where()"); // Data using _data_t = where_data_t; @@ -87,7 +87,7 @@ namespace sqlpp static_assert(is_expression_t::value, "invalid expression argument in where::add()"); static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "expression uses tables unknown to this statement in where::add()"); - using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t::value>; + using ok = detail::all_t<_is_dynamic::value, is_expression_t::value>; _add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert } @@ -141,7 +141,7 @@ namespace sqlpp template<> struct where_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data @@ -181,10 +181,10 @@ namespace sqlpp }; // NO WHERE YET - template + template struct no_where_t { - using _traits = make_traits; + using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; // Data @@ -220,26 +220,28 @@ namespace sqlpp { using _database_t = typename Policies::_database_t; template - using _new_statement_t = typename Policies::template _new_statement_t; + using _new_statement_t = new_statement; 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 - auto where(Args... args) + auto where(Args... args) const -> _new_statement_t> { - return { *static_cast(this), where_data_t{args...} }; + return { static_cast&>(*this), where_data_t{args...} }; } template - auto dynamic_where(Args... args) + auto dynamic_where(Args... args) const -> _new_statement_t> { static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement"); - return { *static_cast(this), where_data_t<_database_t, Args...>{args...} }; + return { static_cast&>(*this), where_data_t<_database_t, Args...>{args...} }; } }; }; diff --git a/include/sqlpp11/wrap_operand.h b/include/sqlpp11/wrap_operand.h index ffab6e94..7be274c2 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,9 +40,9 @@ 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 _traits = make_traits; using _recursive_traits = make_recursive_traits<>; using _value_t = bool; @@ -76,9 +78,9 @@ 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 _traits = make_traits; using _recursive_traits = make_recursive_traits<>; using _value_t = int64_t; @@ -115,9 +117,9 @@ 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 _traits = make_traits; using _recursive_traits = make_recursive_traits<>; using _value_t = double; @@ -153,9 +155,9 @@ 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 _traits = make_traits; using _recursive_traits = make_recursive_traits<>; using _value_t = std::string; @@ -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/scripts/ddl2cpp b/scripts/ddl2cpp index 9fbeabb2..dd09cf86 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -175,7 +175,6 @@ for tableCreation in tableCreations: print(' struct ' + tableClass + ': ' + NAMESPACE + '::table_t<' + tableTemplateParameters + '>', file=header) print(' {', file=header) - print(' using _value_type = ' + NAMESPACE + '::no_value_t;', file=header) print(' struct _name_t', file=header) print(' {', file=header) print(' static constexpr const char* _get_name() { return "' + sqlTableName + '"; }', file=header) diff --git a/test_constraints/CMakeLists.txt b/test_constraints/CMakeLists.txt index bdb60f10..2281b371 100644 --- a/test_constraints/CMakeLists.txt +++ b/test_constraints/CMakeLists.txt @@ -1,31 +1,33 @@ -include_directories(${CMAKE_BINARY_DIR}/tests) +include_directories("${CMAKE_SOURCE_DIR}/tests") add_custom_target(test_sqlpp_constraints COMMAND true) function(test_constraint name pattern) add_executable( - ${name} + "${name}" EXCLUDE_FROM_ALL - ${name}.cpp + "${name}.cpp" ) - add_custom_command(OUTPUT ${name}.out - COMMAND ${CMAKE_MAKE_PROGRAM} ${name} > ${CMAKE_CURRENT_BINARY_DIR}/${name}.out 2>&1 || true - COMMAND grep ${pattern} ${CMAKE_CURRENT_BINARY_DIR}/${name}.out > /dev/null - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp + add_custom_command(OUTPUT "${name}.out" + COMMAND "${CMAKE_MAKE_PROGRAM}" "${name}" > "${CMAKE_CURRENT_BINARY_DIR}/${name}.out" 2>&1 || true + COMMAND grep "${pattern}" "${CMAKE_CURRENT_BINARY_DIR}/${name}.out" > /dev/null + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp" COMMENT "${name}" - ) + VERBATIM) - add_custom_target(test_${name} DEPENDS ${name}.out COMMAND true) + add_custom_target("test_${name}" DEPENDS "${name}.out" COMMAND true) - add_dependencies(test_sqlpp_constraints test_${name}) - -endfunction(testconstraint) + add_dependencies(test_sqlpp_constraints "test_${name}") +endfunction(test_constraint) +test_constraint(count_of_count "requires an expression as argument") +test_constraint(max_of_max "requires an expression as argument") 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") diff --git a/test_constraints/count_of_count.cpp b/test_constraints/count_of_count.cpp new file mode 100644 index 00000000..95f089db --- /dev/null +++ b/test_constraints/count_of_count.cpp @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include +#include + +MockDb db; + +int main() +{ + test::TabBar t; + + count(count(t.alpha)); +} diff --git a/test_constraints/max_of_max.cpp b/test_constraints/max_of_max.cpp new file mode 100644 index 00000000..96483e9b --- /dev/null +++ b/test_constraints/max_of_max.cpp @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include +#include + +MockDb db; + +int main() +{ + test::TabBar t; + + max(max(t.alpha)); +} diff --git a/test_constraints/must_not_update.cpp b/test_constraints/must_not_update.cpp new file mode 100644 index 00000000..42f9ac04 --- /dev/null +++ b/test_constraints/must_not_update.cpp @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#include "Sample.h" +#include "MockDb.h" +#include + +MockDb db; + +int main() +{ + test::TabBar t; + + update(t).set(t.alpha = 7, t.gamma = false, t.beta = "alpha must not be set"); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6582425b..86462e61 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,9 +1,9 @@ macro (build_and_run arg) # Add headers to sources to enable file browsing in IDEs - include_directories(${CMAKE_BINARY_DIR}/tests) - add_executable(${arg} ${arg}.cpp ${sqlpp_headers} ${CMAKE_CURRENT_LIST_DIR}/Sample.h) - add_test(${arg} ${arg}) + include_directories("${CMAKE_BINARY_DIR}/tests") + add_executable("${arg}" "${arg}.cpp" ${sqlpp_headers} "${CMAKE_CURRENT_LIST_DIR}/Sample.h") + add_test("${arg}" "${arg}") endmacro () build_and_run(BooleanExpressionTest) @@ -21,8 +21,7 @@ build_and_run(ResultTest) # if you want to use the generator, you can do something like this: #find_package(PythonInterp REQUIRED) #add_custom_command( -# OUTPUT ${CMAKE_CURRENT_LIST_DIR}/Sample.h -# COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/ddl2cpp ${CMAKE_CURRENT_LIST_DIR}/sample.sql Sample test -# DEPENDS ${CMAKE_CURRENT_LIST_DIR}/sample.sql -# ) - +# OUTPUT "${CMAKE_CURRENT_LIST_DIR}/Sample.h" +# COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/ddl2cpp" "${CMAKE_CURRENT_LIST_DIR}/sample.sql" Sample test +# DEPENDS "${CMAKE_CURRENT_LIST_DIR}/sample.sql" +# VERBATIM) diff --git a/tests/FunctionTest.cpp b/tests/FunctionTest.cpp index 374a7c20..b0026480 100644 --- a/tests/FunctionTest.cpp +++ b/tests/FunctionTest.cpp @@ -50,15 +50,15 @@ int main() using TI = decltype(t.alpha.in(1, 2, 3)); using TF = decltype(f.omega.in(1.0, 2.0, 3.0)); using TT = decltype(t.beta.in("a", "b", "c")); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -69,15 +69,15 @@ int main() using TI = decltype(t.alpha.in(sqlpp::value_list(std::vector({1, 2, 3})))); using TF = decltype(f.omega.in(sqlpp::value_list(std::vector({1.0, 2.0, 3.0})))); using TT = decltype(t.beta.in(sqlpp::value_list(std::vector({"a", "b", "c"})))); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -88,15 +88,15 @@ int main() using TI = decltype(t.alpha.not_in(1, 2, 3)); using TF = decltype(f.omega.not_in(1.0, 2.0, 3.0)); using TT = decltype(t.beta.not_in("a", "b", "c")); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -107,15 +107,15 @@ int main() using TI = decltype(t.alpha.not_in(sqlpp::value_list(std::vector({1, 2, 3})))); using TF = decltype(f.omega.not_in(sqlpp::value_list(std::vector({1.0, 2.0, 3.0})))); using TT = decltype(t.beta.not_in(sqlpp::value_list(std::vector({"a", "b", "c"})))); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -124,7 +124,7 @@ int main() // Test like { using TT = decltype(t.beta.like("%c%")); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -141,15 +141,15 @@ int main() static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -166,15 +166,15 @@ int main() static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -187,11 +187,11 @@ int main() { using TI = decltype(exists(select(t.alpha).from(t))); using TT = decltype(exists(select(t.beta).from(t))); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); @@ -206,17 +206,17 @@ int main() using TI = decltype(any(select(t.alpha).from(t))); using TT = decltype(any(select(t.beta).from(t))); using TF = decltype(any(select(f.omega).from(f))); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "tFpe requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); @@ -229,18 +229,18 @@ int main() using TI = decltype(some(select(t.alpha).from(t))); using TT = decltype(some(select(t.beta).from(t))); using TF = decltype(some(select(f.omega).from(f))); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); static_assert(not sqlpp::is_text_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_multi_expression_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); @@ -254,11 +254,11 @@ int main() { using TI = decltype(avg(t.alpha)); using TF = decltype(avg(f.omega)); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); @@ -269,15 +269,15 @@ int main() using TI = decltype(count(t.alpha)); using TT = decltype(count(t.beta)); using TF = decltype(count(f.omega)); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); @@ -288,15 +288,15 @@ int main() using TI = decltype(max(t.alpha)); using TF = decltype(max(f.omega)); using TT = decltype(max(t.beta)); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -306,15 +306,15 @@ int main() using TI = decltype(min(t.alpha)); using TF = decltype(min(f.omega)); using TT = decltype(min(t.beta)); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -323,11 +323,11 @@ int main() { using TI = decltype(sum(t.alpha)); using TF = decltype(sum(f.omega)); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); @@ -342,13 +342,13 @@ int main() using TI = decltype(sqlpp::value(7)); using TF = decltype(sqlpp::value(1.5)); using TT = decltype(sqlpp::value("cheesecake")); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -358,13 +358,13 @@ int main() using TI = decltype(flatten(t.alpha, db)); using TF = decltype(flatten(f.omega, db)); using TT = decltype(flatten(t.beta, db)); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -382,13 +382,13 @@ int main() static_assert(std::is_same::value, "type_requirement"); static_assert(std::is_same::value, "type_requirement"); static_assert(std::is_same::value, "type_requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -398,20 +398,20 @@ int main() using TI = decltype(sqlpp::verbatim("42")); using TF = decltype(sqlpp::verbatim("1.5")); using TT = decltype(sqlpp::verbatim("cheesecake")); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } // test verbatim_table { using T = decltype(sqlpp::verbatim_table("cheesecake")); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); static_assert(sqlpp::is_table_t::value, "type requirement"); } @@ -419,7 +419,7 @@ int main() // test verbatim_table alias { using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen)); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); static_assert(sqlpp::is_table_t::value, "type requirement"); static_assert(sqlpp::is_alias_t::value, "type requirement"); diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 6d0943ac..c3813a24 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -179,6 +179,9 @@ int main() printer.reset(); std::cerr << serialize(x, printer).str() << std::endl; + printer.reset(); + std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).where(true))), printer).str() << std::endl; + return 0; diff --git a/tests/MockDb.h b/tests/MockDb.h index d6a55365..0586c04c 100644 --- a/tests/MockDb.h +++ b/tests/MockDb.h @@ -41,6 +41,12 @@ struct MockDbT: public sqlpp::connection { std::ostringstream _os; + _serializer_context_t() = default; + _serializer_context_t(const _serializer_context_t& rhs) + { + _os << rhs._os.str(); + } + std::string str() const { return _os.str(); @@ -159,8 +165,6 @@ struct MockDbT: public sqlpp::connection template size_t run_prepared_insert(const PreparedInsert& x) { - _serializer_context_t context; - ::sqlpp::serialize(x, context); return 0; } @@ -175,8 +179,6 @@ struct MockDbT: public sqlpp::connection template result_t run_prepared_select(PreparedSelect& x) { - _serializer_context_t context; - ::sqlpp::serialize(x, context); return {}; } diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index cacac316..27a5832e 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -81,9 +81,9 @@ int main() using Exp = decltype((t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha)) or t.gamma != parameter(t.gamma)); using T = sqlpp::make_parameter_list_t; T npl; - static_assert(std::is_same::_parameter_t, decltype(npl.alpha)>::value, "type requirement"); - static_assert(std::is_same::_parameter_t, decltype(npl.beta)>::value, "type requirement"); - static_assert(std::is_same::_parameter_t, decltype(npl.gamma)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.alpha)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.beta)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.gamma)>::value, "type requirement"); } // Wonderful, now take a look at the parameter list of a select @@ -96,9 +96,9 @@ int main() using T = sqlpp::make_parameter_list_t; T npl; - static_assert(std::is_same::_parameter_t, decltype(npl.alpha)>::value, "type requirement"); - static_assert(std::is_same::_parameter_t, decltype(npl.beta)>::value, "type requirement"); - static_assert(std::is_same::_parameter_t, decltype(npl.gamma)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.alpha)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.beta)>::value, "type requirement"); + static_assert(std::is_same>, decltype(npl.gamma)>::value, "type requirement"); npl.alpha = 7; auto x = npl; x = npl; diff --git a/tests/ResultTest.cpp b/tests/ResultTest.cpp index 7add38fa..21ca2f82 100644 --- a/tests/ResultTest.cpp +++ b/tests/ResultTest.cpp @@ -43,7 +43,7 @@ int main() static_assert(not sqlpp::null_is_trivial_value_t::value, "t.alpha does not say null_is_trivial"); // Using a non-enforcing db - for (const auto& row : db(select(all_of(t)).from(t).where(true))) + for (const auto& row : db(select(all_of(t), t.beta.like("")).from(t).where(true))) { static_assert(sqlpp::can_be_null_t::value, "row.alpha can be null"); static_assert(sqlpp::null_is_trivial_value_t::value, "row.alpha interprets null_is_trivial"); diff --git a/tests/Sample.h b/tests/Sample.h index 4ba3774d..5f1bf1de 100644 --- a/tests/Sample.h +++ b/tests/Sample.h @@ -60,7 +60,6 @@ namespace test TabFoo_::Epsilon, TabFoo_::Omega> { - using _value_type = sqlpp::no_value_t; struct _name_t { static constexpr const char* _get_name() { return "tab_foo"; } @@ -143,7 +142,6 @@ namespace test TabBar_::Gamma, TabBar_::Delta> { - using _value_type = sqlpp::no_value_t; struct _name_t { static constexpr const char* _get_name() { return "tab_bar"; } diff --git a/tests/SelectTest.cpp b/tests/SelectTest.cpp index 1e97562c..bbf9a3e5 100644 --- a/tests/SelectTest.cpp +++ b/tests/SelectTest.cpp @@ -69,6 +69,11 @@ int main() std::cout << row.alpha << std::endl; } + for (const auto& row : db(select(count(t.alpha), avg(t.alpha)).from(t).where(true))) + { + std::cout << row.count << std::endl; + } + auto stat = sqlpp::select().columns(all_of(t)).flags(sqlpp::all).from(t).extra_tables(f,t).where(t.alpha > 0).group_by(t.alpha).order_by(t.gamma.asc()).having(t.gamma).limit(7).offset(19); auto s = dynamic_select(db).dynamic_columns(all_of(t)).dynamic_flags().dynamic_from(t).extra_tables(f,t).dynamic_where().dynamic_group_by(t.alpha).dynamic_order_by().dynamic_having(t.gamma).dynamic_limit().dynamic_offset(); @@ -92,5 +97,7 @@ int main() printer.reset(); std::cerr << serialize(stat, printer).str() << std::endl; + select(sqlpp::value(7).as(t.alpha)); + return 0; } diff --git a/tests/SelectTypeTest.cpp b/tests/SelectTypeTest.cpp index 6a8f931e..00c0d882 100644 --- a/tests/SelectTypeTest.cpp +++ b/tests/SelectTypeTest.cpp @@ -56,7 +56,7 @@ int main() static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -74,7 +74,7 @@ int main() static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -92,7 +92,7 @@ int main() static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_update_t::value, "type requirement"); @@ -111,7 +111,7 @@ int main() static_assert(sqlpp::is_integral_t::value, "type requirement"); static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_update_t::value, "type requirement"); @@ -129,7 +129,7 @@ int main() static_assert(not sqlpp::is_integral_t::value, "type requirement"); static_assert(sqlpp::is_floating_point_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -145,7 +145,7 @@ int main() using T = decltype(t.alpha.as(alias::a)); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -161,7 +161,7 @@ int main() using T = decltype(select(t.alpha)); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -179,7 +179,7 @@ int main() //static_assert(sqlpp::is_from_t::value, "Must not be noop"); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -195,7 +195,7 @@ int main() using T = decltype(select(t.alpha.as(alias::a)).from(t)); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -211,7 +211,7 @@ int main() using T = decltype(select(t.alpha).from(t).as(alias::b)); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -227,7 +227,7 @@ int main() using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b)); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(not sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); static_assert(not sqlpp::must_not_update_t::value, "type requirement"); @@ -243,7 +243,7 @@ int main() using T = decltype(select(t.alpha).from(t).as(alias::b).alpha); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_update_t::value, "type requirement"); @@ -259,7 +259,7 @@ int main() using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b).a); static_assert(sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_named_expression_t::value, "type requirement"); + static_assert(sqlpp::is_selectable_t::value, "type requirement"); static_assert(not sqlpp::require_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_insert_t::value, "type requirement"); static_assert(sqlpp::must_not_update_t::value, "type requirement"); @@ -364,8 +364,8 @@ int main() static_assert(sqlpp::must_not_insert_t::value, "alpha must not be inserted"); serialize(t.alpha, printer).str(); std::cerr << "\n" << sizeof(test::TabBar) << std::endl; - static_assert(sqlpp::is_named_expression_t::value, "alpha should be a named expression"); - static_assert(sqlpp::is_named_expression_t::value, "an alias of alpha should be a named expression"); + static_assert(sqlpp::is_selectable_t::value, "alpha should be a named expression"); + static_assert(sqlpp::is_selectable_t::value, "an alias of alpha should be a named expression"); static_assert(sqlpp::is_alias_t::value, "an alias of alpha should be an alias"); auto l = t.as(alias::left); diff --git a/tests/UpdateTest.cpp b/tests/UpdateTest.cpp index 04f73024..e12224ec 100644 --- a/tests/UpdateTest.cpp +++ b/tests/UpdateTest.cpp @@ -68,6 +68,8 @@ int main() db(update(t).set(t.delta = sqlpp::null).where(true)); db(update(t).set(t.delta = sqlpp::default_value).where(true)); + db(update(t).set(t.delta += t.alpha * 2, t.beta += " and cake").where(true)); + return 0; }