0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Moved static asserts for inconsistency errors much closer to call site

This commit is contained in:
rbock 2014-11-17 19:05:22 +01:00
parent 4ef00a03b2
commit 59734b3f51
24 changed files with 121 additions and 103 deletions

View File

@ -70,17 +70,20 @@ namespace sqlpp
custom_query_t& operator=(custom_query_t&&) = default;
~custom_query_t() = default;
static void _check_consistency() {};
using _consistency_check = consistent_t;
template<typename Db>
auto _run(Db& db) const -> decltype(std::declval<_methods_t>()._run(db, *this))
{
static_assert(_get_static_no_of_parameters() == 0, "cannot run execute directly with parameters, use prepare instead");
_run_check{};
return _methods_t::_run(db, *this);
}
template<typename Db>
auto _prepare(Db& db) const -> decltype(std::declval<_methods_t>()._prepare(db, *this))
{
_prepare_check{};
return _methods_t::_prepare(db, *this);
}

View File

@ -99,7 +99,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -142,7 +142,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_extra_tables_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto extra_tables(Args...) const

View File

@ -119,7 +119,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -163,7 +163,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_from_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Tables>
auto from(Tables... tables) const

View File

@ -128,7 +128,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -172,7 +172,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_group_by_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto group_by(Args... args) const

View File

@ -126,7 +126,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -170,7 +170,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_having_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto having(Args... args) const

View File

@ -61,18 +61,12 @@ namespace sqlpp
auto _run(Db& db, const Composite& composite) const
-> decltype(db.insert(composite))
{
Composite::_check_consistency();
static_assert(Composite::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
return db.insert(composite);
}
template<typename Db>
auto _run(Db& db) const -> decltype(db.insert(this->_get_statement()))
{
_statement_t::_check_consistency();
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
return db.insert(_get_statement());
}
@ -81,8 +75,6 @@ namespace sqlpp
auto _prepare(Db& db, const Composite& composite) const
-> prepared_insert_t<Db, Composite>
{
Composite::_check_consistency();
return {{}, db.prepare_insert(composite)};
}
@ -90,8 +82,6 @@ namespace sqlpp
auto _prepare(Db& db) const
-> prepared_insert_t<Db, _statement_t>
{
_statement_t::_check_consistency();
return {{}, db.prepare_insert(_get_statement())};
}
};

View File

@ -96,7 +96,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -200,7 +200,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -288,7 +288,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};

View File

@ -96,7 +96,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};

View File

@ -89,7 +89,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -166,7 +166,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -209,7 +209,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_limit_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename Arg>
auto limit(Arg arg) const

View File

@ -55,18 +55,12 @@ namespace sqlpp
template<typename Db, typename Composite>
auto _run(Db& db, const Composite& composite) const -> void
{
Composite::_check_consistency();
static_assert(Composite::_get_static_no_of_parameters() == 0, "cannot run execute directly with parameters, use prepare instead");
return db.execute(composite);
}
template<typename Db>
auto _run(Db& db) const -> void
{
_statement_t::_check_consistency();
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
return db.execute(_get_statement());
}
@ -75,8 +69,6 @@ namespace sqlpp
auto _prepare(Db& db, const Composite& composite) const
-> prepared_execute_t<Db, Composite>
{
Composite::_check_consistency();
return {{}, db.prepare_execute(composite)};
}
@ -84,8 +76,6 @@ namespace sqlpp
auto _prepare(Db& db) const
-> prepared_execute_t<Db, _statement_t>
{
_statement_t::_check_consistency();
return {{}, db.prepare_execute(_get_statement())};
}
};

View File

@ -89,7 +89,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -165,7 +165,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename Offset>
void set_offset(Offset value)
@ -220,7 +220,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_offset_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename Arg>
auto offset(Arg arg) const

View File

@ -128,7 +128,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -172,7 +172,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_order_by_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto order_by(Args... args) const

View File

@ -61,18 +61,12 @@ namespace sqlpp
auto _run(Db& db, const Composite& composite) const
-> decltype(db.remove(composite))
{
Composite::_check_consistency();
static_assert(Composite::_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
return db.remove(composite);
}
template<typename Db>
auto _run(Db& db) const -> decltype(db.remove(this->_get_statement()))
{
_statement_t::_check_consistency();
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
return db.remove(_get_statement());
}
@ -81,8 +75,6 @@ namespace sqlpp
auto _prepare(Db& db, const Composite& composite) const
-> prepared_remove_t<Db, Composite>
{
Composite::_check_consistency();
return {{}, db.prepare_remove(composite)};
}
@ -90,8 +82,6 @@ namespace sqlpp
auto _prepare(Db& db) const
-> prepared_remove_t<Db, _statement_t>
{
_statement_t::_check_consistency();
return {{}, db.prepare_remove(_get_statement())};
}
};

View File

@ -231,7 +231,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
// Result methods
@ -297,9 +297,6 @@ namespace sqlpp
auto _run(Db& db, const Composite& composite) const
-> result_t<decltype(db.select(composite)), _result_row_t<Db>>
{
Composite::_check_consistency();
static_assert(Composite::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
return {db.select(composite), get_dynamic_names()};
}
@ -307,9 +304,6 @@ namespace sqlpp
auto _run(Db& db) const
-> result_t<decltype(db.select(std::declval<_statement_t>())), _result_row_t<Db>>
{
_statement_t::_check_consistency();
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
return {db.select(_get_statement()), get_dynamic_names()};
}
@ -318,8 +312,6 @@ namespace sqlpp
auto _prepare(Db& db, const Composite& composite) const
-> prepared_select_t<Db, _statement_t, Composite>
{
Composite::_check_consistency();
return {make_parameter_list_t<Composite>{}, get_dynamic_names(), db.prepare_select(composite)};
}
@ -327,8 +319,6 @@ namespace sqlpp
auto _prepare(Db& db) const
-> prepared_select_t<Db, _statement_t>
{
_statement_t::_check_consistency();
return {make_parameter_list_t<_statement_t>{}, get_dynamic_names(), db.prepare_select(_get_statement())};
}
};
@ -385,7 +375,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_select_column_list_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto columns(Args... args) const

View File

@ -127,7 +127,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -171,7 +171,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_select_flag_list_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto flags(Args... args) const

View File

@ -95,7 +95,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -140,7 +140,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_single_table_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto from(Args... args) const

View File

@ -35,6 +35,7 @@
#include <sqlpp11/policy_update.h>
#include <sqlpp11/serializer.h>
#include <sqlpp11/detail/get_first.h>
#include <sqlpp11/detail/get_last.h>
#include <sqlpp11/detail/pick_arg.h>
@ -43,6 +44,28 @@ namespace sqlpp
template<typename Db, typename... Policies>
struct statement_t;
struct assert_no_unknown_tables_t
{
using type = std::false_type;
template<typename T = void>
static void _()
{
static_assert(wrong_t<T>::value, "one clause requires tables which are otherwise not known in the statement");
}
};
struct assert_no_parameters_t
{
using type = std::false_type;
template<typename T = void>
static void _()
{
static_assert(wrong_t<T>::value, "cannot run statements with parameters directly, use prepare instead");
}
};
namespace detail
{
template<typename Db = void, typename... Policies>
@ -110,7 +133,7 @@ namespace sqlpp
struct _recursive_traits
{
using _required_tables = statement_policies_t::_required_tables;
using _required_tables = _required_tables;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
@ -119,6 +142,16 @@ namespace sqlpp
detail::type_set<tag::can_be_null>,
detail::type_set<>>::type;
};
using _table_check = typename std::conditional<_required_tables::size::value == 0,
consistent_t, assert_no_unknown_tables_t>::type;
using _parameter_check = typename std::conditional<std::tuple_size<typename _recursive_traits::_parameters>::value == 0,
consistent_t, assert_no_parameters_t>::type;
using _run_check = detail::get_first_if<is_inconsistent_t, consistent_t,
_table_check, _parameter_check, typename Policies::template _methods_t<statement_policies_t>::_consistency_check...>;
using _prepare_check = detail::get_first_if<is_inconsistent_t, consistent_t,
_table_check, typename Policies::template _methods_t<statement_policies_t>::_consistency_check...>;
};
}
@ -132,6 +165,9 @@ namespace sqlpp
public Policies::template _methods_t<detail::statement_policies_t<Db, Policies...>>...
{
using _policies_t = typename detail::statement_policies_t<Db, Policies...>;
using _run_check = typename _policies_t::_run_check;
using _prepare_check = typename _policies_t::_prepare_check;
using _result_type_provider = typename _policies_t::_result_type_provider;
template<typename Composite>
using _result_methods_t = typename _result_type_provider::template _result_methods_t<Composite>;
@ -181,28 +217,20 @@ namespace sqlpp
return _policies_t::_can_be_used_as_table();
}
static void _check_consistency()
{
static_assert(not required_tables_of<_policies_t>::size::value, "one sub expression requires tables which are otherwise not known in the statement");
using swallow = int[];
(void) swallow{(Policies::template _methods_t<detail::statement_policies_t<Db, Policies...>>::_check_consistency(), 0)...};
}
template<typename Database>
auto _run(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._run(db))
{
_run_check::_();
return _result_methods_t<statement_t>::_run(db);
}
template<typename Database>
auto _prepare(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._prepare(db))
{
_prepare_check::_();
return _result_methods_t<statement_t>::_prepare(db);
}
};
template<typename Context, typename Database, typename... Policies>
@ -257,7 +285,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};

View File

@ -239,6 +239,16 @@ namespace sqlpp
template<typename Policies>
using derived_statement_t = typename Policies::_statement_t;
struct consistent_t
{
using type = std::true_type;
static void _() {};
};
template<typename T>
using is_inconsistent_t = typename std::conditional<std::is_same<consistent_t, T>::value, std::false_type, std::true_type>::type;
}
#endif

View File

@ -61,18 +61,12 @@ namespace sqlpp
auto _run(Db& db, const Composite& composite) const
-> decltype(db.update(composite))
{
Composite::_check_consistency();
static_assert(Composite::_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
return db.update(composite);
}
template<typename Db>
auto _run(Db& db) const -> decltype(db.update(this->_get_statement()))
{
_statement_t::_check_consistency();
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
return db.update(_get_statement());
}
@ -81,8 +75,6 @@ namespace sqlpp
auto _prepare(Db& db, const Composite& composite) const
-> prepared_update_t<Db, Composite>
{
Composite::_check_consistency();
return {{}, db.prepare_update(composite)};
}
@ -90,8 +82,6 @@ namespace sqlpp
auto _prepare(Db& db) const
-> prepared_update_t<Db, _statement_t>
{
_statement_t::_check_consistency();
return {{}, db.prepare_update(_get_statement())};
}
};

View File

@ -124,7 +124,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};

View File

@ -121,7 +121,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -165,7 +165,7 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_using_t, T>;
static void _check_consistency() {}
using _consistency_check = consistent_t;
template<typename... Args>
auto using_(Args... args) const

View File

@ -128,7 +128,7 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
@ -176,11 +176,22 @@ namespace sqlpp
template<typename Policies>
struct _methods_t
{
static void _check_consistency() {}
using _consistency_check = consistent_t;
};
};
struct assert_where_t
{
using type = std::false_type;
template<typename T = void>
static void _()
{
static_assert(wrong_t<T>::value, "where expression required, e.g. where(true)");
};
};
// NO WHERE YET
template<bool WhereRequired>
struct no_where_t
@ -223,12 +234,10 @@ namespace sqlpp
template<typename T>
using _new_statement_t = new_statement<Policies, no_where_t, T>;
static void _check_consistency()
{
static constexpr bool _tables_provided = (Policies::_all_provided_tables::size::value > 0);
static constexpr bool _required = WhereRequired and _tables_provided;
static_assert(not _required, "where expression required, e.g. where(true)");
}
using _consistency_check = typename std::conditional<
WhereRequired and (Policies::_all_provided_tables::size::value > 0),
assert_where_t,
consistent_t>::type;
template<typename... Args>
auto where(Args... args) const

View File

@ -107,11 +107,25 @@ struct MockDbT: public sqlpp::connection
// Directly executed statements start here
template<typename T>
auto operator() (const T& t) -> decltype(t._run(*this))
auto _run(const T& t, const std::true_type&) -> decltype(t._run(*this))
{
return t._run(*this);
}
template<typename T>
auto _run(const T& t, const std::false_type&) -> decltype(t._run(*this))
{
return decltype(t._run(*this)){};
}
template<typename T>
auto operator() (const T& t) -> decltype(t._run(*this))
{
T::_run_check::_();
using _ok = typename T::_run_check::type;
return _run(t, _ok{});
}
void execute(const std::string& command);
template<typename Statement,

View File

@ -38,10 +38,13 @@ MockDb::_serializer_context_t printer;
int main()
{
test::TabFoo f;
//test::TabFoo f;
test::TabBar t;
sqlpp::select(t.alpha).flags(sqlpp::all).from(t);
db(select(all_of(t)).from(t));
#if 0
select(t.alpha).flags(sqlpp::all).from(t);
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
{
int64_t a = row.alpha;
@ -98,6 +101,7 @@ int main()
std::cerr << serialize(stat, printer).str() << std::endl;
select(sqlpp::value(7).as(t.alpha));
#endif
return 0;
}