diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index abad7cfb..0f60e025 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -44,13 +44,15 @@ namespace sqlpp SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_rhs_comparison_operand_t, "invalid rhs operand in comparison"); template - using check_rhs_comparison_operand_t = static_check_t< - (is_expression_t::value // expressions are OK - or - is_multi_expression_t::value) // multi-expressions like ANY are OK for comparisons, too - and - LhsValueType::template _is_valid_operand::value, // the correct value type is required, of course - assert_valid_rhs_comparison_operand_t>; + using check_rhs_comparison_operand_t = + static_check_t<(is_expression_t>::value // expressions are OK + or + is_multi_expression_t>::value) // multi-expressions like ANY are + // OK for comparisons, too + and + LhsValueType::template _is_valid_operand< + sqlpp::wrap_operand_t>::value, // the correct value type is required, of course + assert_valid_rhs_comparison_operand_t>; SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_in_arguments_t, "at least one operand of in() is not valid"); diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 80e0063b..52af8e4d 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -3,25 +3,25 @@ ## # Copyright (c) 2013-2015, Roland Bock # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without modification, + # + # 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, + # + # * 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 + # * 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 + # + # 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. ## @@ -67,12 +67,12 @@ ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue"); ddlAutoValue = ddlWord("AUTO_INCREMENT").setResultsName("hasAutoValue"); ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment") ddlConstraint = Or([ - ddlWord("CONSTRAINT"), - ddlWord("PRIMARY"), - ddlWord("FOREIGN"), + ddlWord("CONSTRAINT"), + ddlWord("PRIMARY"), + ddlWord("FOREIGN"), ddlWord("KEY"), - ddlWord("INDEX"), - ddlWord("UNIQUE"), + ddlWord("INDEX"), + ddlWord("UNIQUE"), ]) ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlTerm.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create") @@ -98,8 +98,11 @@ types = { 'mediumblob': 'blob', 'longblob': 'blob', 'bool': 'boolean', + 'boolean': 'boolean', 'double': 'floating_point', 'float': 'floating_point', + 'date' : 'date', + 'datetime' : 'date_time', } # PROCESS DDL @@ -113,6 +116,7 @@ namespace = sys.argv[3] ddlFile = open(pathToDdl, 'r') header = open(pathToHeader, 'w') +print('// generated by ' + ' '.join(sys.argv), file=header) print('#ifndef '+get_include_guard_name(namespace, pathToHeader), file=header) print('#define '+get_include_guard_name(namespace, pathToHeader), file=header) print('', file=header) diff --git a/test_static_asserts/AssertTables.h b/test_static_asserts/AssertTables.h new file mode 100644 index 00000000..6c6cdef3 --- /dev/null +++ b/test_static_asserts/AssertTables.h @@ -0,0 +1,290 @@ +// generated by ../scripts/ddl2cpp ../test_static_asserts/AssertTables.sql ../test_static_asserts/AssertTables test +#ifndef TEST_ASSERTTABLES_H +#define TEST_ASSERTTABLES_H + +#include +#include +#include + +namespace test +{ + namespace TabAllTypes_ + { + struct SomeString + { + struct _alias_t + { + static constexpr const char _literal[] = "some_string"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someString; + T& operator()() + { + return someString; + } + const T& operator()() const + { + return someString; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct SomeInt + { + struct _alias_t + { + static constexpr const char _literal[] = "some_int"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someInt; + T& operator()() + { + return someInt; + } + const T& operator()() const + { + return someInt; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct SomeFloat + { + struct _alias_t + { + static constexpr const char _literal[] = "some_float"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someFloat; + T& operator()() + { + return someFloat; + } + const T& operator()() const + { + return someFloat; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct SomeBool + { + struct _alias_t + { + static constexpr const char _literal[] = "some_bool"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someBool; + T& operator()() + { + return someBool; + } + const T& operator()() const + { + return someBool; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct SomeDate + { + struct _alias_t + { + static constexpr const char _literal[] = "some_date"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someDate; + T& operator()() + { + return someDate; + } + const T& operator()() const + { + return someDate; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct SomeDateTime + { + struct _alias_t + { + static constexpr const char _literal[] = "some_date_time"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T someDateTime; + T& operator()() + { + return someDateTime; + } + const T& operator()() const + { + return someDateTime; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct OtherInt + { + struct _alias_t + { + static constexpr const char _literal[] = "other_int"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T otherInt; + T& operator()() + { + return otherInt; + } + const T& operator()() const + { + return otherInt; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct OtherFloat + { + struct _alias_t + { + static constexpr const char _literal[] = "other_float"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T otherFloat; + T& operator()() + { + return otherFloat; + } + const T& operator()() const + { + return otherFloat; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct OtherBool + { + struct _alias_t + { + static constexpr const char _literal[] = "other_bool"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T otherBool; + T& operator()() + { + return otherBool; + } + const T& operator()() const + { + return otherBool; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct OtherDate + { + struct _alias_t + { + static constexpr const char _literal[] = "other_date"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T otherDate; + T& operator()() + { + return otherDate; + } + const T& operator()() const + { + return otherDate; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + struct OtherDateTime + { + struct _alias_t + { + static constexpr const char _literal[] = "other_date_time"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T otherDateTime; + T& operator()() + { + return otherDateTime; + } + const T& operator()() const + { + return otherDateTime; + } + }; + }; + using _traits = sqlpp::make_traits; + }; + } + + struct TabAllTypes : sqlpp::table_t + { + struct _alias_t + { + static constexpr const char _literal[] = "tab_all_types"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T tabAllTypes; + T& operator()() + { + return tabAllTypes; + } + const T& operator()() const + { + return tabAllTypes; + } + }; + }; + }; +} +#endif diff --git a/test_static_asserts/AssertTables.sql b/test_static_asserts/AssertTables.sql new file mode 100644 index 00000000..17cf1cf4 --- /dev/null +++ b/test_static_asserts/AssertTables.sql @@ -0,0 +1,43 @@ +-- +-- Copyright (c) 2015-2015, 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_all_types +( + some_string varchar(255), + some_int bigint, + some_float double, + some_bool bool, + some_date date, + some_date_time datetime + other_string varchar(255), + other_int bigint, + other_float double, + other_bool bool, + other_date date, + other_date_time datetime +); + + diff --git a/test_static_asserts/CMakeLists.txt b/test_static_asserts/CMakeLists.txt index 6722cb9b..34d5a051 100644 --- a/test_static_asserts/CMakeLists.txt +++ b/test_static_asserts/CMakeLists.txt @@ -30,4 +30,6 @@ endfunction() test_compile(aggregates) test_compile(insert) +test_compile(date) +test_compile(date_time) diff --git a/test_static_asserts/date.cpp b/test_static_asserts/date.cpp new file mode 100644 index 00000000..ea7dc9e1 --- /dev/null +++ b/test_static_asserts/date.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015-2015, 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 +#include +#include "AssertTables.h" +#include + +namespace +{ + constexpr auto t = test::TabAllTypes{}; + + template + void print_type_on_error(std::true_type) + { + } + + template + void print_type_on_error(std::false_type) + { + T::_print_me_; + } + + template + void static_check_comparison(const Operand& operand) + { + using CheckResult = sqlpp::check_rhs_comparison_operand_t; + using ExpectedCheckResult = std::is_same; + static_assert(ExpectedCheckResult::value, "Unexpected check result"); + print_type_on_error(ExpectedCheckResult{}); + + using ReturnType = sqlpp::detail::make_type_set_t< + decltype(t.someDate < operand), decltype(t.someDate <= operand), decltype(t.someDate == operand), + decltype(t.someDate != operand), decltype(t.someDate >= operand), decltype(t.someDate > operand), + decltype(t.someDate.in(operand)), decltype(t.someDate.in(operand, operand)), + decltype(t.someDate.not_in(operand)), decltype(t.someDate.not_in(operand, operand))>; + using ExpectedReturnType = + sqlpp::logic::all_t>::value>; + static_assert(ExpectedReturnType::value, "Unexpected return type"); + print_type_on_error(ExpectedReturnType{}); + } + + void allowed_comparands() + { + static_check_comparison(std::chrono::system_clock::now()); + static_check_comparison(t.someDate); + static_check_comparison(t.someDateTime); + } + + void disallowed_comparands() + { + static_check_comparison(17); + static_check_comparison('a'); + static_check_comparison(std::string("a")); + static_check_comparison(t); + static_check_comparison(t.someBool); + static_check_comparison(t.someFloat); + static_check_comparison(t.someInt); + static_check_comparison(t.someString); + } +} + +int main(int, char**) +{ + allowed_comparands(); + disallowed_comparands(); +} diff --git a/test_static_asserts/date_time.cpp b/test_static_asserts/date_time.cpp new file mode 100644 index 00000000..1b184208 --- /dev/null +++ b/test_static_asserts/date_time.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015-2015, 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 +#include +#include "AssertTables.h" +#include + +namespace +{ + constexpr auto t = test::TabAllTypes{}; + + template + void print_type_on_error(std::true_type) + { + } + + template + void print_type_on_error(std::false_type) + { + T::_print_me_; + } + + template + void static_check_comparison(const Operand& operand) + { + using CheckResult = sqlpp::check_rhs_comparison_operand_t; + using ExpectedCheckResult = std::is_same; + static_assert(ExpectedCheckResult::value, "Unexpected check result"); + print_type_on_error(ExpectedCheckResult{}); + + using ReturnType = sqlpp::detail::make_type_set_t< + decltype(t.someDateTime < operand), decltype(t.someDateTime <= operand), decltype(t.someDateTime == operand), + decltype(t.someDateTime != operand), decltype(t.someDateTime >= operand), decltype(t.someDateTime > operand), + decltype(t.someDateTime.in(operand)), decltype(t.someDateTime.in(operand, operand)), + decltype(t.someDateTime.not_in(operand)), decltype(t.someDateTime.not_in(operand, operand))>; + using ExpectedReturnType = + sqlpp::logic::all_t>::value>; + static_assert(ExpectedReturnType::value, "Unexpected return type"); + print_type_on_error(ExpectedReturnType{}); + } + + void allowed_comparands() + { + static_check_comparison(std::chrono::system_clock::now()); + static_check_comparison(t.someDate); + static_check_comparison(t.someDateTime); + } + + void disallowed_comparands() + { + static_check_comparison(17); + static_check_comparison('a'); + static_check_comparison(std::string("a")); + static_check_comparison(t); + static_check_comparison(t.someBool); + static_check_comparison(t.someFloat); + static_check_comparison(t.someInt); + static_check_comparison(t.someString); + } +} + +int main(int, char**) +{ + allowed_comparands(); + disallowed_comparands(); +} diff --git a/tests/sample.sql b/tests/sample.sql index cdb10660..fc420fd0 100644 --- a/tests/sample.sql +++ b/tests/sample.sql @@ -1,17 +1,17 @@ /* * Copyright (c) 2013-2015, 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