diff --git a/include/sqlpp11/core/basic/schema_qualified_table.h b/include/sqlpp11/core/basic/schema_qualified_table.h index c4b551c0..47f16477 100644 --- a/include/sqlpp11/core/basic/schema_qualified_table.h +++ b/include/sqlpp11/core/basic/schema_qualified_table.h @@ -80,7 +80,7 @@ namespace sqlpp "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_t
::value, + static_assert(is_raw_table
::value, "table must be a raw table, i.e. not an alias or common table expression"); return {schema, table}; diff --git a/include/sqlpp11/core/basic/table.h b/include/sqlpp11/core/basic/table.h index 5e848ae2..f81b58d0 100644 --- a/include/sqlpp11/core/basic/table.h +++ b/include/sqlpp11/core/basic/table.h @@ -39,7 +39,7 @@ namespace sqlpp template struct table_t : public TableSpec::_table_columns>, public enable_join> { - using _traits = make_traits; + using _traits = make_traits; using _required_insert_columns = typename TableSpec::_required_insert_columns; #warning: Need to inherit? @@ -56,11 +56,14 @@ namespace sqlpp }; template - struct name_tag_of>: public name_tag_of {}; + struct is_raw_table>: public std::true_type {}; template struct is_table>: public std::true_type {}; + template + struct name_tag_of>: public name_tag_of {}; + template struct provided_tables_of> { diff --git a/include/sqlpp11/core/clause/into.h b/include/sqlpp11/core/clause/into.h index 50108940..37b10a95 100644 --- a/include/sqlpp11/core/clause/into.h +++ b/include/sqlpp11/core/clause/into.h @@ -89,7 +89,7 @@ namespace sqlpp template struct check_into { - using type = static_combined_check_t::value, assert_into_arg_is_table>>; + using type = static_combined_check_t::value, assert_into_arg_is_table>>; }; template using check_into_t = typename check_into::type; diff --git a/include/sqlpp11/core/type_traits.h b/include/sqlpp11/core/type_traits.h index 6caffaf9..ee497d46 100644 --- a/include/sqlpp11/core/type_traits.h +++ b/include/sqlpp11/core/type_traits.h @@ -227,7 +227,6 @@ namespace sqlpp SQLPP_VALUE_TRAIT_GENERATOR(is_cte) SQLPP_VALUE_TRAIT_GENERATOR(is_noop) SQLPP_VALUE_TRAIT_GENERATOR(is_missing) - SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table) SQLPP_VALUE_TRAIT_GENERATOR(is_pre_join) SQLPP_VALUE_TRAIT_GENERATOR(is_join) SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_pre_join) @@ -414,9 +413,14 @@ namespace sqlpp template using parameters_of = typename detail::parameters_of_impl::type; + // Something that can be used as a table template struct is_table : public std::false_type{}; + // Really a table, not a `table AS ...`, `JOIN` or `CTE` or `SELECT ... AS` + template + struct is_raw_table : public std::false_type{}; + template struct make_traits { diff --git a/tests/core/types/basic/column.cpp b/tests/core/types/basic/column.cpp index f4adabec..5e62b27a 100644 --- a/tests/core/types/basic/column.cpp +++ b/tests/core/types/basic/column.cpp @@ -52,8 +52,6 @@ void test_column() static_assert(std::is_same, sqlpp::integral>::value, ""); - foo.as(test::TabBar{}).id = 7; - // tab_foo.id AS cheese // This is only useful SELECT. It therefore exposes neither name nor value directly. // It does require its table, though. @@ -74,7 +72,6 @@ void test_column() static_assert(std::is_same, sqlpp::no_value_t>::value, ""); // (tab_foo AS bar).id -#warning : insert must not accept table_as! static_assert(not sqlpp::is_table::value, ""); static_assert(sqlpp::has_default::value, ""); static_assert(sqlpp::is_group_by_column::value, ""); diff --git a/tests/core/types/basic/join.cpp b/tests/core/types/basic/join.cpp index f110c41f..c74b745e 100644 --- a/tests/core/types/basic/join.cpp +++ b/tests/core/types/basic/join.cpp @@ -26,34 +26,116 @@ #include "Sample.h" #include +namespace test { +SQLPP_CREATE_NAME_TAG(cheese); +SQLPP_CREATE_NAME_TAG(cake); +} + void test_group_by() { auto v = sqlpp::value(17); auto foo = test::TabFoo{}; auto bar = test::TabBar{}; + auto cheese = foo.as(test::cheese); + auto cake = foo.as(test::cake); + + using Foo = decltype(foo); + using Bar = decltype(bar); + using Cheese = decltype(cheese); + using Cake = decltype(cake); // Pre-join static_assert(not sqlpp::is_table::value, ""); - // Join + // Join of tables { using J = decltype(foo.join(bar).on(foo.id == bar.id)); static_assert(sqlpp::is_table::value, ""); static_assert( - std::is_same, sqlpp::detail::type_vector, sqlpp::table_t>>::value, ""); + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); static_assert( std::is_same, sqlpp::detail::type_vector<>>::value, ""); -#warning: test the provided dynamic tables of? + } + + { + using J = decltype(foo.cross_join(bar)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector<>>::value, ""); + } + + { + using J = decltype(foo.inner_join(bar).on(foo.id == bar.id)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector<>>::value, ""); + } + + { + using J = decltype(foo.left_outer_join(bar).on(foo.id == bar.id)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + } + + { + using J = decltype(foo.right_outer_join(bar).on(foo.id == bar.id)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); } { using J = decltype(foo.full_outer_join(bar).on(foo.id == bar.id)); static_assert(sqlpp::is_table::value, ""); static_assert( - std::is_same, sqlpp::detail::type_vector, sqlpp::table_t>>::value, ""); + std::is_same, sqlpp::detail::type_vector>::value, ""); static_assert( - std::is_same, sqlpp::detail::type_vector, sqlpp::table_t>>::value, ""); -#warning: test the provided dynamic tables of? + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + } + + // Join with rhs alias table + { + using J = decltype(foo.join(cheese).on(foo.id == cheese.id)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector<>>::value, ""); + } + + // Join with two alias tables + { + using J = decltype(cheese.join(cake).on(cheese.id == cake.id)); + static_assert(sqlpp::is_table::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::provided_tables_of_t>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector<>>::value, ""); } // Join with dynamic table @@ -61,16 +143,14 @@ void test_group_by() using J = decltype(foo.join(dynamic(true, bar)).on(foo.id == bar.id)); static_assert(sqlpp::is_table::value, ""); static_assert( - std::is_same, sqlpp::detail::type_vector>::value, ""); -#warning: OUTER is the wrong term. In a left-outer join, the *right* table is the one with optional rows. + std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert( + std::is_same, sqlpp::detail::type_vector>::value, ""); static_assert( std::is_same, sqlpp::detail::type_vector<>>::value, ""); -#warning: test the provided dynamic tables of? } -#warning: Need to add tests all join types! -#warning: Need to add tests with table_as #warning: Need to add tests with verbatim tables #warning: Need to add tests with 3 tables diff --git a/tests/core/types/basic/table.cpp b/tests/core/types/basic/table.cpp index 2c448088..d448ae96 100644 --- a/tests/core/types/basic/table.cpp +++ b/tests/core/types/basic/table.cpp @@ -33,6 +33,7 @@ void test_table() auto bar = test::TabBar{}; static_assert(sqlpp::is_table::value, ""); + static_assert(sqlpp::is_raw_table::value, ""); static_assert(std::is_same, test::TabFoo_::_sqlpp_name_tag>::value, ""); static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); static_assert(std::is_same, sqlpp::provided_tables_of_t>::value, ""); diff --git a/tests/core/types/basic/table_as.cpp b/tests/core/types/basic/table_as.cpp index 12d43fb3..0bc916ec 100644 --- a/tests/core/types/basic/table_as.cpp +++ b/tests/core/types/basic/table_as.cpp @@ -36,6 +36,7 @@ void test_table() static_assert(std::is_same>::value, ""); static_assert(sqlpp::is_table::value, ""); + static_assert(not sqlpp::is_raw_table::value, ""); static_assert(std::is_same, test::TabBar_::_sqlpp_name_tag>::value, ""); static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); static_assert(std::is_same, sqlpp::provided_tables_of_t>::value, "");