diff --git a/include/sqlpp11/dynamic.h b/include/sqlpp11/dynamic.h index 3d703081..39b55b65 100644 --- a/include/sqlpp11/dynamic.h +++ b/include/sqlpp11/dynamic.h @@ -78,6 +78,7 @@ namespace sqlpp template using remove_dynamic_t = typename remove_dynamic::type; +#warning: Should not turn Expr to into optional, but just the value type template struct dynamic_to_optional { diff --git a/include/sqlpp11/field_spec.h b/include/sqlpp11/field_spec.h index e08906ae..27c207c1 100644 --- a/include/sqlpp11/field_spec.h +++ b/include/sqlpp11/field_spec.h @@ -44,6 +44,12 @@ namespace sqlpp using cpp_type = result_value_t; }; + template + struct name_tag_of> + { + using type = NameType; + }; + template struct is_field_compatible { diff --git a/include/sqlpp11/operator/comparison_expression.h b/include/sqlpp11/operator/comparison_expression.h index 49049f6e..ac570068 100644 --- a/include/sqlpp11/operator/comparison_expression.h +++ b/include/sqlpp11/operator/comparison_expression.h @@ -62,8 +62,8 @@ namespace sqlpp struct op_is_null; struct op_is_not_null; - struct is_distinct_from; - struct is_not_distinct_from; + struct op_is_distinct_from; + struct op_is_not_distinct_from; template struct value_type_of> { using type = boolean; }; @@ -72,10 +72,10 @@ namespace sqlpp struct value_type_of> { using type = boolean; }; template - struct value_type_of> { using type = boolean; }; + struct value_type_of> { using type = boolean; }; template - struct value_type_of> { using type = boolean; }; + struct value_type_of> { using type = boolean; }; template diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 8b7176a8..65953fef 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -712,13 +712,21 @@ namespace sqlpp using parameters_of = typename detail::parameters_of_impl::type; struct name_tag_base{}; // Used by SQLPP_ALIAS_PROVIDER and ddl2cpp + template + struct name_tag_of_impl + { + using type = no_name_t; + }; + template + struct name_tag_of_impl + { + using type = typename T::_alias_t; + }; + template struct name_tag_of { - using type = typename std::conditional::value, // if T is a name tag - typename T::_alias_t, // then it is embedded, - no_name_t // else, there is no default name - >::type; + using type = typename name_tag_of_impl::value>::type; }; template diff --git a/tests/core/types/CMakeLists.txt b/tests/core/types/CMakeLists.txt index d4da25f8..ce960edc 100644 --- a/tests/core/types/CMakeLists.txt +++ b/tests/core/types/CMakeLists.txt @@ -37,6 +37,7 @@ endfunction() test_compile(any) test_compile(aggregate_functions) test_compile(comparison_expression) +test_compile(dynamic) test_compile(in_expression) test_compile(logical_expression) test_compile(result_row) diff --git a/tests/core/types/dynamic.cpp b/tests/core/types/dynamic.cpp new file mode 100644 index 00000000..6e629ce6 --- /dev/null +++ b/tests/core/types/dynamic.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016-2016, 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 "MockDb.h" +#include "Sample.h" +#include + +namespace +{ + auto db = MockDb{}; +} + +SQLPP_ALIAS_PROVIDER(r_not_null); +SQLPP_ALIAS_PROVIDER(r_maybe_null); + +template +using is_value_type = std::is_same, ValueType>; + +template +void test_dynamic(Value v) +{ + using ValueType = sqlpp::value_type_of_t; + using OptValueType = sqlpp::compat::optional; + + auto v_not_null= dynamic(true, sqlpp::value(v)); + auto v_maybe_null= dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))); + auto v_not_null_alias = dynamic(true, sqlpp::value(v).as(r_not_null)); + auto v_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null)); + + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(sqlpp::has_name::value, ""); + static_assert(sqlpp::has_name::value, ""); + + static_assert(is_value_type, ValueType>::value, ""); + static_assert(is_value_type, OptValueType>::value, ""); + static_assert(is_value_type, ValueType>::value, ""); + static_assert(is_value_type, OptValueType>::value, ""); +} + +int main() +{ + // boolean + test_dynamic(bool{true}); + + // integral + test_dynamic(int8_t{7}); + test_dynamic(int16_t{7}); + test_dynamic(int32_t{7}); + test_dynamic(int64_t{7}); + + // unsigned integral + test_dynamic(uint8_t{7}); + test_dynamic(uint16_t{7}); + test_dynamic(uint32_t{7}); + test_dynamic(uint64_t{7}); + + // floating point + test_dynamic(float{7.7}); + test_dynamic(double{7.7}); + + // text + test_dynamic('7'); + test_dynamic("seven"); + test_dynamic(std::string("seven")); + test_dynamic(sqlpp::compat::string_view("seven")); + + // blob + test_dynamic(std::vector{}); + + // date + test_dynamic(::sqlpp::chrono::day_point{}); + + // timestamp + test_dynamic(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_dynamic(minute_point{}); + + // time_of_day + test_dynamic(std::chrono::microseconds{}); + +} + diff --git a/tests/core/types/value.cpp b/tests/core/types/value.cpp index 3e9a6321..e424198a 100644 --- a/tests/core/types/value.cpp +++ b/tests/core/types/value.cpp @@ -50,22 +50,16 @@ void test_value(Value v) auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); auto v_not_null_alias = sqlpp::value(v).as(r_not_null); auto v_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); - auto v_opt_not_null_alias = sqlpp::value(v).as(r_opt_not_null).if_(true); - auto v_opt_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_opt_maybe_null).if_(true); static_assert(is_value_type::value, ""); static_assert(is_value_type::value, ""); static_assert(is_value_type::value, ""); static_assert(is_value_type::value, ""); - static_assert(is_value_type::value, ""); - static_assert(is_value_type::value, ""); static_assert(not sqlpp::can_be_null::value, ""); static_assert(sqlpp::can_be_null::value, ""); static_assert(not sqlpp::can_be_null::value, ""); static_assert(sqlpp::can_be_null::value, ""); - static_assert(sqlpp::can_be_null::value, ""); - static_assert(sqlpp::can_be_null::value, ""); } int main() diff --git a/tests/core/usage/MockDb.h b/tests/core/usage/MockDb.h index fdbaf694..6d6679b0 100644 --- a/tests/core/usage/MockDb.h +++ b/tests/core/usage/MockDb.h @@ -86,16 +86,16 @@ struct MockDb : public sqlpp::connection } template - static _serializer_context_t& _serialize_interpretable(const T& t, _serializer_context_t& context) + static _serializer_context_t& _serialize_interpretable(const T& x, _serializer_context_t& context) { - serialize(t, context); + serialize(context, x); return context; } template - static _serializer_context_t& _interpret_interpretable(const T& t, _interpreter_context_t& context) + static _serializer_context_t& _interpret_interpretable(const T& x, _interpreter_context_t& context) { - serialize(t, context); + serialize(context, x); return context; } @@ -141,7 +141,7 @@ struct MockDb : public sqlpp::connection size_t execute(const Statement& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running execute call with\n" << context.str() << std::endl; return execute(context.str()); } @@ -150,7 +150,7 @@ struct MockDb : public sqlpp::connection size_t insert(const Insert& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running insert call with\n" << context.str() << std::endl; return 0; } @@ -159,7 +159,7 @@ struct MockDb : public sqlpp::connection size_t update(const Update& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running update call with\n" << context.str() << std::endl; return 0; } @@ -168,7 +168,7 @@ struct MockDb : public sqlpp::connection size_t remove(const Remove& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running remove call with\n" << context.str() << std::endl; return 0; } @@ -177,7 +177,7 @@ struct MockDb : public sqlpp::connection result_t select(const Select& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running select call with\n" << context.str() << std::endl; return {}; } @@ -204,7 +204,7 @@ struct MockDb : public sqlpp::connection _prepared_statement_t prepare_execute(Statement& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare execute call with\n" << context.str() << std::endl; return nullptr; } @@ -213,7 +213,7 @@ struct MockDb : public sqlpp::connection _prepared_statement_t prepare_insert(Insert& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare insert call with\n" << context.str() << std::endl; return nullptr; } @@ -234,7 +234,7 @@ struct MockDb : public sqlpp::connection _prepared_statement_t prepare_select(Select& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare select call with\n" << context.str() << std::endl; return nullptr; } @@ -300,16 +300,16 @@ struct MockSizeDb : public sqlpp::connection } template - static _serializer_context_t& _serialize_interpretable(const T& t, _serializer_context_t& context) + static _serializer_context_t& _serialize_interpretable(const T& x, _serializer_context_t& context) { - serialize(t, context); + serialize(context, x); return context; } template - static _serializer_context_t& _interpret_interpretable(const T& t, _interpreter_context_t& context) + static _serializer_context_t& _interpret_interpretable(const T& x, _interpreter_context_t& context) { - serialize(t, context); + serialize(context, x); return context; } @@ -349,7 +349,7 @@ struct MockSizeDb : public sqlpp::connection size_t execute(const Statement& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running execute call with\n" << context.str() << std::endl; return execute(context.str()); } @@ -358,7 +358,7 @@ struct MockSizeDb : public sqlpp::connection size_t insert(const Insert& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running insert call with\n" << context.str() << std::endl; return 0; } @@ -367,7 +367,7 @@ struct MockSizeDb : public sqlpp::connection size_t update(const Update& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running update call with\n" << context.str() << std::endl; return 0; } @@ -376,7 +376,7 @@ struct MockSizeDb : public sqlpp::connection size_t remove(const Remove& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running remove call with\n" << context.str() << std::endl; return 0; } @@ -385,7 +385,7 @@ struct MockSizeDb : public sqlpp::connection result_t select(const Select& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running select call with\n" << context.str() << std::endl; return {}; } @@ -412,7 +412,7 @@ struct MockSizeDb : public sqlpp::connection _prepared_statement_t prepare_execute(Statement& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare execute call with\n" << context.str() << std::endl; return nullptr; } @@ -421,7 +421,7 @@ struct MockSizeDb : public sqlpp::connection _prepared_statement_t prepare_insert(Insert& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare insert call with\n" << context.str() << std::endl; return nullptr; } @@ -442,7 +442,7 @@ struct MockSizeDb : public sqlpp::connection _prepared_statement_t prepare_select(Select& x) { _serializer_context_t context; - serialize(x, context); + serialize(context, x); std::cout << "Running prepare select call with\n" << context.str() << std::endl; return nullptr; }