Reduced error messages for several clauses

This commit is contained in:
rbock
2014-11-29 14:02:24 +01:00
parent 213080f58b
commit 9110f6653a
8 changed files with 169 additions and 60 deletions

View File

@@ -62,12 +62,6 @@ namespace sqlpp
using _tags = detail::type_set<>;
};
// FIXME: extra_tables must not require tables!
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
static_assert(not detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
static_assert(detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
// Data
using _data_t = extra_tables_data_t<Tables...>;
@@ -130,17 +124,41 @@ namespace sqlpp
return t.no_extra_tables;
}
template<typename T>
using _new_statement_t = new_statement<Policies, no_extra_tables_t, T>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_extra_tables_t, T>;
template<typename... T>
using _check = detail::all_t<is_table_t<T>::value...>;
using _consistency_check = consistent_t;
template<typename... Args>
auto extra_tables(Args...) const
-> _new_statement_t<extra_tables_t<Args...>>
template<typename... Tables>
auto extra_tables(Tables... tables) const
-> _new_statement_t<_check<Tables...>, extra_tables_t<Tables...>>
{
#warning: need to move static asserts
return { static_cast<const derived_statement_t<Policies>&>(*this), extra_tables_data_t<Args...>{} };
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in extra_tables()");
return _extra_tables_impl<void>(_check<Tables...>{}, tables...);
}
private:
template<typename Database, typename... Tables>
auto _extra_tables_impl(const std::false_type&, Tables... tables) const
-> bad_statement;
template<typename Database, typename... Tables>
auto _extra_tables_impl(const std::true_type&, Tables...) const
-> _new_statement_t<std::true_type, extra_tables_t<Tables...>>
{
static_assert(required_tables_of<extra_tables_t<Tables...>>::size::value == 0, "at least one table depends on another table in extra_tables()");
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...);
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>;
using _unique_table_names = detail::transform_set_t<name_of, _unique_tables>;
static_assert(_number_of_tables == _unique_tables::size::value, "at least one duplicate table detected in extra_tables()");
static_assert(_number_of_tables == _unique_table_names::size::value, "at least one duplicate table name detected in extra_tables()");
return { static_cast<const derived_statement_t<Policies>&>(*this), extra_tables_data_t<Tables...>{} };
}
};
};

View File

@@ -189,7 +189,7 @@ namespace sqlpp
auto _from_impl(const std::true_type&, Tables... tables) const
-> _new_statement_t<std::true_type, from_t<Database, Tables...>>
{
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, "at least one table depends on another table");
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, "at least one table depends on another table in from()");
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...);
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>;

View File

@@ -61,9 +61,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_into>;
using _recursive_traits = make_recursive_traits<Table>;
static_assert(is_table_t<Table>::value, "argument has to be a table");
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
using _data_t = into_data_t<Database, Table>;
struct _name_t {};
@@ -140,16 +137,35 @@ namespace sqlpp
}
using _database_t = typename Policies::_database_t;
template<typename T>
using _new_statement_t = new_statement<Policies, no_into_t, T>;
using _check = detail::all_t<is_table_t<T>::value>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_into_t, T>;
using _consistency_check = assert_into_t;
template<typename... Args>
auto into(Args... args) const
-> _new_statement_t<into_t<void, Args...>>
template<typename Table>
auto into(Table table) const
-> _new_statement_t<_check<Table>, into_t<void, Table>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<void, Args...>{args...} };
static_assert(_check<Table>::value, "argument is not a table in into()");
return _into_impl<void>(_check<Table>{}, table);
}
private:
template<typename Database, typename Table>
auto _into_impl(const std::false_type&, Table table) const
-> bad_statement;
template<typename Database, typename Table>
auto _into_impl(const std::true_type&, Table table) const
-> _new_statement_t<std::true_type, into_t<Database, Table>>
{
static_assert(required_tables_of<into_t<Database, Table>>::size::value == 0, "argument depends on another table in into()");
return { static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<Database, Table>{table} };
}
};
};
@@ -169,10 +185,10 @@ namespace sqlpp
}
};
template<typename... T>
auto into(T&&... t) -> decltype(statement_t<void, no_into_t>().into(std::forward<T>(t)...))
template<typename T>
auto into(T&& t) -> decltype(statement_t<void, no_into_t>().into(std::forward<T>(t)))
{
return statement_t<void, no_into_t>().into(std::forward<T>(t)...);
return statement_t<void, no_into_t>().into(std::forward<T>(t));
}
}

View File

@@ -57,8 +57,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_limit>;
using _recursive_traits = make_recursive_traits<Limit>;
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
// Data
using _data_t = limit_data_t<Limit>;
@@ -134,6 +132,7 @@ namespace sqlpp
{
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
using arg_t = wrap_operand_t<Limit>;
static_assert(is_integral_t<arg_t>::value, "limit requires an integral value or integral parameter");
_data._value = arg_t{value};
_data._initialized = true;
}
@@ -195,23 +194,39 @@ namespace sqlpp
using _database_t = typename Policies::_database_t;
template<typename T>
using _new_statement_t = new_statement<Policies, no_limit_t, T>;
using _check = is_integral_t<wrap_operand_t<T>>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_limit_t, T>;
using _consistency_check = consistent_t;
template<typename Arg>
auto limit(Arg arg) const
-> _new_statement_t<limit_t<wrap_operand_t<Arg>>>
-> _new_statement_t<_check<Arg>, limit_t<wrap_operand_t<Arg>>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<wrap_operand_t<Arg>>{{arg}} };
static_assert(_check<Arg>::value, "limit requires an integral value or integral parameter");
return _limit_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
}
auto dynamic_limit() const
-> _new_statement_t<dynamic_limit_t<_database_t>>
-> _new_statement_t<std::true_type, dynamic_limit_t<_database_t>>
{
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
return { static_cast<const derived_statement_t<Policies>&>(*this), dynamic_limit_data_t<_database_t>{} };
}
private:
template<typename Arg>
auto _limit_impl(const std::false_type&, Arg arg) const
-> bad_statement;
template<typename Arg>
auto _limit_impl(const std::true_type&, Arg arg) const
-> _new_statement_t<std::true_type, limit_t<Arg>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{arg} };
}
};
};

View File

@@ -134,6 +134,7 @@ namespace sqlpp
{
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
using arg_t = wrap_operand_t<Offset>;
static_assert(is_integral_t<arg_t>::value, "offset requires an integral value or integral parameter");
_data._value = arg_t{value};
_data._initialized = true;
}
@@ -205,24 +206,42 @@ namespace sqlpp
}
using _database_t = typename Policies::_database_t;
template<typename T>
using _new_statement_t = new_statement<Policies, no_offset_t, T>;
using _check = is_integral_t<wrap_operand_t<T>>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_offset_t, T>;
using _consistency_check = consistent_t;
template<typename Arg>
auto offset(Arg arg) const
-> _new_statement_t<offset_t<wrap_operand_t<Arg>>>
-> _new_statement_t<_check<Arg>, offset_t<wrap_operand_t<Arg>>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<wrap_operand_t<Arg>>{{arg}} };
static_assert(_check<Arg>::value, "offset requires an integral value or integral parameter");
return _offset_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
}
auto dynamic_offset() const
-> _new_statement_t<dynamic_offset_t<_database_t>>
-> _new_statement_t<std::true_type, dynamic_offset_t<_database_t>>
{
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
return { static_cast<const derived_statement_t<Policies>&>(*this), dynamic_offset_data_t<_database_t>{} };
}
private:
template<typename Arg>
auto _offset_impl(const std::false_type&, Arg arg) const
-> bad_statement;
template<typename Arg>
auto _offset_impl(const std::true_type&, Arg arg) const
-> _new_statement_t<std::true_type, offset_t<Arg>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{arg} };
}
};
};

View File

@@ -129,15 +129,33 @@ namespace sqlpp
using _database_t = typename Policies::_database_t;
template<typename T>
using _new_statement_t = new_statement<Policies, no_single_table_t, T>;
using _check = detail::all_t<is_table_t<T>::value>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_single_table_t, T>;
using _consistency_check = consistent_t;
template<typename... Args>
auto from(Args... args) const
-> _new_statement_t<single_table_t<void, Args...>>
template<typename Table>
auto single_table(Table table) const
-> _new_statement_t<_check<Table>, single_table_t<void, Table>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), single_table_data_t<void, Args...>{args...} };
static_assert(_check<Table>::value, "argument is not a table in single_table()");
return _single_table_impl<void>(_check<Table>{}, table);
}
private:
template<typename Database, typename Table>
auto _single_table_impl(const std::false_type&, Table table) const
-> bad_statement;
template<typename Database, typename Table>
auto _single_table_impl(const std::true_type&, Table table) const
-> _new_statement_t<std::true_type, single_table_t<Database, Table>>
{
static_assert(required_tables_of<single_table_t<Database, Table>>::size::value == 0, "argument depends on another table in single_table()");
return { static_cast<const derived_statement_t<Policies>&>(*this), single_table_data_t<Database, Table>{table} };
}
};
};

View File

@@ -112,17 +112,17 @@ namespace sqlpp
template<typename Table>
constexpr auto update(Table table)
-> decltype(blank_update_t<void>().from(table))
-> decltype(blank_update_t<void>().single_table(table))
{
return { blank_update_t<void>().from(table) };
return { blank_update_t<void>().single_table(table) };
}
template<typename Database, typename Table>
constexpr auto dynamic_update(const Database&, Table table)
-> decltype(blank_update_t<Database>().from(table))
-> decltype(blank_update_t<Database>().single_table(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return { blank_update_t<Database>().from(table) };
return { blank_update_t<Database>().single_table(table) };
}
}

View File

@@ -75,10 +75,6 @@ namespace sqlpp
using _is_dynamic = is_database<Database>;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
static_assert(detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
static_assert(detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
// Data
using _data_t = where_data_t<Database, Expressions...>;
@@ -231,28 +227,55 @@ namespace sqlpp
}
using _database_t = typename Policies::_database_t;
template<typename T>
using _new_statement_t = new_statement<Policies, no_where_t, T>;
template<typename... T>
using _check = detail::all_t<is_expression_t<T>::value...>;
template<typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_where_t, T>;
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
-> _new_statement_t<where_t<void, Args...>>
auto where(bool b) const
-> _new_statement_t<std::true_type, where_t<void, bool>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, Args...>{args...} };
return { static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, bool>{b} };
}
template<typename... Args>
auto dynamic_where(Args... args) const
-> _new_statement_t<where_t<_database_t, Args...>>
template<typename... Expressions>
auto where(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, where_t<void, Expressions...>>
{
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
return { static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<_database_t, Args...>{args...} };
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in where()");
static_assert(sizeof...(Expressions), "at least one expression argument required in where()");
return _where_impl<void>(_check<Expressions...>{}, expressions...);
}
template<typename... Expressions>
auto dynamic_where(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, where_t<_database_t, Expressions...>>
{
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in where()");
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
return _where_impl<_database_t>(_check<Expressions...>{}, expressions...);
}
private:
template<typename Database, typename... Expressions>
auto _where_impl(const std::false_type&, Expressions... expressions) const
-> bad_statement;
template<typename Database, typename... Expressions>
auto _where_impl(const std::true_type&, Expressions... expressions) const
-> _new_statement_t<std::true_type, where_t<Database, Expressions...>>
{
return { static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<_database_t, Expressions...>{expressions...} };
}
};
};