diff --git a/.gitignore b/.gitignore index 485dee64..c844e265 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea +CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index 56ee04e2..0b15323e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,11 @@ install(TARGETS sqlpp11 EXPORT Sqlpp11Targets ) +install(PROGRAMS "${PROJECT_SOURCE_DIR}/scripts/ddl2cpp" + RENAME sqlpp11-ddl2cpp + DESTINATION bin +) + include(CMakePackageConfigHelpers) write_basic_package_version_file( @@ -113,4 +118,4 @@ if(ENABLE_TESTS) add_subdirectory(test_static_asserts) add_subdirectory(test_constraints) add_subdirectory(test_scripts) -endif() \ No newline at end of file +endif() diff --git a/cmake/Sqlpp11Config.cmake b/cmake/Sqlpp11Config.cmake index 015ab4b6..720fef2d 100644 --- a/cmake/Sqlpp11Config.cmake +++ b/cmake/Sqlpp11Config.cmake @@ -29,3 +29,17 @@ include(CMakeFindDependencyMacro) find_dependency(HinnantDate REQUIRED) include("${CMAKE_CURRENT_LIST_DIR}/Sqlpp11Targets.cmake") + +# Import "ddl2cpp" script +if(TARGET sqlpp11::ddl2cpp) + message(FATAL_ERROR "Target sqlpp11::ddl2cpp already defined") +endif() +get_filename_component(sqlpp11_ddl2cpp_location "${CMAKE_CURRENT_LIST_DIR}/../../../bin/sqlpp11-ddl2cpp" REALPATH) +if(NOT EXISTS "${sqlpp11_ddl2cpp_location}") + message(FATAL_ERROR "The imported target sqlpp11::ddl2cpp references the file '${sqlpp11_ddl2cpp_location}' but this file does not exists.") +endif() +add_executable(sqlpp11::ddl2cpp IMPORTED) +set_target_properties(sqlpp11::ddl2cpp PROPERTIES + IMPORTED_LOCATION "${sqlpp11_ddl2cpp_location}" +) +unset(sqlpp11_ddl2cpp_location) diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index f4665b73..c924f964 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -127,7 +127,7 @@ namespace sqlpp auto operator==(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -136,7 +136,7 @@ namespace sqlpp auto operator!=(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -145,7 +145,7 @@ namespace sqlpp auto operator<(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -154,7 +154,7 @@ namespace sqlpp auto operator<=(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -163,7 +163,7 @@ namespace sqlpp auto operator>(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -172,7 +172,7 @@ namespace sqlpp auto operator>=(T t) const -> _new_binary_expression_t { using rhs = wrap_operand_t; - check_comparison_t::_(); + check_comparison_t{}; return {*static_cast(this), rhs{t}}; } @@ -205,98 +205,98 @@ namespace sqlpp template auto in(T... t) const -> typename _new_nary_expression::type { - check_in_t...>::_(); + check_in_t...>{}; return {*static_cast(this), typename wrap_operand::type{t}...}; } template auto not_in(T... t) const -> typename _new_nary_expression::type { - check_in_t...>::_(); + check_in_t...>{}; return {*static_cast(this), typename wrap_operand::type{t}...}; } template auto operator not() const -> return_type_not_t { - return_type_not::check::_(); + typename return_type_not::check{}; return {*static_cast(this)}; } template auto operator and(const R& r) const -> return_type_and_t { - return_type_and::check::_(); + typename return_type_and::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator&(const R& r) const -> return_type_bitwise_and_t { - return_type_bitwise_and::check::_(); + typename return_type_bitwise_and::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator|(const R& r) const -> return_type_bitwise_or_t { - return_type_bitwise_or::check::_(); + typename return_type_bitwise_or::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator or(const R& r) const -> return_type_or_t { - return_type_or::check::_(); + typename return_type_or::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator+(const R& r) const -> return_type_plus_t { - return_type_plus::check::_(); + typename return_type_plus::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator-(const R& r) const -> return_type_minus_t { - return_type_minus::check::_(); + typename return_type_minus::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator*(const R& r) const -> return_type_multiplies_t { - return_type_multiplies::check::_(); + typename return_type_multiplies::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator/(const R& r) const -> return_type_divides_t { - return_type_divides::check::_(); + typename return_type_divides::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator%(const R& r) const -> return_type_modulus_t { - return_type_modulus::check::_(); + typename return_type_modulus::check{}; return {*static_cast(this), wrap_operand_t{r}}; } template auto operator+() const -> return_type_unary_plus_t { - return_type_unary_plus::check::_(); + typename return_type_unary_plus::check{}; return {*static_cast(this)}; } template auto operator-() const -> return_type_unary_minus_t { - return_type_unary_minus::check::_(); + typename return_type_unary_minus::check{}; return {*static_cast(this)}; } }; diff --git a/include/sqlpp11/consistent.h b/include/sqlpp11/consistent.h index 6dbc8eb9..0b38593c 100644 --- a/include/sqlpp11/consistent.h +++ b/include/sqlpp11/consistent.h @@ -33,7 +33,6 @@ namespace sqlpp { struct consistent_t : std::true_type { - static void _(){}; }; } // namespace sqlpp diff --git a/include/sqlpp11/data_types.h b/include/sqlpp11/data_types.h index c9776077..b447a214 100644 --- a/include/sqlpp11/data_types.h +++ b/include/sqlpp11/data_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, Roland Bock, Aaron Bishop + * Copyright (c) 2013-2017, Roland Bock, Aaron Bishop * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,6 +27,7 @@ #ifndef SQLPP11_DATA_TYPES_H #define SQLPP11_DATA_TYPES_H +#include #include #include #include diff --git a/include/sqlpp11/data_types/blob.h b/include/sqlpp11/data_types/blob.h new file mode 100644 index 00000000..3196dd31 --- /dev/null +++ b/include/sqlpp11/data_types/blob.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_H +#define SQLPP_BLOB_H + +#include +#include +#include +#include +#include +#include +#include + +// blob specific functions +#include +#include + +#endif diff --git a/include/sqlpp11/data_types/blob/column_operators.h b/include/sqlpp11/data_types/blob/column_operators.h new file mode 100644 index 00000000..6c4f88da --- /dev/null +++ b/include/sqlpp11/data_types/blob/column_operators.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_COLUMN_OPERATORS_H +#define SQLPP_BLOB_COLUMN_OPERATORS_H + +#include +#include +#include +#include + +namespace sqlpp +{ + template + struct concat_t; + + template + struct column_operators + { + template + using _is_valid_operand = is_valid_operand; + + 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), + concat_t>{*static_cast(this), rhs{t}}}; + } + }; +} +#endif diff --git a/include/sqlpp11/data_types/blob/data_type.h b/include/sqlpp11/data_types/blob/data_type.h new file mode 100644 index 00000000..c97a1380 --- /dev/null +++ b/include/sqlpp11/data_types/blob/data_type.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_DATA_TYPE_H +#define SQLPP_BLOB_DATA_TYPE_H + +#include + +#include +#include + +namespace sqlpp +{ + struct blob + { + using _traits = make_traits; + using _cpp_value_type = std::vector; + + template + using _is_valid_operand = ::sqlpp::logic::any_t::value, is_text_t::value>; + }; + + using blob = blob; + using mediumblob = blob; +} +#endif diff --git a/include/sqlpp11/data_types/blob/expression_operators.h b/include/sqlpp11/data_types/blob/expression_operators.h new file mode 100644 index 00000000..210c57f6 --- /dev/null +++ b/include/sqlpp11/data_types/blob/expression_operators.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_EXPRESSION_OPERATORS_H +#define SQLPP_BLOB_EXPRESSION_OPERATORS_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + template + struct like_t; + + template + struct return_type_like> + { + using check = consistent_t; + using type = like_t, wrap_operand_t>; + }; + + template + struct return_type_like> + { + using check = consistent_t; + using type = like_t, wrap_operand_t>; + }; + + template + struct expression_operators : public basic_expression_operators + { + template + using _is_valid_operand = is_valid_operand; + + template + auto like(const R& r) const -> return_type_like_t + { + typename return_type_like::check{}; + return {*static_cast(this), wrap_operand_t{r}}; + } + }; +} // namespace sqlpp +#endif diff --git a/include/sqlpp11/data_types/blob/operand.h b/include/sqlpp11/data_types/blob/operand.h new file mode 100644 index 00000000..ad8d237b --- /dev/null +++ b/include/sqlpp11/data_types/blob/operand.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_OPERAND_H +#define SQLPP_BLOB_OPERAND_H + +#include +#include +#include +#include + +namespace sqlpp +{ + struct blob; + + struct blob_operand : public alias_operators + { + using _traits = make_traits; + using _nodes = detail::type_vector<>; + using _is_aggregate_expression = std::true_type; + + using _value_t = std::vector; + + blob_operand() : _t{} + { + } + + blob_operand(_value_t t) : _t(t) + { + } + + template + blob_operand(const std::array& t) : _t(t.begin(), t.end()) + { + } + + blob_operand(const blob_operand&) = default; + blob_operand(blob_operand&&) = default; + blob_operand& operator=(const blob_operand&) = default; + blob_operand& operator=(blob_operand&&) = default; + ~blob_operand() = default; + + bool _is_trivial() const + { + return _t.empty(); + } + + _value_t _t; + }; + + template + struct serializer_t + { + using _serialize_check = consistent_t; + using Operand = blob_operand; + + static Context& _(const Operand& t, Context& context) + { + constexpr char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + context << "x'"; + for (const auto c : t._t) + { + context << hexChars[c >> 4] << hexChars[c & 0x0F]; + } + context << '\''; + + return context; + } + }; +} +#endif diff --git a/include/sqlpp11/data_types/blob/parameter_value.h b/include/sqlpp11/data_types/blob/parameter_value.h new file mode 100644 index 00000000..e2e70a4c --- /dev/null +++ b/include/sqlpp11/data_types/blob/parameter_value.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_PARAMETER_VALUE_H +#define SQLPP_BLOB_PARAMETER_VALUE_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + template <> + struct parameter_value_t : public parameter_value_base + { + using base = parameter_value_base; + using base::base; + using base::operator=; + + template + void _bind(Target& target, size_t index) const + { + target._bind_blob_parameter(index, &_value, _is_null); + } + }; +} +#endif diff --git a/include/sqlpp11/data_types/blob/result_field.h b/include/sqlpp11/data_types/blob/result_field.h new file mode 100644 index 00000000..a790c714 --- /dev/null +++ b/include/sqlpp11/data_types/blob/result_field.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_RESULT_FIELD_H +#define SQLPP_BLOB_RESULT_FIELD_H + +#include +#include +#include +#include +#include +#include + +namespace sqlpp +{ + template + struct result_field_t> + : public result_field_base> + { + const uint8_t* blob{nullptr}; // Non-owning + size_t len{}; + + template + void _bind(Target& target, size_t index) + { + target._bind_blob_result(index, &blob, &len); + if (blob) + this->_value.assign(blob, blob+len); + else + this->_value.clear(); + this->_is_null = (blob == nullptr); + } + + template + void _post_bind(Target& target, size_t index) + { + target._post_bind_blob_result(index, &blob, &len); + if (blob) + this->_value.assign(blob, blob+len); + else + this->_value.clear(); + this->_is_null = (blob == nullptr); + } + }; + + template + inline std::ostream& operator<<( + std::ostream& os, const result_field_t>& e) + { + if (e.is_null() and not NullIsTrivialValue) + { + return os << "NULL"; + } + else + { + return os << e.value(); + } + } +} +#endif diff --git a/include/sqlpp11/data_types/blob/wrap_operand.h b/include/sqlpp11/data_types/blob/wrap_operand.h new file mode 100644 index 00000000..ba065e21 --- /dev/null +++ b/include/sqlpp11/data_types/blob/wrap_operand.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2017, 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_BLOB_WRAP_OPERAND_H +#define SQLPP_BLOB_WRAP_OPERAND_H + +#include +#include +#include +#include + +namespace sqlpp +{ + struct blob_operand; + + template <> + struct wrap_operand, void> + { + using type = blob_operand; + }; + + template + struct wrap_operand, void> + { + using type = blob_operand; + }; +} +#endif diff --git a/include/sqlpp11/data_types/text/data_type.h b/include/sqlpp11/data_types/text/data_type.h index d3ed84eb..de8fc0e1 100644 --- a/include/sqlpp11/data_types/text/data_type.h +++ b/include/sqlpp11/data_types/text/data_type.h @@ -40,7 +40,6 @@ namespace sqlpp using _is_valid_operand = is_text_t; }; - using blob = text; using varchar = text; using char_ = text; using binary = text; diff --git a/include/sqlpp11/data_types/text/expression_operators.h b/include/sqlpp11/data_types/text/expression_operators.h index 6802a795..440ce546 100644 --- a/include/sqlpp11/data_types/text/expression_operators.h +++ b/include/sqlpp11/data_types/text/expression_operators.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace sqlpp { @@ -40,15 +41,6 @@ namespace sqlpp template struct like_t; - template - struct return_type_like - { - using check = assert_valid_operands; - using type = bad_expression; - }; - template - using return_type_like_t = typename return_type_like::type; - template struct return_type_like> { @@ -65,7 +57,7 @@ namespace sqlpp template auto like(const R& r) const -> return_type_like_t { - return_type_like::check::_(); + typename return_type_like::check{}; return {*static_cast(this), wrap_operand_t{r}}; } }; diff --git a/include/sqlpp11/data_types/text/return_type_like.h b/include/sqlpp11/data_types/text/return_type_like.h new file mode 100644 index 00000000..8262c567 --- /dev/null +++ b/include/sqlpp11/data_types/text/return_type_like.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013-2017, 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_RETURN_TYPE_LIKE_H +#define SQLPP_RETURN_TYPE_LIKE_H + +#include + +namespace sqlpp +{ + template + struct return_type_like + { + using check = assert_valid_operands; + using type = bad_expression; + }; + template + using return_type_like_t = typename return_type_like::type; +} + +#endif diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 58aeff9a..ff11ac3d 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -27,6 +27,7 @@ #ifndef SQLPP11_FUNCTIONS_H #define SQLPP11_FUNCTIONS_H +#include #include #include #include diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index 2c67b021..feceddc3 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -123,8 +123,8 @@ namespace sqlpp template struct insert_list_data_t { - insert_list_data_t(Assignments... assignments) - : _assignments(assignments...), _columns(assignments._lhs...), _values(assignments._rhs...) + insert_list_data_t(std::tuple assignments) + : _assignments(assignments), _columns( columns_from_tuple(assignments) ), _values( values_from_tuple(assignments) ) { } @@ -140,6 +140,31 @@ namespace sqlpp std::tuple...> _values; interpretable_list_t _dynamic_columns; interpretable_list_t _dynamic_values; + private: + template< size_t... Indexes > + auto columns_from_tuple( detail::index_sequence, std::tuple assignments ) -> decltype (_columns) + { + (void) assignments; + return decltype(_columns)(std::get(assignments)._lhs...); + } + + auto columns_from_tuple(std::tuple assignments) -> decltype (_columns) { + const auto seq = detail::make_index_sequence{}; + return columns_from_tuple(seq, assignments); + } + + template< size_t... Indexes > + auto values_from_tuple( detail::index_sequence, std::tuple assignments ) -> decltype(_values) + { + (void) assignments; + return decltype(_values)(std::get(assignments)._rhs...); + } + + auto values_from_tuple( std::tuple assignments ) -> decltype(_values) + { + const auto seq = detail::make_index_sequence{}; + return values_from_tuple(seq, assignments); + } }; SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_assignments_t, "at least one argument is not an assignment in set()"); @@ -511,16 +536,32 @@ namespace sqlpp -> _new_statement_t, insert_list_t> { using Check = check_insert_static_set_t; - return _set_impl(Check{}, assignments...); + return _set_impl(Check{}, std::make_tuple(assignments...)); } + template + auto set(std::tuple assignments) const + -> _new_statement_t, insert_list_t> + { + using Check = check_insert_static_set_t; + return _set_impl(Check{}, assignments); + } template auto dynamic_set(Assignments... assignments) const -> _new_statement_t, insert_list_t<_database_t, Assignments...>> { using Check = check_insert_dynamic_set_t<_database_t, Assignments...>; - return _set_impl<_database_t>(Check{}, assignments...); + return _set_impl<_database_t>(Check{}, std::make_tuple(assignments...)); + } + + template + auto dynamic_set(std::tuple assignments) const + -> _new_statement_t, + insert_list_t<_database_t, Assignments...>> + { + using Check = check_insert_dynamic_set_t<_database_t, Assignments...>; + return _set_impl<_database_t>(Check{}, assignments); } private: @@ -548,11 +589,11 @@ namespace sqlpp auto _set_impl(Check, Assignments... assignments) const -> inconsistent; template - auto _set_impl(consistent_t /*unused*/, Assignments... assignments) const + auto _set_impl(consistent_t /*unused*/,std::tuple assignments) const -> _new_statement_t> { return {static_cast&>(*this), - insert_list_data_t{assignments...}}; + insert_list_data_t{assignments}}; } }; }; diff --git a/include/sqlpp11/ppgen.h b/include/sqlpp11/ppgen.h index 0fd267a6..f602ede5 100644 --- a/include/sqlpp11/ppgen.h +++ b/include/sqlpp11/ppgen.h @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include diff --git a/include/sqlpp11/ppgen/colops/floating_point.h b/include/sqlpp11/ppgen/colops/floating_point.h index bd8881f3..2980815e 100644 --- a/include/sqlpp11/ppgen/colops/floating_point.h +++ b/include/sqlpp11/ppgen/colops/floating_point.h @@ -34,6 +34,11 @@ #define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_float(...) \ ::sqlpp::floating_point +#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_real \ + PROC_real +#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_real(...) \ + ::sqlpp::floating_point + #define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_double \ PROC_double #define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_double(...) \ diff --git a/include/sqlpp11/ppgen/colops/unsigned_integer.h b/include/sqlpp11/ppgen/colops/unsigned_integer.h new file mode 100644 index 00000000..08f54411 --- /dev/null +++ b/include/sqlpp11/ppgen/colops/unsigned_integer.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014-2017, Damien COJAN + * 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. + */ + +// clang-format off + +#ifndef _sqlpp__ppgen__colops__unsigned_integer_h +#define _sqlpp__ppgen__colops__unsigned_integer_h + +#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_tinyint_unsigned \ + PROC_tinyint_unsigned +#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_tinyint_unsigned(...) \ + ::sqlpp::tinyint_unsigned + +#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_smallint_unsigned \ + PROC_smallint_unsigned +#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_smallint_unsigned(...) \ + ::sqlpp::smallint_unsigned + +#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_int_unsigned \ + PROC_int_unsigned +#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_int_unsigned(...) \ + ::sqlpp::integer_unsigned + +#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_bigint_unsigned \ + PROC_bigint_unsigned +#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_bigint_unsigned(...) \ + ::sqlpp::bigint_unsigned + +#endif // _sqlpp__ppgen__colops__unsigned_integer_h diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 4f0a2051..7db9ac53 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, Roland Bock, Aaron Bishop + * Copyright (c) 2013-2017, Roland Bock, Aaron Bishop * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -63,6 +63,10 @@ namespace sqlpp }; // data types + struct blob; + template + using is_blob_t = std::is_same, blob>; + struct boolean; template using is_boolean_t = std::is_same, boolean>; diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index 768f9d13..b27d008e 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -38,7 +38,7 @@ namespace sqlpp template struct update_list_data_t { - update_list_data_t(Assignments... assignments) : _assignments(assignments...) + update_list_data_t(std::tuple assignments ) : _assignments(assignments) { } @@ -258,7 +258,15 @@ namespace sqlpp -> _new_statement_t, update_list_t> { using Check = check_update_static_set_t; - return _set_impl(Check{}, assignments...); + return _set_impl(Check{}, std::make_tuple(assignments...)); + } + + template + auto set(std::tuple assignments) const + -> _new_statement_t, update_list_t> + { + using Check = check_update_static_set_t; + return _set_impl(Check{}, assignments); } template @@ -267,7 +275,7 @@ namespace sqlpp update_list_t<_database_t, Assignments...>> { using Check = check_update_dynamic_set_t<_database_t, Assignments...>; - return _set_impl<_database_t>(Check{}, assignments...); + return _set_impl<_database_t>(Check{}, std::make_tuple(assignments...)); } private: @@ -275,11 +283,11 @@ namespace sqlpp auto _set_impl(Check, Assignments... assignments) const -> inconsistent; template - auto _set_impl(consistent_t /*unused*/, Assignments... assignments) const + auto _set_impl(consistent_t /*unused*/, std::tuple assignments) const -> _new_statement_t> { return {static_cast&>(*this), - update_list_data_t{assignments...}}; + update_list_data_t{assignments}}; } }; }; diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 838ba7a2..a39af9bf 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -45,17 +45,29 @@ from pyparsing import CaselessLiteral, Literal, SkipTo, restOfLine, oneOf, ZeroO # HELPERS def get_include_guard_name(namespace, inputfile): - val = re.sub("[^A-Za-z]+", "_", namespace + '_' + os.path.basename(inputfile)) + val = re.sub("[^A-Za-z0-9]+", "_", namespace + '_' + os.path.basename(inputfile)) return val.upper() +def identity_naming_func(s): + return s -def repl_func(m): +def repl_camel_case_func(m): if m.group(1) == '_': return m.group(2).upper() else: return m.group(1) + m.group(2).upper() +def class_name_naming_func(s): + return re.sub("(^|\s|[_0-9])(\S)", repl_camel_case_func, s) + + +def member_name_naming_func(s): + return re.sub("(\s|_|[0-9])(\S)", repl_camel_case_func, s) + +toClassName = class_name_naming_func +toMemberName = member_name_naming_func + def repl_func_for_args(m): if m.group(1) == '-': return m.group(2).upper() @@ -113,6 +125,7 @@ optionalArgs = { '-fail-on-parse': "abort instead of silent genereation of unusable headers", # failOnParse = True '-warn-on-parse': "warn about unusable headers, but continue", # warnOnParse = True '-auto-id': "Assume column 'id' to have an automatic value as if AUTO_INCREMENT was specified (e.g. implicit for SQLite ROWID)", # autoId = True + '-identity-naming': "Use table and column names from the ddl (defaults to UpperCamelCase for tables and lowerCamelCase for columns", # identityNaming = True '-help': "show this help" } @@ -129,6 +142,7 @@ failOnParse = False warnOnParse = False parseError = "Parsing error, possible reason: can't parse default value for a field" autoId = False +identityNaming = False if len(sys.argv) >= 4: @@ -143,6 +157,10 @@ if len(sys.argv) >= 4: else: pass +if identityNaming: + toClassName = identity_naming_func + toMemberName = identity_naming_func + pathToDdl = sys.argv[firstPositional] pathToHeader = sys.argv[firstPositional + 1] + '.h' @@ -168,7 +186,16 @@ negativeSign = Literal('-') ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) ddlTerm = Word(alphanums + "_$") ddlName = Or([ddlTerm, ddlString]) +ddlMathOp = Word("+><=-") +ddlBoolean = Or([ddlWord("AND"), ddlWord("OR"), ddlWord("NOT")]) ddlArguments = "(" + delimitedList(Or([ddlString, ddlTerm, ddlNum])) + ")" +ddlMathCond = "(" + delimitedList( + Or([ + Group(ddlName + ddlMathOp + ddlName), + Group(ddlName + ddlWord("NOT") + ddlWord("NULL")), + ]), + delim=ddlBoolean) + ")" + ddlUnsigned = ddlWord("unsigned").setResultsName("isUnsigned") ddlNotNull = Group(ddlWord("NOT") + ddlWord("NULL")).setResultsName("notNull") ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue") @@ -186,8 +213,9 @@ ddlConstraint = Or([ ddlWord("KEY"), ddlWord("INDEX"), ddlWord("UNIQUE"), + ddlWord("CHECK") ]) -ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlUnsigned, ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlFunctionWord("NOW"), ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) +ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlUnsigned, ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlFunctionWord("NOW"), ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments, ddlMathCond]))) ddlIfNotExists = Optional(Group(ddlWord("IF") + ddlWord("NOT") + ddlWord("EXISTS")).setResultsName("ifNotExists")) createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlIfNotExists + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create") #ddlString.setDebug(True) #uncomment to debug pyparsing @@ -202,15 +230,20 @@ types = { 'tinyint': 'tinyint', 'smallint': 'smallint', 'smallserial': 'smallint', # PostgreSQL + 'int2': 'smallint', #PostgreSQL 'integer': 'integer', 'int': 'integer', 'serial': 'integer', # PostgreSQL + 'int4': 'integer', #PostgreSQL 'mediumint' : 'integer', 'bigint': 'bigint', 'bigserial': 'bigint', # PostgreSQL + 'int8': 'bigint', #PostgreSQL 'char': 'char_', 'varchar': 'varchar', + 'character varying': 'varchar', #PostgreSQL 'text': 'text', + 'clob': 'text', 'tinyblob': 'blob', 'blob': 'blob', 'mediumblob': 'blob', @@ -218,13 +251,22 @@ types = { 'bool': 'boolean', 'boolean': 'boolean', 'double': 'floating_point', + 'float8': 'floating_point', # PostgreSQL 'float': 'floating_point', - 'real': 'floating_point', + 'float4': 'floating_point', # PostgreSQL + 'numeric': 'floating_point', # PostgreSQL 'date': 'day_point', 'datetime': 'time_point', + 'time without time zone': 'time_point', # PostgreSQL + 'time with time zone': 'time_point', # PostgreSQL 'timestamp': 'time_point', + 'timestamp without time zone': 'time_point', # PostgreSQL + 'timestamp with time zone': 'time_point', # PostgreSQL + 'timestamptz': 'time_point', # PostgreSQL 'enum': 'text', # MYSQL 'set': 'text', # MYSQL, + 'json' : 'text', # PostgreSQL + 'jsonb' : 'text', # PostgreSQL 'tinyint unsigned': 'tinyint_unsigned', #MYSQL 'smallint unsigned': 'smallint_unsigned', #MYSQL 'integer unsigned': 'integer_unsigned', #MYSQL diff --git a/test_scripts/CMakeLists.txt b/test_scripts/CMakeLists.txt index fd3c482a..f2f4c34f 100644 --- a/test_scripts/CMakeLists.txt +++ b/test_scripts/CMakeLists.txt @@ -58,16 +58,26 @@ if (${PYTHONINTERP_FOUND}) "${CMAKE_CURRENT_BINARY_DIR}/fail" test) - set(sqlpp.test.generated.sample "${CMAKE_CURRENT_BINARY_DIR}/Sample") - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - add_custom_command( - OUTPUT "${sqlpp.test.generated.sample}.h" - COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" "${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql" "${sqlpp.test.generated.sample}" test - DEPENDS "${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql" - VERBATIM) + foreach(sample_name sample sample_identity_naming) + set(sqlpp.test.generated.sample.include "${CMAKE_CURRENT_BINARY_DIR}/${sample_name}") + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + set(use_identity_naming) + if(sample_name STREQUAL "sample_identity_naming") + set(use_identity_naming -identity-naming) + endif() + add_custom_command( + OUTPUT "${sqlpp.test.generated.sample.include}.h" + COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" + ${use_identity_naming} + "${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql" + "${sqlpp.test.generated.sample.include}" + test + DEPENDS "${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql" + VERBATIM) - add_executable(sqlpp.test.compiled.sample sample.cpp "${sqlpp.test.generated.sample}.h") - target_link_libraries(sqlpp.test.compiled.sample PRIVATE sqlpp11) + add_executable(sqlpp.test.compiled.${sample_name} ${sample_name}.cpp "${sqlpp.test.generated.sample.include}.h") + target_link_libraries(sqlpp.test.compiled.${sample_name} PRIVATE sqlpp11) + endforeach() endif() endif() diff --git a/test_scripts/sample.cpp b/test_scripts/sample.cpp index 6f48646e..62900760 100644 --- a/test_scripts/sample.cpp +++ b/test_scripts/sample.cpp @@ -1,5 +1,15 @@ -#include +#include int main() { + test::TabFoo tab_foo; + tab_foo.delta = "delta"; + tab_foo.Epsilon = 42; + tab_foo.omega = 3.14; + + test::TabBar tab_bar; + tab_bar.alpha = 42; + tab_bar.beta = "beta"; + tab_bar.gamma = true; + tab_bar.delta = 42; } diff --git a/test_scripts/sample_identity_naming.cpp b/test_scripts/sample_identity_naming.cpp new file mode 100644 index 00000000..4e745463 --- /dev/null +++ b/test_scripts/sample_identity_naming.cpp @@ -0,0 +1,15 @@ +#include + +int main() +{ + test::tab_foo tab_foo; + tab_foo.delta = "delta"; + tab_foo._epsilon = 42; + tab_foo.omega = 3.14; + + test::tab_bar tab_bar; + tab_bar.alpha = 42; + tab_bar.beta = "beta"; + tab_bar.gamma = true; + tab_bar.delta = 42; +} diff --git a/test_serializer/Blob.cpp b/test_serializer/Blob.cpp new file mode 100644 index 00000000..458de030 --- /dev/null +++ b/test_serializer/Blob.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, 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 "compare.h" +#include "Sample.h" +#include + +#include +#include + +namespace +{ + /* + auto getTrue() -> std::string + { + MockDb::_serializer_context_t printer = {}; + return serialize(sqlpp::value(true), printer).str(); + } + */ + + auto getFalse() -> std::string + { + MockDb::_serializer_context_t printer = {}; + return serialize(sqlpp::value(false), printer).str(); + } + + auto toByteVector(const std::string& s) -> std::vector + { + return std::vector(s.begin(), s.end()); + } +} + +int Blob(int, char* []) +{ + const auto foo = test::TabFoo{}; + // const auto bar = test::TabBar{}; + + // Unconditionally + compare(__LINE__, select(foo.book).from(foo).where(foo.book == toByteVector("john doe")), + "SELECT tab_foo.book FROM tab_foo WHERE (tab_foo.book=x'6A6F686E20646F65')"); + + std::array arr{{'j', 'o', 'h', 'n', ' ', 'd', 'o', 'e'}}; + compare(__LINE__, select(foo.book).from(foo).where(foo.book == arr), + "SELECT tab_foo.book FROM tab_foo WHERE (tab_foo.book=x'6A6F686E20646F65')"); + + // Never + compare(__LINE__, where(sqlpp::value(false)), " WHERE " + getFalse()); + + return 0; +} diff --git a/test_serializer/CMakeLists.txt b/test_serializer/CMakeLists.txt index 2246b936..042908e0 100644 --- a/test_serializer/CMakeLists.txt +++ b/test_serializer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2016, Roland Bock +# Copyright (c) 2013-2017, Roland Bock # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -23,14 +23,15 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set(test_serializer_names - CustomQuery As + Blob + CustomQuery + ForUpdate From In Insert TableAlias Where - ForUpdate ) create_test_sourcelist(test_serializer_sources test_serializer_main.cpp ${test_serializer_names}) diff --git a/tests/Insert.cpp b/tests/Insert.cpp index 0c6e61b7..43b7c1d0 100644 --- a/tests/Insert.cpp +++ b/tests/Insert.cpp @@ -71,10 +71,15 @@ int Insert(int, char* []) db(multi_insert); + auto values=[&t](){ + return std::make_tuple(t.gamma = true, t.delta = sqlpp::tvin(0)); + }; + db(insert_into(t).set(t.gamma = true, t.delta = sqlpp::verbatim("17+4"))); db(insert_into(t).set(t.gamma = true, t.delta = sqlpp::null)); db(insert_into(t).set(t.gamma = true, t.delta = sqlpp::default_value)); db(insert_into(t).set(t.gamma = true, t.delta = sqlpp::tvin(0))); + db(insert_into(t).set(values())); return 0; } diff --git a/tests/MockDb.h b/tests/MockDb.h index 05271893..c3a25ef0 100644 --- a/tests/MockDb.h +++ b/tests/MockDb.h @@ -36,9 +36,10 @@ #include // an object to store internal Mock flags and values to validate in tests -struct InternalMockData { - sqlpp::isolation_level _last_isolation_level; - sqlpp::isolation_level _default_isolation_level; +struct InternalMockData +{ + sqlpp::isolation_level _last_isolation_level; + sqlpp::isolation_level _default_isolation_level; }; template @@ -254,7 +255,7 @@ struct MockDbT : public sqlpp::connection void start_transaction() { - _mock_data._last_isolation_level = _mock_data._default_isolation_level; + _mock_data._last_isolation_level = _mock_data._default_isolation_level; } void start_transaction(sqlpp::isolation_level level) @@ -264,22 +265,25 @@ struct MockDbT : public sqlpp::connection void set_default_isolation_level(sqlpp::isolation_level level) { - _mock_data._default_isolation_level = level; + _mock_data._default_isolation_level = level; } sqlpp::isolation_level get_default_isolation_level() { - return _mock_data._default_isolation_level; + return _mock_data._default_isolation_level; } void rollback_transaction(bool) - {} + { + } void commit_transaction() - {} + { + } void report_rollback_failure(std::string) - {} + { + } // temporary data store to verify the expected results were produced InternalMockData _mock_data; @@ -470,24 +474,31 @@ struct MockSizeDb : public sqlpp::connection void set_default_isolation_level(sqlpp::isolation_level level) { - _mock_data._default_isolation_level = level; + _mock_data._default_isolation_level = level; } sqlpp::isolation_level get_default_isolation_level() { - return _mock_data._default_isolation_level; + return _mock_data._default_isolation_level; } void rollback_transaction(bool) - {} + { + } void commit_transaction() - {} + { + } void report_rollback_failure(std::string) - {} + { + } // temporary data store to verify the expected results were produced InternalMockData _mock_data; }; + +using MockDb = MockDbT; +using EnforceDb = MockDbT; + #endif diff --git a/tests/Ppgen.cpp b/tests/Ppgen.cpp index 9093e473..70332796 100644 --- a/tests/Ppgen.cpp +++ b/tests/Ppgen.cpp @@ -52,6 +52,8 @@ SQLPP_DECLARE_TABLE( (id , int , SQLPP_PRIMARY_KEY) (name , varchar(255), SQLPP_NOT_NULL ) (feature, int , SQLPP_NOT_NULL ) + (age , int_unsigned, SQLPP_NOT_NULL ) + (level , real , SQLPP_NOT_NULL ) ) SQLPP_DECLARE_TABLE( @@ -76,14 +78,29 @@ int Ppgen(int, char* []) 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); + auto i = insert_into(p).columns(p.name, p.feature, p.age, p.level); + i.values.add(p.name = "Roland" + , p.feature = 1 + , p.age = static_cast(32) + , p.level = 3.14); + i.values.add(p.name = "Zaphod" + , p.feature = sqlpp::default_value + , p.age = static_cast(16) + , p.level = 3.14*2); db(i); - auto pi = db.prepare(insert_into(p).set(p.name = parameter(f.name), p.feature = parameter(p.feature))); + auto pi = db.prepare( + insert_into(p).set( + p.name = parameter(f.name) + ,p.feature = parameter(p.feature) + ,p.age = parameter(p.age) + ,p.level = parameter(p.level) + ) + ); pi.params.name = "likes java"; - pi.params.feature = true; + pi.params.feature = 2; + pi.params.age = 21; + pi.params.level = 3.14; db(pi); return 0; diff --git a/tests/Sample.h b/tests/Sample.h index 15e7ee69..b610d618 100644 --- a/tests/Sample.h +++ b/tests/Sample.h @@ -97,9 +97,31 @@ namespace test }; using _traits = sqlpp::make_traits; }; + struct Book + { + struct _alias_t + { + static constexpr const char _literal[] = "book"; + using _name_t = sqlpp::make_char_sequence; + template + struct _member_t + { + T book; + T& operator()() + { + return book; + } + const T& operator()() const + { + return book; + } + }; + }; + using _traits = sqlpp::make_traits; + }; } - struct TabFoo : sqlpp::table_t + struct TabFoo : sqlpp::table_t { struct _alias_t { diff --git a/tests/Update.cpp b/tests/Update.cpp index 7a4bf569..78d181e9 100644 --- a/tests/Update.cpp +++ b/tests/Update.cpp @@ -63,11 +63,15 @@ int Update(int, char* []) db(u); + auto values=[&t](){ + return std::make_tuple(t.delta += t.alpha, t.beta = "no cake this time"); + }; + db(update(t).set(t.delta = sqlpp::verbatim("17+4")).unconditionally()); db(update(t).set(t.delta = sqlpp::null).unconditionally()); db(update(t).set(t.delta = sqlpp::default_value).unconditionally()); db(update(t).set(t.delta += t.alpha * 2, t.beta += " and cake").unconditionally()); - + db(update(t).set(values()).unconditionally()); return 0; } diff --git a/tests/With.cpp b/tests/With.cpp index 71c2c1c1..dc51b840 100644 --- a/tests/With.cpp +++ b/tests/With.cpp @@ -49,5 +49,11 @@ int With(int, char* []) db(with(y)(select(y.alpha).from(y).unconditionally())); + using ::sqlpp::alias::a; + using ::sqlpp::alias::b; + const auto c = + sqlpp::cte(b).as(select(t.alpha.as(a)).from(t).unconditionally().union_all(select(sqlpp::value(123).as(a)))); + db(with(c)(select(all_of(c)).from(c).unconditionally())); + return 0; }