From c52a60cabdc95e783606d596947936089156b110 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Fri, 15 Nov 2024 11:55:36 +0100 Subject: [PATCH] Add tests for schema-qualified tables --- include/sqlpp11/core/basic/enable_join.h | 6 ++ include/sqlpp11/core/basic/schema.h | 9 ++- .../core/basic/schema_qualified_table.h | 73 ++++++++++--------- include/sqlpp11/core/basic/table.h | 6 -- include/sqlpp11/core/basic/table_as.h | 3 - include/sqlpp11/core/to_sql_string.h | 2 +- tests/core/serialize/basic/CMakeLists.txt | 1 + .../basic/schema_qualified_table.cpp | 45 ++++++++++++ tests/core/types/basic/CMakeLists.txt | 1 + .../types/basic/schema_qualified_table.cpp | 56 ++++++++++++++ 10 files changed, 156 insertions(+), 46 deletions(-) create mode 100644 tests/core/serialize/basic/schema_qualified_table.cpp create mode 100644 tests/core/types/basic/schema_qualified_table.cpp diff --git a/include/sqlpp11/core/basic/enable_join.h b/include/sqlpp11/core/basic/enable_join.h index 60a86f6a..b7fdf13e 100644 --- a/include/sqlpp11/core/basic/enable_join.h +++ b/include/sqlpp11/core/basic/enable_join.h @@ -77,4 +77,10 @@ namespace sqlpp return ::sqlpp::cross_join(this->derived(), std::move(t)); } }; + + template + struct has_enabled_join : public std::is_base_of, T> + { + }; + } // namespace sqlpp diff --git a/include/sqlpp11/core/basic/schema.h b/include/sqlpp11/core/basic/schema.h index a573ae15..f043dcef 100644 --- a/include/sqlpp11/core/basic/schema.h +++ b/include/sqlpp11/core/basic/schema.h @@ -38,7 +38,12 @@ namespace sqlpp template auto to_sql_string(Context& context, const schema_t& t) -> std::string { - context << t._name; - return context; + return name_to_sql_string(context, t._name); } + + auto schema(std::string name) -> schema_t + { + return schema_t{std::move(name)}; + }; + } // namespace sqlpp diff --git a/include/sqlpp11/core/basic/schema_qualified_table.h b/include/sqlpp11/core/basic/schema_qualified_table.h index 47f16477..b36133e2 100644 --- a/include/sqlpp11/core/basic/schema_qualified_table.h +++ b/include/sqlpp11/core/basic/schema_qualified_table.h @@ -37,52 +37,57 @@ namespace sqlpp { - template + template + struct schema_qualified_table_as_t + : public TableSpec::_table_columns>, public enable_join> + { + schema_qualified_table_as_t(schema_t schema) : _schema(std::move(schema)) + { + } + + schema_t _schema; + }; + + template + struct is_table> : public std::true_type {}; + + template + struct name_tag_of> { + using type = NameTag; + }; + + template + struct provided_tables_of> + { + using type = detail::type_vector>; + }; + + template + auto to_sql_string(Context& context, const schema_qualified_table_as_t& t) -> std::string + { + return to_sql_string(context, t._schema) + "." + name_to_sql_string(context, name_tag_of_t::name) + + " AS " + name_to_sql_string(context, NameTag::name); + } + + template struct schema_qualified_table_t { - using _traits = make_traits>; - - using _nodes = detail::type_vector<>; - using _required_ctes = detail::type_set<>; - using _provided_tables = detail::type_set<>; - - schema_qualified_table_t(schema_t schema, Table table) : _schema(std::move(schema)), _table(table) + schema_qualified_table_t(schema_t schema) : _schema(std::move(schema)) { } template - typename Table::template _foreign_table_as_t as( - const NameTagProvider& /*unused*/) const + auto as(const NameTagProvider& /*unused*/) const->schema_qualified_table_as_t> { - return {*this}; + return {_schema}; } schema_t _schema; - Table _table; }; - template - struct is_table> : public std::true_type {}; - - template - auto to_sql_string(Context& context, const schema_qualified_table_t& t) -> std::string + template + auto schema_qualified_table(schema_t schema, table_t) -> schema_qualified_table_t { - to_sql_string(context, t._schema); - context << '.'; - to_sql_string(context, t._table); - return context; - } - - template - auto schema_qualified_table(schema_t schema, Table table) -> schema_qualified_table_t
- { - static_assert(required_tables_of_t
::size::value == 0, - "schema qualified tables must not depend on other tables"); - static_assert(required_ctes_of
::size::value == 0, - "schema qualified tables must not depend on common table expressions"); - static_assert(is_raw_table
::value, - "table must be a raw table, i.e. not an alias or common table expression"); - - return {schema, table}; + return {schema}; } } // namespace sqlpp diff --git a/include/sqlpp11/core/basic/table.h b/include/sqlpp11/core/basic/table.h index 51397441..86162edf 100644 --- a/include/sqlpp11/core/basic/table.h +++ b/include/sqlpp11/core/basic/table.h @@ -39,13 +39,7 @@ namespace sqlpp template struct table_t : public TableSpec::_table_columns>, public enable_join> { - using _traits = make_traits; - using _required_insert_columns = typename TableSpec::_required_insert_columns; -#warning: Need to inherit? - //using _column_tuple_t = std::tuple...>; - template - using _foreign_table_as_t = table_as_t; template constexpr auto as(const NameTagProvider& /*unused*/) const -> table_as_t> diff --git a/include/sqlpp11/core/basic/table_as.h b/include/sqlpp11/core/basic/table_as.h index 28c1e3b3..8c187c24 100644 --- a/include/sqlpp11/core/basic/table_as.h +++ b/include/sqlpp11/core/basic/table_as.h @@ -42,9 +42,6 @@ namespace sqlpp using _nodes = detail::type_vector<>; static_assert(required_tables_of_t::empty(), "table aliases must not depend on external tables"); - -#warning: need to inherit? - //using _column_tuple_t = std::tuple...>; }; template diff --git a/include/sqlpp11/core/to_sql_string.h b/include/sqlpp11/core/to_sql_string.h index 895c5e2d..518d33d3 100644 --- a/include/sqlpp11/core/to_sql_string.h +++ b/include/sqlpp11/core/to_sql_string.h @@ -266,7 +266,7 @@ namespace sqlpp } template - auto name_to_sql_string(Context& , const char* t) -> std::string + auto name_to_sql_string(Context& , const ::sqlpp::string_view& t) -> std::string { #warning: We used to have a version of SQLPP_ALIAS_PROVIDER that marked names as keywords #warning: IIUC, the standard SQL way of handling keywords as names is to put them in square brackets, MySQL uses backticks, though diff --git a/tests/core/serialize/basic/CMakeLists.txt b/tests/core/serialize/basic/CMakeLists.txt index bd8a0894..c04a6795 100644 --- a/tests/core/serialize/basic/CMakeLists.txt +++ b/tests/core/serialize/basic/CMakeLists.txt @@ -30,4 +30,5 @@ function(create_test name) endfunction() create_test(join) +create_test(schema_qualified_table) diff --git a/tests/core/serialize/basic/schema_qualified_table.cpp b/tests/core/serialize/basic/schema_qualified_table.cpp new file mode 100644 index 00000000..ba8c2e66 --- /dev/null +++ b/tests/core/serialize/basic/schema_qualified_table.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024, 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 "../compare.h" +#include + +int main(int, char* []) +{ + // A schema-qualified table cannot be used without AS. + auto major = schema_qualified_table(sqlpp::schema("major"), test::TabFoo{}); + using M = decltype(major); + + static_assert(not sqlpp::is_table::value, ""); + + // A schema-qualified table can be used as table with AS: + auto major_foo = major.as(sqlpp::alias::a); + + SQLPP_COMPARE(major_foo, "major.tab_foo AS a"); + SQLPP_COMPARE(major_foo.id, "a.id"); + + return 0; +} diff --git a/tests/core/types/basic/CMakeLists.txt b/tests/core/types/basic/CMakeLists.txt index 014f4a8b..e5a913e7 100644 --- a/tests/core/types/basic/CMakeLists.txt +++ b/tests/core/types/basic/CMakeLists.txt @@ -30,6 +30,7 @@ endfunction() test_compile(column) test_compile(join) +test_compile(schema_qualified_table) test_compile(table) test_compile(table_as) diff --git a/tests/core/types/basic/schema_qualified_table.cpp b/tests/core/types/basic/schema_qualified_table.cpp new file mode 100644 index 00000000..3cdf26d6 --- /dev/null +++ b/tests/core/types/basic/schema_qualified_table.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024, 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 "../compare.h" +#include + +int main(int, char* []) +{ + // A schema-qualified table cannot be used without AS. + auto major = schema_qualified_table(sqlpp::schema("major"), test::TabFoo{}); + using M = decltype(major); + + static_assert(not sqlpp::is_table::value, ""); + + // A schema-qualified table can be used as table with AS: + auto major_foo = major.as(test::TabFoo{}); + using MF = decltype(major_foo); + + static_assert(sqlpp::is_table::value, ""); + static_assert(sqlpp::has_enabled_join::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector<>>::value, ""); + + // Columns of a schema-qualified table work just like columns of unqualified tables. + using MFI = decltype(major_foo.id); + static_assert(sqlpp::is_integral::value, ""); + static_assert(sqlpp::has_name_tag::value, ""); + + static_assert(std::is_same, sqlpp::detail::type_vector<>>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + + return 0; +}