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

Remove dynamic query components

This commit is contained in:
Roland Bock 2024-06-08 11:35:54 +02:00
parent bda77c620b
commit c347b5d11c
53 changed files with 137 additions and 2428 deletions

View File

@ -1,74 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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 <sqlpp11/type_traits.h>
#include <sqlpp11/interpretable.h>
namespace sqlpp
{
template <typename Database>
struct boolean_expression_t : public expression_operators<boolean_expression_t<Database>, boolean>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _nodes = detail::type_vector<>;
template <typename Expr>
boolean_expression_t(Expr expr) : _expr(expr)
{
static_assert(is_expression_t<Expr>::value, "boolean_expression requires a boolean expression argument");
static_assert(is_boolean_t<Expr>::value, "boolean_expression requires a boolean expression argument");
}
boolean_expression_t(const boolean_expression_t&) = default;
boolean_expression_t(boolean_expression_t&&) = default;
boolean_expression_t& operator=(const boolean_expression_t&) = default;
boolean_expression_t& operator=(boolean_expression_t&&) = default;
~boolean_expression_t() = default;
interpretable_t<Database> _expr;
};
template <typename Database, typename T>
boolean_expression_t<Database> boolean_expression(T t)
{
using Expr = wrap_operand_t<T>;
return {Expr{t}};
}
template <typename Database, typename T>
boolean_expression_t<Database> boolean_expression(const Database& /*unused*/, T t)
{
return boolean_expression<Database>(t);
}
template <typename Context, typename Database>
Context& serialize(const boolean_expression_t<Database>& t, Context& context)
{
return serialize(t._expr, context);
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/result_row.h>
@ -234,7 +233,6 @@ namespace sqlpp
// The cte_t is displayed as AliasProviderName except within the with:
// - the with needs the
// AliasProviderName AS (ColumnNames) (select/union)
// The result row of the select should not have dynamic parts
template <typename AliasProvider>
struct cte_ref_t
{
@ -253,8 +251,6 @@ namespace sqlpp
static_assert(not required_ctes_of<Statement>::template count<AliasProvider>(),
"common table expression must not self-reference in the first part, use union_all/union_distinct "
"for recursion");
static_assert(is_static_result_row_t<get_result_row_t<Statement>>::value,
"ctes must not have dynamically added columns");
return {statement};
}

View File

@ -135,13 +135,4 @@ namespace sqlpp
return custom_query_t<void, wrap_operand_t<Parts>...>(parts...);
}
template <typename Database, typename... Parts>
auto dynamic_custom_query(const Database& /*unused*/, Parts... parts)
-> custom_query_t<Database, wrap_operand_t<Parts>...>
{
static_assert(sizeof...(Parts) > 0, "custom query requires at least one query argument");
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return custom_query_t<Database, wrap_operand_t<Parts>...>(parts...);
}
} // namespace sqlpp

View File

@ -1,57 +0,0 @@
#pragma once
/*
* 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 <sqlpp11/dynamic_pre_join.h>
namespace sqlpp
{
template <typename PreJoin, typename On>
struct dynamic_join_t
{
using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_join>;
using _nodes = detail::type_vector<PreJoin, On>;
using _can_be_null = std::false_type;
using _provided_tables = provided_tables_of<PreJoin>;
using _required_tables = detail::make_difference_set_t<required_tables_of<On>, _provided_tables>;
static_assert(is_dynamic_pre_join_t<PreJoin>::value, "lhs argument for on() has to be a pre join");
static_assert(required_tables_of<PreJoin>::size::value == 0, "joined tables must not depend on other tables");
static_assert(is_on_t<On>::value, "invalid on expression in join().on()");
PreJoin _pre_join;
On _on;
};
template <typename Context, typename PreJoin, typename On>
Context& serialize(const dynamic_join_t<PreJoin, On>& t, Context& context)
{
serialize(t._pre_join, context);
serialize(t._on, context);
return context;
}
} // namespace sqlpp

View File

@ -1,163 +0,0 @@
#pragma once
/*
* 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 <sqlpp11/join_types.h>
#include <sqlpp11/on.h>
namespace sqlpp
{
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_pre_join_table_t, "argument of dynamic_join() has to be a table");
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_pre_join_no_join_t, "argument of dynamic_join() must not be a table");
template <typename Table>
struct check_dynamic_pre_join
{
using type =
static_combined_check_t<static_check_t<is_table_t<Table>::value, assert_dynamic_pre_join_table_t>,
static_check_t<not is_join_t<Table>::value, assert_dynamic_pre_join_no_join_t>>;
};
template <typename Table>
using check_dynamic_pre_join_t = typename check_dynamic_pre_join<Table>::type;
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_consist_of_pre_join_and_on_t,
"dynamic join has to consist of a dynamic pre_join and a join condition");
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_no_table_dependencies_t,
"dynamically joined tables must not depend on other tables");
template <typename PreJoin, typename On>
struct check_dynamic_join
{
using type = static_combined_check_t<
static_check_t<is_dynamic_pre_join_t<PreJoin>::value, assert_dynamic_join_consist_of_pre_join_and_on_t>,
static_check_t<is_on_t<On>::value, assert_dynamic_join_consist_of_pre_join_and_on_t>,
static_check_t<required_tables_of<PreJoin>::size::value == 0, assert_dynamic_join_no_table_dependencies_t>>;
};
template <typename PreJoin, typename On>
using check_dynamic_join_t = typename check_dynamic_join<PreJoin, On>::type;
template <typename PreJoin, typename Expr>
struct check_dynamic_join_on
{
using type = static_combined_check_t<check_on_t<Expr>, check_dynamic_join_t<PreJoin, on_t<Expr>>>;
};
template <typename PreJoin, typename Expr>
using check_dynamic_join_on_t = typename check_dynamic_join_on<PreJoin, Expr>::type;
template <typename PreJoin, typename On>
struct dynamic_join_t;
template <typename JoinType, typename Rhs>
struct dynamic_pre_join_t
{
using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_pre_join>;
using _nodes = detail::type_vector<Rhs>;
using _can_be_null = std::false_type;
static_assert(is_table_t<Rhs>::value, "rhs argument for dynamic_join() has to be a table");
static_assert(not is_join_t<Rhs>::value, "rhs argument for dynamic_join must not be a join");
static_assert(required_tables_of<dynamic_pre_join_t>::size::value == 0,
"joined tables must not depend on other tables");
auto unconditionally() const -> dynamic_join_t<dynamic_pre_join_t, on_t<unconditional_t>>
{
return {*this, {}};
}
template <typename Expr>
auto on(Expr expr) const -> typename std::conditional<check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::value,
dynamic_join_t<dynamic_pre_join_t, on_t<Expr>>,
check_dynamic_join_on_t<dynamic_pre_join_t, Expr>>::type
{
return {*this, {expr}};
}
Rhs _rhs;
};
template <typename Context, typename JoinType, typename Rhs>
Context& serialize(const dynamic_pre_join_t<JoinType, Rhs>& t, Context& context)
{
context << JoinType::_name;
context << " JOIN ";
serialize(t._rhs, context);
return context;
}
template <typename JoinType, typename Table>
using make_dynamic_pre_join_t = typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_pre_join_t<JoinType, Table>,
check_dynamic_pre_join_t<Table>>::type;
template <typename Table>
auto dynamic_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{
check_dynamic_pre_join_t<Table>::verify(); // FIXME: Failure return type?
return {table};
}
template <typename Table>
auto dynamic_inner_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{
check_dynamic_pre_join_t<Table>::verify();
return {table};
}
template <typename Table>
auto dynamic_left_outer_join(Table table) -> make_dynamic_pre_join_t<left_outer_join_t, Table>
{
check_dynamic_pre_join_t<Table>::verify();
return {table};
}
template <typename Table>
auto dynamic_right_outer_join(Table table) -> make_dynamic_pre_join_t<right_outer_join_t, Table>
{
check_dynamic_pre_join_t<Table>::verify();
return {table};
}
template <typename Table>
auto dynamic_outer_join(Table table) -> make_dynamic_pre_join_t<outer_join_t, Table>
{
check_dynamic_pre_join_t<Table>::verify();
return {table};
}
template <typename Table>
auto dynamic_cross_join(Table table) ->
typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_join_t<dynamic_pre_join_t<cross_join_t, Table>, on_t<unconditional_t>>,
check_dynamic_pre_join_t<Table>>::type
{
return {dynamic_pre_join_t<cross_join_t, Table>{table}, {}};
}
} // namespace sqlpp

View File

@ -1,102 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-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 <vector>
#include <string>
#include <sqlpp11/no_name.h>
#include <sqlpp11/named_interpretable.h>
namespace sqlpp
{
template <typename Db>
struct dynamic_select_column_list
{
using _names_t = std::vector<std::string>;
std::vector<named_interpretable_t<Db>> _dynamic_columns;
_names_t _dynamic_expression_names;
template <typename Expr>
void emplace_back(Expr expr)
{
_dynamic_expression_names.push_back(name_of<Expr>::template char_ptr<typename Db::_serializer_context_t>());
_dynamic_columns.emplace_back(expr);
}
bool empty() const
{
return _dynamic_columns.empty();
}
auto size() -> size_t
{
return _dynamic_columns.size();
}
};
template <>
struct dynamic_select_column_list<void>
{
using _names_t = no_name_t;
_names_t _dynamic_expression_names;
static constexpr bool empty()
{
return true;
}
static constexpr auto size() -> size_t
{
return {};
}
};
template <typename Context, typename Db>
Context& serialize(const dynamic_select_column_list<Db>& t, Context& context)
{
bool first = true;
for (const auto& column : t._dynamic_columns)
{
if (first)
{
first = false;
}
else
{
context << ',';
}
serialize(column, context);
}
return context;
}
template <typename Context>
Context& serialize(const dynamic_select_column_list<void>&, Context& context)
{
return context;
}
} // namespace sqlpp

View File

@ -26,9 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/dynamic_join.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h>
@ -52,43 +50,8 @@ namespace sqlpp
~from_data_t() = default;
Table _table;
interpretable_list_t<Database> _dynamic_tables;
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic, "from::add() requires a dynamic_from");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_not_dynamic_pre_join, "join condition missing");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic_join, "from::add(X) requires X to be a dynamic join");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_unique_names,
"from::add() must not add table names already used in from");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_no_required_tables,
"from::add():dynamic join condition depends on "
"tables not statically known, use "
"without_table_check() to express the intent");
template <typename From, typename DynamicJoin>
struct check_from_add
{
using _known_tables = provided_tables_of<typename From::_table_t>; // Hint: Joins contain more than one table
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198
// using _known_table_names = detail::transform_set_t<name_of, _known_tables>;
using _known_table_names = detail::make_name_of_set_t<_known_tables>;
using _joined_tables = provided_tables_of<DynamicJoin>;
using _joined_table_names = detail::make_name_of_set_t<_joined_tables>;
using _required_tables = required_tables_of<DynamicJoin>;
using type = static_combined_check_t<
static_check_t<From::_is_dynamic::value, assert_from_add_dynamic>,
static_check_t<not is_dynamic_pre_join_t<DynamicJoin>::value, assert_from_add_not_dynamic_pre_join>,
static_check_t<is_dynamic_join_t<DynamicJoin>::value, assert_from_add_dynamic_join>,
static_check_t<detail::is_disjunct_from<_joined_table_names, _known_table_names>::value,
assert_from_add_unique_names>,
static_check_t<detail::is_subset_of<_required_tables, _known_tables>::value,
assert_from_add_no_required_tables>
>;
};
template <typename From, typename DynamicJoin>
using check_from_add_t = typename check_from_add<From, DynamicJoin>::type;
// FROM
template <typename Database, typename Table>
struct from_t
@ -104,7 +67,6 @@ namespace sqlpp
struct _impl_t
{
using _database_t = Database;
using _is_dynamic = is_database<_database_t>;
using _table_t = Table;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
@ -113,24 +75,6 @@ namespace sqlpp
{
}
template <typename DynamicJoin>
auto add(DynamicJoin dynamicJoin) -> typename std::
conditional<check_from_add_t<_impl_t, DynamicJoin>::value, void, check_from_add_t<_impl_t, DynamicJoin>>::type
{
using Check = check_from_add_t<_impl_t, DynamicJoin>;
return _add_impl(dynamicJoin, Check{});
}
private:
template <typename DynamicJoin>
auto _add_impl(DynamicJoin dynamicJoin, consistent_t /*unused*/) -> void
{
_data._dynamic_tables.emplace_back(from_table(dynamicJoin));
}
template <typename Check, typename DynamicJoin>
auto _add_impl(DynamicJoin dynamicJoin, Check) -> inconsistent<Check>;
public:
_data_t _data;
};
@ -175,9 +119,6 @@ namespace sqlpp
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dependency_free_t, "at least one table depends on another table in from()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_no_duplicates_t, "at least one duplicate table name detected in from()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dynamic_statement_dynamic_t,
"dynamic_from must not be called in a static statement");
template <typename Table>
struct check_from
{
@ -196,11 +137,6 @@ namespace sqlpp
template <typename Table>
using check_from_static_t = check_from_t<Table>;
template <typename Database, typename Table>
using check_from_dynamic_t = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_from_dynamic_statement_dynamic_t>,
check_from_t<Table>>;
struct no_from_t
{
using _traits = make_traits<no_value_t, tag::is_noop>;
@ -264,14 +200,6 @@ namespace sqlpp
return _from_impl<void>(Check{}, table);
}
template <typename Table>
auto dynamic_from(Table table) const
-> _new_statement_t<check_from_dynamic_t<_database_t, Table>, from_t<_database_t, from_table_t<Table>>>
{
using Check = check_from_dynamic_t<_database_t, Table>;
return _from_impl<_database_t>(Check{}, table);
}
private:
template <typename Database, typename Check, typename Table>
auto _from_impl(Check, Table table) const -> inconsistent<Check>;
@ -292,10 +220,6 @@ namespace sqlpp
{
context << " FROM ";
serialize(t._table, context);
if (not t._dynamic_tables.empty())
{
interpret_list(t._dynamic_tables, "", context);
}
return context;
}
@ -305,10 +229,4 @@ namespace sqlpp
return statement_t<void, no_from_t>().from(std::forward<T>(t));
}
template <typename Database, typename T>
auto dynamic_from(const Database& /*unused*/, T&& t)
-> decltype(statement_t<Database, no_from_t>().dynamic_from(std::forward<T>(t)))
{
return statement_t<Database, no_from_t>().dynamic_from(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
@ -51,7 +50,6 @@ namespace sqlpp
~group_by_data_t() = default;
std::tuple<Expressions...> _expressions;
interpretable_list_t<Database> _dynamic_expressions;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -65,9 +63,7 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_group_by>;
using _nodes = detail::type_vector<Expressions...>;
using _is_dynamic = is_database<Database>;
using _provided_aggregates = typename std::
conditional<_is_dynamic::value, detail::type_set<>, detail::make_type_set_t<Expressions...>>::type;
using _provided_aggregates = detail::make_type_set_t<Expressions...>;
// Data
using _data_t = group_by_data_t<Database, Expressions...>;
@ -82,28 +78,6 @@ namespace sqlpp
{
}
template <typename Expression>
void add(Expression expression)
{
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
static_assert(Policies::template _no_unknown_tables<Expression>::value,
"expression uses tables unknown to this statement in group_by::add()");
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Expression>
void _add_impl(Expression expression, const std::true_type& /*unused*/)
{
_data._dynamic_expressions.emplace_back(expression);
}
template <typename Expression>
void _add_impl(Expression expression, const std::false_type&);
public:
_data_t _data;
};
@ -219,16 +193,6 @@ namespace sqlpp
return _group_by_impl<void>(check_group_by_t<Expressions...>{}, expressions...);
}
template <typename... Expressions>
auto dynamic_group_by(Expressions... expressions) const
-> _new_statement_t<check_group_by_t<Expressions...>, group_by_t<_database_t, Expressions...>>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_group_by must not be called in a static statement");
return _group_by_impl<_database_t>(check_group_by_t<Expressions...>{}, expressions...);
}
private:
template <typename Database, typename Check, typename... Expressions>
auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
@ -250,17 +214,8 @@ namespace sqlpp
template <typename Context, typename Database, typename... Expressions>
Context& serialize(const group_by_data_t<Database, Expressions...>& t, Context& context)
{
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
{
return context;
}
context << " GROUP BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
{
context << ',';
}
interpret_list(t._dynamic_expressions, ',', context);
return context;
}
@ -270,10 +225,4 @@ namespace sqlpp
return statement_t<void, no_group_by_t>().group_by(std::forward<T>(t)...);
}
template <typename Database, typename... T>
auto dynamic_group_by(const Database& /*unused*/, T&&... t)
-> decltype(statement_t<Database, no_group_by_t>().dynamic_group_by(std::forward<T>(t)...))
{
return statement_t<Database, no_group_by_t>().dynamic_group_by(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
@ -51,7 +50,6 @@ namespace sqlpp
~having_data_t() = default;
Expression _expression;
interpretable_list_t<Database> _dynamic_expressions;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -68,8 +66,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_having>;
using _nodes = detail::type_vector<Expression>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = having_data_t<Database, Expression>;
@ -83,28 +79,6 @@ namespace sqlpp
{
}
template <typename Expr>
void add(Expr expression)
{
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
static_assert(is_expression_t<Expr>::value, "invalid expression argument in having::add()");
static_assert(Policies::template _no_unknown_tables<Expr>::value,
"expression uses tables unknown to this statement in having::add()");
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value>;
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Expr>
void _add_impl(Expr expression, const std::true_type& /*unused*/)
{
_data._dynamic_expressions.emplace_back(expression);
}
template <typename Expr>
void _add_impl(Expr expression, const std::false_type&);
public:
_data_t _data;
};
@ -154,8 +128,6 @@ namespace sqlpp
"sqlpp::value(bool_expresson) if you really want to use a bool value here");
SQLPP_PORTABLE_STATIC_ASSERT(assert_having_boolean_expression_t,
"having() argument has to be an sqlpp boolean expression.");
SQLPP_PORTABLE_STATIC_ASSERT(assert_having_dynamic_statement_dynamic_t,
"dynamic_having() must not be called in a static statement");
template <typename Expression>
struct check_having
@ -172,11 +144,6 @@ namespace sqlpp
template <typename Expression>
using check_having_static_t = check_having_t<Expression>;
template <typename Database, typename Expression>
using check_having_dynamic_t = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_having_dynamic_statement_dynamic_t>,
check_having_t<Expression>>;
template <typename... Exprs>
constexpr auto are_all_parameters_expressions() -> bool
{
@ -257,21 +224,6 @@ namespace sqlpp
return _having_impl<void>(Check{}, expression);
}
template <typename Expression>
auto dynamic_having(Expression expression) const
-> _new_statement_t<check_having_dynamic_t<_database_t, Expression>, having_t<_database_t, Expression>>
{
using Check = check_having_dynamic_t<_database_t, Expression>;
return _having_impl<_database_t>(Check{}, expression);
}
auto dynamic_having() const -> _new_statement_t<check_having_dynamic_t<_database_t, boolean_operand>,
having_t<_database_t, boolean_operand>>
{
return dynamic_having(::sqlpp::value(true));
}
private:
template <typename Database, typename Check, typename Expression>
auto _having_impl(Check, Expression expression) const -> inconsistent<Check>;
@ -292,11 +244,6 @@ namespace sqlpp
{
context << " HAVING ";
serialize(t._expression, context);
if (not t._dynamic_expressions.empty())
{
context << " AND ";
}
interpret_list(t._dynamic_expressions, " AND ", context);
return context;
}
@ -306,10 +253,4 @@ namespace sqlpp
return statement_t<void, no_having_t>().having(std::forward<T>(t));
}
template <typename Database, typename T>
auto dynamic_having(const Database& /*unused*/, T&& t)
-> decltype(statement_t<Database, no_having_t>().dynamic_having(std::forward<T>(t)))
{
return statement_t<Database, no_having_t>().dynamic_having(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -109,18 +109,4 @@ namespace sqlpp
return {blank_insert_t<void>().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert(const Database & /*unused*/) -> decltype(blank_insert_t<Database>())
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_insert_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_into(const Database& /*unused*/, Table table)
-> decltype(blank_insert_t<Database>().into(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_insert_t<Database>().into(table)};
}
} // namespace sqlpp

View File

@ -31,7 +31,6 @@
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/insert_value.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h>
@ -137,8 +136,6 @@ namespace sqlpp
// (connector-container requires assignments)
std::tuple<simple_column_t<lhs_t<Assignments>>...> _columns;
std::tuple<rhs_t<Assignments>...> _values;
interpretable_list_t<Database> _dynamic_columns;
interpretable_list_t<Database> _dynamic_values;
private:
template <size_t... Indexes>
@ -635,33 +632,13 @@ namespace sqlpp
template <typename Context, typename Database, typename... Assignments>
Context& serialize(const insert_list_data_t<Database, Assignments...>& t, Context& context)
{
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
{
serialize(insert_default_values_data_t(), context);
}
else
{
context << " (";
interpret_tuple(t._columns, ",", context);
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
{
context << ',';
}
interpret_list(t._dynamic_columns, ',', context);
context << ")";
if (sizeof...(Assignments) or not t._dynamic_values.empty())
{
context << " VALUES(";
interpret_tuple(t._values, ",", context);
if (sizeof...(Assignments) and not t._dynamic_values.empty())
{
context << ',';
}
interpret_list(t._dynamic_values, ',', context);
context << ")";
}
}
return context;
}
@ -672,13 +649,6 @@ namespace sqlpp
return statement_t<void, no_insert_value_list_t>().set(assignments...);
}
template <typename Database, typename... Assignments>
auto dynamic_insert_set(Assignments... assignments)
-> decltype(statement_t<Database, no_insert_value_list_t>().dynamic_set(assignments...))
{
return statement_t<Database, no_insert_value_list_t>().dynamic_set(assignments...);
}
template <typename... Columns>
auto insert_columns(Columns... cols)
-> decltype(statement_t<void, no_insert_value_list_t>().columns(cols...))

View File

@ -1,101 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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 <memory>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/serialize.h>
namespace sqlpp
{
template <typename Db>
struct interpretable_t
{
using _serializer_context_t = typename Db::_serializer_context_t;
template <typename T>
interpretable_t(T t) : _requires_parens(requires_parens_t<T>::value), _impl(std::make_shared<_impl_t<T>>(t))
{
}
interpretable_t(const interpretable_t&) = default;
interpretable_t(interpretable_t&&) = default;
interpretable_t& operator=(const interpretable_t&) = default;
interpretable_t& operator=(interpretable_t&&) = default;
~interpretable_t() = default;
_serializer_context_t& interpret(_serializer_context_t& context) const
{
return _impl->interpret(context);
}
bool _requires_parens;
private:
struct _impl_base
{
virtual ~_impl_base() = default;
virtual _serializer_context_t& interpret(_serializer_context_t& context) const = 0;
};
template <typename T>
struct _impl_t : public _impl_base
{
static_assert(not make_parameter_list_t<T>::size::value, "parameters not supported in dynamic statement parts");
_impl_t(T t) : _t(t)
{
}
_serializer_context_t& interpret(_serializer_context_t& context) const
{
serialize(_t, context);
return context;
}
T _t;
};
std::shared_ptr<const _impl_base> _impl;
};
template <typename Context, typename Database>
Context& serialize(const interpretable_t<Database>& t, Context& context)
{
if (t._requires_parens)
{
context << '(';
t.interpret(context);
context << ')';
}
else
{
t.interpret(context);
}
return context;
}
} // namespace sqlpp

View File

@ -1,93 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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 <sqlpp11/interpretable.h>
#include <vector>
namespace sqlpp
{
template <typename Db>
struct interpretable_list_t
{
std::vector<interpretable_t<Db>> _serializables;
std::size_t size() const
{
return _serializables.size();
}
bool empty() const
{
return _serializables.empty();
}
template <typename Expr>
void emplace_back(Expr expr)
{
_serializables.emplace_back(expr);
}
};
template <>
struct interpretable_list_t<void>
{
static constexpr std::size_t size()
{
return 0;
}
static constexpr bool empty()
{
return true;
}
};
template <typename Db, typename Separator, typename Context>
auto interpret_list(const interpretable_list_t<Db>& t, const Separator& separator, Context& context)
-> Context&
{
bool first = true;
for (const auto& entry : t._serializables)
{
if (not first)
{
context << separator;
}
first = false;
serialize(entry, context);
}
return context;
}
template <typename Separator, typename Context>
auto interpret_list(const interpretable_list_t<void>&, const Separator&, Context& context)
-> Context&
{
return context;
}
} // namespace sqlpp

View File

@ -104,96 +104,6 @@ namespace sqlpp
};
};
// DYNAMIC LIMIT DATA
template <typename Database>
struct dynamic_limit_data_t
{
dynamic_limit_data_t() : _value(noop())
{
}
template <typename Limit>
dynamic_limit_data_t(Limit value) : _initialized(true), _value(wrap_operand_t<Limit>(value))
{
}
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
~dynamic_limit_data_t() = default;
bool _initialized = false;
interpretable_t<Database> _value;
};
// DYNAMIC LIMIT
template <typename Database>
struct dynamic_limit_t
{
using _traits = make_traits<no_value_t, tag::is_limit>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = dynamic_limit_data_t<Database>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
template <typename Limit>
void set(Limit value)
{
// 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_unsigned_integral_t<arg_t>::value,
"limit requires an unsigned integral value or unsigned integral parameter");
_data._value = arg_t{value};
_data._initialized = true;
}
public:
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = dynamic_limit_data_t<Database>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : limit{std::forward<Args>(args)...}
{
}
_impl_t<Policies> limit;
_impl_t<Policies>& operator()()
{
return limit;
}
const _impl_t<Policies>& operator()() const
{
return limit;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.limit)
{
return t.limit;
}
using _consistency_check = consistent_t;
};
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_limit_is_unsigned_integral,
"argument for limit() must be an unsigned integral expressions");
template <typename T>
@ -267,11 +177,6 @@ namespace sqlpp
return _limit_impl(check_limit_t<Arg>{}, wrap_operand_t<Arg>{arg});
}
auto dynamic_limit() const -> _new_statement_t<consistent_t, dynamic_limit_t<_database_t>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this), dynamic_limit_data_t<_database_t>{}};
}
private:
template <typename Check, typename Arg>
auto _limit_impl(Check, Arg arg) const -> inconsistent<Check>;
@ -285,17 +190,6 @@ namespace sqlpp
};
// Interpreters
template <typename Context, typename Database>
Context& serialize(const dynamic_limit_data_t<Database>& t, Context& context)
{
if (t._initialized)
{
context << " LIMIT ";
serialize(t._value, context);
}
return context;
}
template <typename Context, typename Limit>
Context& serialize(const limit_data_t<Limit>& t, Context& context)
{
@ -310,9 +204,4 @@ namespace sqlpp
return statement_t<void, no_limit_t>().limit(std::forward<T>(t));
}
template <typename Database>
auto dynamic_limit(const Database & /*unused*/) -> decltype(statement_t<Database, no_limit_t>().dynamic_limit())
{
return statement_t<Database, no_limit_t>().dynamic_limit();
}
} // namespace sqlpp

View File

@ -1,112 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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 <memory>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/char_sequence.h>
namespace sqlpp
{
template <typename Db>
struct named_interpretable_t
{
using _serializer_context_t = typename Db::_serializer_context_t;
template <typename T>
named_interpretable_t(T t) : _requires_parens(requires_parens_t<T>::value), _impl(std::make_shared<_impl_t<T>>(t))
{
}
named_interpretable_t(const named_interpretable_t&) = default;
named_interpretable_t(named_interpretable_t&&) = default;
named_interpretable_t& operator=(const named_interpretable_t&) = default;
named_interpretable_t& operator=(named_interpretable_t&&) = default;
~named_interpretable_t() = default;
_serializer_context_t& interpret(_serializer_context_t& context) const
{
return _impl->interpret(context);
}
std::string _get_name() const
{
return _impl->_get_name();
}
bool _requires_parens;
private:
struct _impl_base
{
virtual ~_impl_base() = default;
virtual _serializer_context_t& interpret(_serializer_context_t& context) const = 0;
virtual std::string _get_name() const = 0;
};
template <typename T>
struct _impl_t : public _impl_base
{
static_assert(not make_parameter_list_t<T>::size::value, "parameters not supported in dynamic statement parts");
_impl_t(T t) : _t(t)
{
}
_serializer_context_t& interpret(_serializer_context_t& context) const
{
serialize(_t, context);
return context;
}
std::string _get_name() const
{
return name_of<T>::template char_ptr<_serializer_context_t>();
}
T _t;
};
std::shared_ptr<const _impl_base> _impl;
};
template <typename Context, typename Database>
Context& serialize(const named_interpretable_t<Database>& t, Context& context)
{
if (t._requires_parens)
{
context << '(';
t.interpret(context);
context << ')';
}
else
{
t.interpret(context);
}
return context;
}
} // namespace sqlpp

View File

@ -104,108 +104,6 @@ namespace sqlpp
};
};
// DYNAMIC OFFSET DATA
template <typename Database>
struct dynamic_offset_data_t
{
dynamic_offset_data_t() : _value(noop())
{
}
template <typename Offset>
dynamic_offset_data_t(Offset value) : _initialized(true), _value(wrap_operand_t<Offset>(value))
{
}
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
~dynamic_offset_data_t() = default;
bool _initialized = false;
interpretable_t<Database> _value;
};
// DYNAMIC OFFSET
template <typename Database>
struct dynamic_offset_t
{
using _traits = make_traits<no_value_t, tag::is_offset>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = dynamic_offset_data_t<Database>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
template <typename Offset>
void set(Offset value)
{
// 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_unsigned_integral_t<arg_t>::value,
"offset requires an unsigned integral value or unsigned integral parameter");
_data._value = arg_t{value};
_data._initialized = true;
}
public:
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = dynamic_offset_data_t<Database>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : offset{std::forward<Args>(args)...}
{
}
_impl_t<Policies> offset;
_impl_t<Policies>& operator()()
{
return offset;
}
const _impl_t<Policies>& operator()() const
{
return offset;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.offset)
{
return t.offset;
}
using _consistency_check = consistent_t;
template <typename Offset>
void set_offset(Offset value)
{
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
using arg_t = wrap_operand_t<Offset>;
static_cast<derived_statement_t<Policies>*>(this)->_offset()._value = arg_t{value};
static_cast<derived_statement_t<Policies>*>(this)->_offset()._initialized = true;
}
};
bool _initialized = false;
interpretable_t<Database> _value;
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_offset_is_unsigned_integral,
"argument for offset() must be an integral expressions");
template <typename T>
@ -279,13 +177,6 @@ namespace sqlpp
return _offset_impl(check_offset_t<Arg>{}, wrap_operand_t<Arg>{arg});
}
auto dynamic_offset() const -> _new_statement_t<consistent_t, 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 Check, typename Arg>
auto _offset_impl(Check, Arg arg) const -> inconsistent<Check>;
@ -307,26 +198,10 @@ namespace sqlpp
return context;
}
template <typename Context, typename Database>
Context& serialize(const dynamic_offset_data_t<Database>& t, Context& context)
{
if (t._initialized)
{
context << " OFFSET ";
serialize(t._value, context);
}
return context;
}
template <typename T>
auto offset(T&& t) -> decltype(statement_t<void, no_offset_t>().offset(std::forward<T>(t)))
{
return statement_t<void, no_offset_t>().offset(std::forward<T>(t));
}
template <typename Database>
auto dynamic_offset(const Database & /*unused*/) -> decltype(statement_t<Database, no_offset_t>().dynamic_offset())
{
return statement_t<Database, no_offset_t>().dynamic_offset();
}
} // namespace sqlpp

View File

@ -27,7 +27,6 @@
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/unconditional.h>
#include <sqlpp11/logic.h>

View File

@ -28,7 +28,6 @@
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
@ -51,7 +50,6 @@ namespace sqlpp
~order_by_data_t() = default;
std::tuple<Expressions...> _expressions;
interpretable_list_t<Database> _dynamic_expressions;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -65,8 +63,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_order_by>;
using _nodes = detail::type_vector<Expressions...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = order_by_data_t<Database, Expressions...>;
@ -80,28 +76,6 @@ namespace sqlpp
{
}
template <typename Expression>
void add(Expression expression)
{
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
static_assert(is_sort_order_t<Expression>::value, "invalid expression argument in order_by::add()");
static_assert(Policies::template _no_unknown_tables<Expression>::value,
"expression uses tables unknown to this statement in order_by::add()");
using ok = logic::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value>;
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Expression>
void _add_impl(Expression expression, const std::true_type& /*unused*/)
{
_data._dynamic_expressions.emplace_back(expression);
}
template <typename Expression>
void _add_impl(Expression expression, const std::false_type&);
public:
_data_t _data;
};
@ -217,16 +191,6 @@ namespace sqlpp
return _order_by_impl<void>(check_order_by_t<Expressions...>{}, expressions...);
}
template <typename... Expressions>
auto dynamic_order_by(Expressions... expressions) const
-> _new_statement_t<check_order_by_t<Expressions...>, order_by_t<_database_t, Expressions...>>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_order_by must not be called in a static statement");
return _order_by_impl<_database_t>(check_order_by_t<Expressions...>{}, expressions...);
}
private:
template <typename Database, typename Check, typename... Expressions>
auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
@ -248,17 +212,8 @@ namespace sqlpp
template <typename Context, typename Database, typename... Expressions>
Context& serialize(const order_by_data_t<Database, Expressions...>& t, Context& context)
{
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
{
return context;
}
context << " ORDER BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
{
context << ',';
}
interpret_list(t._dynamic_expressions, ',', context);
return context;
}
@ -268,10 +223,4 @@ namespace sqlpp
return statement_t<void, no_order_by_t>().order_by(std::forward<T>(t)...);
}
template <typename Database, typename... T>
auto dynamic_order_by(const Database& /*unused*/, T&&... t)
-> decltype(statement_t<Database, no_order_by_t>().dynamic_order_by(std::forward<T>(t)...))
{
return statement_t<Database, no_order_by_t>().dynamic_order_by(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -29,7 +29,6 @@
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/where.h>
@ -57,7 +56,6 @@ namespace sqlpp
on_conflict_data_t<ConflictTarget> _conflict_target;
std::tuple<Assignments...> _assignments;
// interpretable_list_t<Database> _dynamic_assignments;
};
// Where data

View File

@ -33,7 +33,6 @@
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/named_interpretable.h>
#include <sqlpp11/operand_check.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/result_row.h>
@ -70,66 +69,6 @@ namespace sqlpp
};
} // namespace detail
template <typename Db>
struct dynamic_returning_column_list
{
using _names_t = std::vector<std::string>;
std::vector<named_interpretable_t<Db>> _dynamic_columns;
_names_t _dynamic_expression_names;
template <typename Expr>
void emplace_back(Expr expr)
{
_dynamic_expression_names.push_back(name_of<Expr>::char_ptr());
_dynamic_columns.emplace_back(expr);
}
bool empty() const
{
return _dynamic_columns.empty();
}
};
template <>
struct dynamic_returning_column_list<void>
{
using _names_t = no_name_t;
_names_t _dynamic_expression_names;
static constexpr bool empty()
{
return true;
}
};
template <typename Db>
postgresql::context_t& serialize(const postgresql::dynamic_returning_column_list<Db>& t,
postgresql::context_t& context)
{
bool first{true};
for (const auto& column : t._dynamic_columns)
{
if (first)
{
first = false;
}
else
{
context << ',';
}
serialize(column, context);
}
return context;
}
inline postgresql::context_t& serialize(const postgresql::dynamic_returning_column_list<void>&,
postgresql::context_t& context)
{
return context;
}
template <typename Database, typename... Columns>
struct returning_column_list_data_t
{
@ -145,7 +84,6 @@ namespace sqlpp
returning_column_list_data_t& operator=(returning_column_list_data_t&&) = default;
std::tuple<Columns...> _columns;
dynamic_returning_column_list<Database> _dynamic_columns;
};
// static asserts...
@ -160,7 +98,6 @@ namespace sqlpp
using _traits = typename detail::returning_traits<Columns...>::_traits;
using _nodes = ::sqlpp::detail::type_vector<Columns...>;
using _alias_t = typename detail::returning_traits<Columns...>::_alias_t;
using _is_dynamic = is_database<Database>;
struct _column_type
{
@ -179,39 +116,6 @@ namespace sqlpp
{
}
template <typename NamedExpression>
void add_ntc(NamedExpression namedExpression)
{
add<NamedExpression, std::false_type>(namedExpression);
}
template <typename NamedExpression, typename TableCheckRequired = std::true_type>
void add(NamedExpression namedExpression)
{
using named_expression = auto_alias_t<NamedExpression>;
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
static_assert(is_selectable_t<named_expression>::value,
"invalid named expression argument in selected_columns::add()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<named_expression>::value,
"named expression uses tables unknown to this statement in selected_columns::add()");
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_alias_t...>;
static_assert(not::sqlpp::detail::is_element_of<typename named_expression::_alias_t, column_names>::value,
"a column of this name is present in the select already");
using ok = logic::all_t<_is_dynamic::value, is_selectable_t<named_expression>::value>;
_add_impl(namedExpression, ok());
}
template <typename NamedExpression>
void _add_impl(NamedExpression namedExpression, const std::true_type&)
{
return _data._dynamic_columns.emplace_back(auto_alias_t<NamedExpression>{namedExpression});
}
template <typename NamedExpression>
void _add_impl(NamedExpression namedExpression, const std::false_type&);
_data_t _data;
};
@ -281,12 +185,7 @@ namespace sqlpp
template <typename Db, typename Column>
using _field_t = typename _deferred_field_t<Db, Column>::type;
template <typename Db>
using _result_row_t = typename std::conditional<_is_dynamic::value,
dynamic_result_row_t<Db, _field_t<Db, Columns>...>,
result_row_t<Db, _field_t<Db, Columns>...>>::type;
using _dynamic_names_t = typename dynamic_returning_column_list<Database>::_names_t;
using _result_row_t = result_row_t < Db, _field_t<Db, Columns>... >;
template <typename AliasProvider>
struct _deferred_table_t
@ -310,14 +209,9 @@ namespace sqlpp
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
}
const _dynamic_names_t& get_dynamic_names() const
{
return _get_statement().get_selected_columns()._data._dynamic_columns._dynamic_expression_names;
}
size_t get_no_of_result_columns() const
{
return sizeof...(Columns) + get_dynamic_names().size();
return sizeof...(Columns);
}
// auto ..
@ -325,26 +219,26 @@ namespace sqlpp
auto _run(Db& db, const Composite& composite) const
-> result_t<decltype(db.select(composite)), _result_row_t<Db>>
{
return {db.select(composite), get_dynamic_names()};
return {db.select(composite)};
}
template <typename Db>
auto _run(Db& db) const -> result_t<decltype(db.select(std::declval<_statement_t>())), _result_row_t<Db>>
{
return {db.select(_get_statement()), get_dynamic_names()};
return {db.select(_get_statement())};
}
// Prepare
template <typename Db, typename Composite>
auto _prepare(Db& db, const Composite& composite) const -> prepared_select_t<Db, _statement_t, Composite>
{
return {make_parameter_list_t<Composite>{}, get_dynamic_names(), db.prepare_select(composite)};
return {make_parameter_list_t<Composite>{}, db.prepare_select(composite)};
}
template <typename Db>
auto _prepare(Db& db) const -> prepared_select_t<Db, _statement_t>
{
return {make_parameter_list_t<_statement_t>{}, get_dynamic_names(), db.prepare_select(_get_statement())};
return {make_parameter_list_t<_statement_t>{}, db.prepare_select(_get_statement())};
}
};
};
@ -445,20 +339,6 @@ namespace sqlpp
return _returning_impl<void>(decltype(_check_args(args...)){}, ::sqlpp::detail::column_tuple_merge(args...));
}
template <typename... Args>
auto dynamic_returning(Args... args) const
-> _new_statement_t<decltype(_check_args(args...)),
decltype(detail::make_returning_column_list<_database_t>(::sqlpp::detail::column_tuple_merge(args...)))>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_columns must not be called in a static statement");
static_assert(decltype(_check_args(args...))::value,
"at least one argument is not a selectable expression in returning()");
return _returning_impl<_database_t>(decltype(_check_args(args...)){},
::sqlpp::detail::column_tuple_merge(args...));
}
private:
template <typename Database, typename Check, typename... Args>
auto _returning_impl(const std::false_type&, std::tuple<Args...> args) const -> inconsistent<Check>;
@ -484,9 +364,6 @@ namespace sqlpp
{
context << " RETURNING ";
interpret_tuple(t._columns, ',', context);
if (sizeof...(Columns) and not t._dynamic_columns.empty())
context << ',';
serialize(t._dynamic_columns, context);
return context;
}
}

View File

@ -40,14 +40,13 @@ namespace sqlpp
using _result_row_t = typename Statement::template _result_row_t<Database>;
using _parameter_list_t = make_parameter_list_t<Composite>;
using _dynamic_names_t = typename Statement::_dynamic_names_t;
using _prepared_statement_t = typename Database::_prepared_statement_t;
using _run_check = consistent_t;
auto _run(Database& db) const -> result_t<decltype(db.run_prepared_select(*this)), _result_row_t>
{
return {db.run_prepared_select(*this), _dynamic_names};
return {db.run_prepared_select(*this)};
}
void _bind_params() const
@ -56,7 +55,6 @@ namespace sqlpp
}
_parameter_list_t params;
_dynamic_names_t _dynamic_names;
mutable _prepared_statement_t _prepared_statement;
};
} // namespace sqlpp

View File

@ -108,17 +108,4 @@ namespace sqlpp
return {blank_remove_t<void>().from(table)};
}
template <typename Database>
auto dynamic_remove(const Database & /*unused*/) -> decltype(blank_remove_t<Database>())
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>()};
}
template <typename Database, typename Table>
auto dynamic_remove_from(const Database& /*unused*/, Table table) -> decltype(blank_remove_t<Database>().from(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>().from(table)};
}
} // namespace sqlpp

View File

@ -71,9 +71,8 @@ namespace sqlpp
public:
result_t() = default;
template <typename DynamicNames>
result_t(db_result_t&& result, const DynamicNames& dynamic_names)
: _result(std::move(result)), _result_row(dynamic_names)
result_t(db_result_t&& result)
: _result(std::move(result)), _result_row()
{
_result.next(_result_row);
}

View File

@ -31,7 +31,6 @@
#include <sqlpp11/compat/string_view.h>
#include <sqlpp11/data_types/text.h>
#include <sqlpp11/detail/index_sequence.h>
#include <sqlpp11/dynamic_select_column_list.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/no_name.h>
#include <sqlpp11/result_row_fwd.h>
@ -122,10 +121,6 @@ namespace sqlpp
{
}
result_row_t(const typename dynamic_select_column_list<void>::_names_t& /*unused*/) : _impl()
{
}
result_row_t(const result_row_t&) = delete;
result_row_t(result_row_t&&) = default;
result_row_t& operator=(const result_row_t&) = delete;
@ -195,108 +190,6 @@ namespace sqlpp
static constexpr auto value = logic::all_t<is_field_compatible<LFields, RFields>::value...>::value;
};
template <typename Db, typename... FieldSpecs>
struct dynamic_result_row_t
: public detail::result_row_impl<Db, detail::make_index_sequence<sizeof...(FieldSpecs)>, FieldSpecs...>
{
using _impl = detail::result_row_impl<Db, detail::make_index_sequence<sizeof...(FieldSpecs)>, FieldSpecs...>;
using _field_type = sqlpp::string_view;
bool _is_valid{false};
std::vector<std::string> _dynamic_field_names;
std::map<std::string, _field_type> _dynamic_fields;
dynamic_result_row_t() : _impl()
{
}
dynamic_result_row_t(std::vector<std::string> dynamic_field_names)
: _impl(), _dynamic_field_names(std::move(dynamic_field_names))
{
for (auto field_name : _dynamic_field_names)
{
_dynamic_fields.insert({field_name, _field_type{}});
}
}
dynamic_result_row_t(const dynamic_result_row_t&) = delete;
dynamic_result_row_t(dynamic_result_row_t&&) = default;
dynamic_result_row_t& operator=(const dynamic_result_row_t&) = delete;
dynamic_result_row_t& operator=(dynamic_result_row_t&&) = default;
void _validate()
{
_is_valid = true;
}
void _invalidate()
{
_is_valid = false;
}
bool operator==(const dynamic_result_row_t& rhs) const
{
return _is_valid == rhs._is_valid;
}
const _field_type& at(const std::string& field_name) const
{
return _dynamic_fields.at(field_name);
}
explicit operator bool() const
{
return _is_valid;
}
template <typename Target>
void _bind(Target& target)
{
_impl::_bind(target);
std::size_t index = sizeof...(FieldSpecs);
for (const auto& field_name : _dynamic_field_names)
{
target.read_field(index, _dynamic_fields.at(field_name));
++index;
}
}
template <typename Target>
void _post_bind(Target& target)
{
_impl::_post_bind(target);
std::size_t index = sizeof...(FieldSpecs);
for (const auto& field_name : _dynamic_field_names)
{
target.post_read(index, _dynamic_fields.at(field_name));
++index;
}
}
template <typename Callable>
void _apply(Callable& callable) const
{
_impl::_apply(callable);
for (const auto& field_name : _dynamic_field_names)
{
callable(_dynamic_fields.at(field_name));
}
}
template <typename Callable>
void _apply(const Callable& callable) const
{
_impl::_apply(callable);
for (const auto& field_name : _dynamic_field_names)
{
callable(_dynamic_fields.at(field_name));
}
}
};
template <typename T>
struct is_static_result_row_impl

View File

@ -90,18 +90,4 @@ namespace sqlpp
return blank_select_t<void>().columns(columns...);
}
template <typename Database>
blank_select_t<Database> dynamic_select(const Database& /*unused*/)
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {};
}
template <typename Database, typename... Columns>
auto dynamic_select(const Database& /*unused*/, Columns... columns)
-> decltype(blank_select_t<Database>().columns(columns...))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return blank_select_t<Database>().columns(columns...);
}
} // namespace sqlpp

View File

@ -30,11 +30,9 @@
#include <sqlpp11/auto_alias.h>
#include <sqlpp11/detail/column_tuple_merge.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/dynamic_select_column_list.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/named_interpretable.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_pseudo_table.h>
@ -85,7 +83,6 @@ namespace sqlpp
~select_column_list_data_t() = default;
std::tuple<Columns...> _columns;
dynamic_select_column_list<Database> _dynamic_columns;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -106,8 +103,6 @@ namespace sqlpp
using _alias_t = typename detail::select_traits<Columns...>::_alias_t;
using _is_dynamic = is_database<Database>;
struct _column_type
{
};
@ -125,34 +120,6 @@ namespace sqlpp
{
}
template <typename NamedExpression>
void add(NamedExpression namedExpression)
{
using named_expression = auto_alias_t<NamedExpression>;
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
static_assert(is_selectable_t<named_expression>::value,
"invalid named expression argument in selected_columns::add()");
static_assert(Policies::template _no_unknown_tables<named_expression>::value,
"named expression uses tables unknown to this statement in selected_columns::add()");
using column_names = detail::make_type_set_t<typename Columns::_alias_t...>;
static_assert(not column_names::template count<typename named_expression::_alias_t>(),
"a column of this name is present in the select already");
using ok =
logic::all_t<_is_dynamic::value, is_selectable_t<named_expression>::value>;
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
}
// private:
template <typename NamedExpression>
void _add_impl(NamedExpression namedExpression, const std::true_type& /*unused*/)
{
_data._dynamic_columns.emplace_back(auto_alias_t<NamedExpression>{namedExpression});
}
template <typename NamedExpression>
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
public:
_data_t _data;
};
@ -234,11 +201,7 @@ namespace sqlpp
using _field_t = typename _deferred_field_t<Db, Column>::type;
template <typename Db>
using _result_row_t = typename std::conditional<_is_dynamic::value,
dynamic_result_row_t<Db, _field_t<Db, Columns>...>,
result_row_t<Db, _field_t<Db, Columns>...>>::type;
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
using _result_row_t = result_row_t<Db, _field_t<Db, Columns>...>;
template <typename AliasProvider>
struct _deferred_table_t
@ -262,40 +225,35 @@ namespace sqlpp
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
}
const _dynamic_names_t& get_dynamic_names() const
{
return _get_statement().get_selected_columns()._data._dynamic_columns._dynamic_expression_names;
}
size_t get_no_of_result_columns() const
{
return sizeof...(Columns) + _get_statement().get_selected_columns()._data._dynamic_columns.size();
return sizeof...(Columns);
}
// Execute
template <typename Db, typename Composite>
auto _run(Db& db, const Composite& composite) const -> result_t<decltype(db.select(composite)), _result_row_t<Db>>
{
return {db.select(composite), get_dynamic_names()};
return {db.select(composite)};
}
template <typename Db>
auto _run(Db& db) const -> result_t<decltype(db.select(std::declval<_statement_t>())), _result_row_t<Db>>
{
return {db.select(_get_statement()), get_dynamic_names()};
return {db.select(_get_statement())};
}
// Prepare
template <typename Db, typename Composite>
auto _prepare(Db& db, const Composite& composite) const -> prepared_select_t<Db, _statement_t, Composite>
{
return {make_parameter_list_t<Composite>{}, get_dynamic_names(), db.prepare_select(composite)};
return {make_parameter_list_t<Composite>{}, db.prepare_select(composite)};
}
template <typename Db>
auto _prepare(Db& db) const -> prepared_select_t<Db, _statement_t>
{
return {make_parameter_list_t<_statement_t>{}, get_dynamic_names(), db.prepare_select(_get_statement())};
return {make_parameter_list_t<_statement_t>{}, db.prepare_select(_get_statement())};
}
};
};
@ -395,20 +353,6 @@ namespace sqlpp
return _columns_impl<void>(check{}, detail::column_tuple_merge(args...));
}
template <typename... Args>
auto dynamic_columns(Args... args) const
-> _new_statement_t<decltype(_check_args(detail::column_tuple_merge(args...))),
decltype(detail::make_column_list<_database_t>(detail::column_tuple_merge(args...)))>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_columns must not be called in a static statement");
using check = decltype(_check_args(detail::column_tuple_merge(args...)));
static_assert(check::value,
"at least one argument is not a selectable expression in columns()");
return _columns_impl<_database_t>(check{}, detail::column_tuple_merge(args...));
}
private:
template <typename Database, typename Check, typename... Args>
auto _columns_impl(Check, std::tuple<Args...> args) const -> inconsistent<Check>;
@ -428,11 +372,6 @@ namespace sqlpp
Context& serialize(const select_column_list_data_t<Database, Columns...>& t, Context& context)
{
interpret_tuple(t._columns, ',', context);
if (sizeof...(Columns) and not t._dynamic_columns.empty())
{
context << ',';
}
serialize(t._dynamic_columns, context);
return context;
}
@ -442,10 +381,4 @@ namespace sqlpp
return statement_t<void, no_select_column_list_t>().columns(std::forward<T>(t)...);
}
template <typename Database, typename... T>
auto dynamic_select_columns(const Database& /*unused*/, T&&... t)
-> decltype(statement_t<Database, no_select_column_list_t>().dynamic_columns(std::forward<T>(t)...))
{
return statement_t<Database, no_select_column_list_t>().dynamic_columns(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -51,7 +51,6 @@ namespace sqlpp
~select_flag_list_data_t() = default;
std::tuple<Flags...> _flags;
interpretable_list_t<Database> _dynamic_flags;
};
// SELECT FLAGS
@ -61,8 +60,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_select_flag_list>;
using _nodes = detail::type_vector<Flags...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = select_flag_list_data_t<Database, Flags...>;
@ -76,28 +73,6 @@ namespace sqlpp
{
}
template <typename Flag>
void add(Flag flag)
{
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
static_assert(Policies::template _no_unknown_tables<Flag>::value,
"flag uses tables unknown to this statement in select_flags::add()");
using ok = logic::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Flag>
void _add_impl(Flag flag, const std::true_type& /*unused*/)
{
_data._dynamic_flags.emplace_back(flag);
}
template <typename Flag>
void _add_impl(Flag flag, const std::false_type&);
public:
_data_t _data;
};
@ -207,16 +182,6 @@ namespace sqlpp
return _flags_impl<void>(check_select_flags_t<Flags...>{}, flgs...);
}
template <typename... Flags>
auto dynamic_flags(Flags... flgs) const
-> _new_statement_t<check_select_flags_t<Flags...>, select_flag_list_t<_database_t, Flags...>>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_flags must not be called in a static statement");
return _flags_impl<_database_t>(check_select_flags_t<Flags...>{}, flgs...);
}
private:
template <typename Database, typename Check, typename... Flags>
auto _flags_impl(Check, Flags... flgs) const -> inconsistent<Check>;
@ -243,11 +208,6 @@ namespace sqlpp
{
context << ' ';
}
interpret_list(t._dynamic_flags, ',', context);
if (not t._dynamic_flags.empty())
{
context << ' ';
}
return context;
}
@ -257,10 +217,4 @@ namespace sqlpp
return statement_t<void, no_select_flag_list_t>().flags(std::forward<T>(t));
}
template <typename Database, typename T>
auto dynamic_select_flags(const Database& /*unused*/, T&& t)
-> decltype(statement_t<Database, no_select_flag_list_t>().dynamic_flags(std::forward<T>(t)))
{
return statement_t<Database, no_select_flag_list_t>().dynamic_flags(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -34,7 +34,6 @@
#include <sqlpp11/select.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/boolean_expression.h>
#include <sqlpp11/without_table_check.h>
#include <sqlpp11/schema_qualified_table.h>
#include <sqlpp11/custom_query.h>

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/result_row.h>

View File

@ -103,11 +103,4 @@ namespace sqlpp
return {blank_update_t<void>().single_table(table)};
}
template <typename Database, typename Table>
constexpr auto dynamic_update(const Database& /*unused*/, Table 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>().single_table(table)};
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
@ -48,7 +47,6 @@ namespace sqlpp
~update_list_data_t() = default;
std::tuple<Assignments...> _assignments;
interpretable_list_t<Database> _dynamic_assignments;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -61,7 +59,6 @@ namespace sqlpp
{
using _traits = make_traits<no_value_t, tag::is_update_list>;
using _nodes = detail::type_vector<Assignments...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = update_list_data_t<Database, Assignments...>;
@ -76,32 +73,6 @@ namespace sqlpp
{
}
template <typename Assignment>
void add(Assignment assignment)
{
static_assert(_is_dynamic::value, "add must not be called for static from()");
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
using _assigned_columns = detail::make_type_set_t<lhs_t<Assignments>...>;
static_assert(not _assigned_columns::template count<lhs_t<Assignment>>(),
"Must not assign value to column twice");
static_assert(logic::not_t<must_not_update_t, lhs_t<Assignment>>::value, "add() argument must not be updated");
static_assert(Policies::template _no_unknown_tables<Assignment>::value,
"assignment uses tables unknown to this statement in add()");
using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value>;
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Assignment>
void _add_impl(Assignment assignment, const std::true_type& /*unused*/)
{
_data._dynamic_assignments.emplace_back(assignment);
}
template <typename Assignment>
void _add_impl(Assignment assignment, const std::false_type&);
public:
_data_t _data;
};
@ -149,8 +120,7 @@ namespace sqlpp
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_set_single_table_t,
"set() contains assignments for columns from more than one table");
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_set_count_args_t, "at least one assignment expression required in set()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_dynamic_set_statement_dynamic_t,
"dynamic_set() must not be called in a static statement");
namespace detail
{
template <typename Assignment>
@ -182,17 +152,6 @@ namespace sqlpp
template <typename... Assignments>
using check_update_static_set_t = typename check_update_static_set<Assignments...>::type;
template <typename Database, typename... Assignments>
struct check_update_dynamic_set
{
using type = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_update_dynamic_set_statement_dynamic_t>,
check_update_set_t<Assignments...>>;
};
template <typename... Assignments>
using check_update_dynamic_set_t = typename check_update_dynamic_set<Assignments...>::type;
struct no_update_list_t
{
using _traits = make_traits<no_value_t, tag::is_where>;
@ -265,15 +224,6 @@ namespace sqlpp
return _set_impl<void>(Check{}, assignments);
}
template <typename... Assignments>
auto dynamic_set(Assignments... assignments) const
-> _new_statement_t<check_update_dynamic_set_t<_database_t, Assignments...>,
update_list_t<_database_t, Assignments...>>
{
using Check = check_update_dynamic_set_t<_database_t, Assignments...>;
return _set_impl<_database_t>(Check{}, std::make_tuple(assignments...));
}
private:
template <typename Database, typename Check, typename... Assignments>
auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
@ -294,11 +244,6 @@ namespace sqlpp
{
context << " SET ";
interpret_tuple(t._assignments, ",", context);
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
{
context << ',';
}
interpret_list(t._dynamic_assignments, ',', context);
return context;
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
@ -49,7 +48,6 @@ namespace sqlpp
~using_data_t() = default;
std::tuple<Tables...> _tables;
interpretable_list_t<Database> _dynamic_tables;
};
// USING
@ -59,8 +57,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_using_>;
using _nodes = detail::type_vector<Tables...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = using_data_t<Database, Tables...>;
@ -74,26 +70,6 @@ namespace sqlpp
{
}
template <typename Table>
void add(Table table)
{
static_assert(_is_dynamic::value, "add must not be called for static using()");
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
using ok = logic::all_t<_is_dynamic::value, is_table_t<Table>::value>;
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Table>
void _add_impl(Table table, const std::true_type& /*unused*/)
{
_data._dynamic_tables.emplace_back(table);
}
template <typename Table>
void _add_impl(Table table, const std::false_type&);
public:
_data_t _data;
};
@ -208,16 +184,6 @@ namespace sqlpp
return {_using_impl<void>(check_using_t<Tables...>{}, tables...)};
}
template <typename... Tables>
auto dynamic_using(Tables... tables) const
-> _new_statement_t<check_using_t<Tables...>, using_t<_database_t, Tables...>>
{
static_assert(not std::is_same<_database_t, void>::value,
"dynamic_using must not be called in a static statement");
return {_using_impl<_database_t>(check_using_t<Tables...>{}, tables...)};
}
private:
template <typename Database, typename Check, typename... Tables>
auto _using_impl(Check, Tables... tables) const -> inconsistent<Check>;
@ -238,17 +204,8 @@ namespace sqlpp
template <typename Context, typename Database, typename... Tables>
Context& serialize(const using_data_t<Database, Tables...>& t, Context& context)
{
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
{
return context;
}
context << " USING ";
interpret_tuple(t._tables, ',', context);
if (sizeof...(Tables) and not t._dynamic_tables.empty())
{
context << ',';
}
interpret_list(t._dynamic_tables, ',', context);
return context;
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/statement_fwd.h>
@ -53,7 +52,6 @@ namespace sqlpp
~where_data_t() = default;
Expression _expression;
interpretable_list_t<Database> _dynamic_expressions;
};
SQLPP_PORTABLE_STATIC_ASSERT(
@ -67,8 +65,6 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<Expression>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = where_data_t<Database, Expression>;
@ -82,31 +78,6 @@ namespace sqlpp
{
}
template <typename Expr>
void add(Expr expression)
{
static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where");
static_assert(is_expression_t<Expr>::value, "invalid expression argument in where::add()");
static_assert(is_boolean_t<Expr>::value, "invalid expression argument in where::add()");
static_assert(Policies::template _no_unknown_tables<Expr>::value,
"expression uses tables unknown to this statement in where::add()");
static_assert(not contains_aggregate_function_t<Expr>::value,
"where expression must not contain aggregate functions");
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value>;
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Expr>
void _add_impl(Expr expression, const std::true_type& /*unused*/)
{
_data._dynamic_expressions.emplace_back(expression);
}
template <typename Expr>
void _add_impl(Expr expression, const std::false_type&);
public:
_data_t _data;
};
@ -215,8 +186,6 @@ namespace sqlpp
"where() argument has to be an sqlpp boolean expression.");
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_arg_contains_no_aggregate_functions_t,
"at least one aggregate function used in where()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_dynamic_used_with_dynamic_statement_t,
"dynamic_where() must not be called in a static statement");
// workaround for msvc bugs https://connect.microsoft.com/VisualStudio/Feedback/Details/2086629 &
// https://connect.microsoft.com/VisualStudio/feedback/details/2173198
@ -247,15 +216,6 @@ namespace sqlpp
template <typename Expression>
using check_where_static_t = check_where_t<Expression>;
template <typename Database, typename Expression>
using check_where_dynamic_t = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_where_dynamic_used_with_dynamic_statement_t>,
check_where_t<Expression>>;
template <typename Database>
using check_where_empty_dynamic_t = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_where_dynamic_used_with_dynamic_statement_t>>;
// NO WHERE YET
template <bool WhereRequired>
struct no_where_t
@ -330,21 +290,6 @@ namespace sqlpp
return _where_impl<void>(Check{}, expression);
}
template <typename Expression>
auto dynamic_where(Expression expression) const
-> _new_statement_t<check_where_dynamic_t<_database_t, Expression>, where_t<_database_t, Expression>>
{
using Check = check_where_dynamic_t<_database_t, Expression>;
return _where_impl<_database_t>(Check{}, expression);
}
auto dynamic_where() const
-> _new_statement_t<check_where_empty_dynamic_t<_database_t>, where_t<_database_t, unconditional_t>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
where_data_t<_database_t, unconditional_t>{unconditional_t{}}};
}
private:
template <typename Database, typename Check, typename Expression>
auto _where_impl(Check, Expression expression) const -> inconsistent<Check>;
@ -365,23 +310,12 @@ namespace sqlpp
{
context << " WHERE ";
serialize(t._expression, context);
if (not t._dynamic_expressions.empty())
{
context << " AND ";
}
interpret_list(t._dynamic_expressions, " AND ", context);
return context;
}
template <typename Context, typename Database>
Context& serialize(const where_data_t<Database, unconditional_t>& t, Context& context)
{
if (t._dynamic_expressions.empty())
{
return context;
}
context << " WHERE ";
interpret_list(t._dynamic_expressions, " AND ", context);
return context;
}
@ -397,20 +331,6 @@ namespace sqlpp
return statement_t<void, no_where_t<false>>().where(std::forward<T>(t));
}
template <typename Database, typename T>
auto dynamic_where(const Database& /*unused*/, T&& t)
-> decltype(statement_t<Database, no_where_t<false>>().dynamic_where(std::forward<T>(t)))
{
return statement_t<Database, no_where_t<false>>().dynamic_where(std::forward<T>(t));
}
template <typename Database>
auto dynamic_where(const Database & /*unused*/)
-> decltype(statement_t<Database, no_where_t<false>>().dynamic_where())
{
return statement_t<Database, no_where_t<false>>().dynamic_where();
}
inline auto unconditionally() -> decltype(statement_t<void, no_where_t<false>>().unconditionally())
{
return statement_t<void, no_where_t<false>>().unconditionally();

View File

@ -30,7 +30,6 @@
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/parameter_list.h>
@ -69,8 +68,6 @@ namespace sqlpp
detail::make_joined_set_t<required_ctes_of<Expressions>...>; // WITH provides common table expressions
using _parameters = detail::type_vector_cat_t<parameters_of<Expressions>...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = with_data_t<Database, Expressions...>;

View File

@ -44,6 +44,8 @@ set(test_files
Operator.cpp
Over.cpp
SelectAs.cpp
SelectColumns.cpp
SelectFlags.cpp
Some.cpp
Sum.cpp
TableAlias.cpp

View File

@ -35,7 +35,6 @@ int CustomQuery(int, char*[])
{
const auto foo = test::TabFoo{};
const auto bar = test::TabBar{};
auto db = MockDb{};
// Unconditionally
compare(__LINE__,
@ -55,11 +54,11 @@ int CustomQuery(int, char*[])
// A full select statement made individual clauses
compare(
__LINE__,
custom_query(sqlpp::select(), dynamic_select_flags(db, sqlpp::distinct), dynamic_select_columns(db, foo.omega),
dynamic_from(db, foo.join(bar).on(foo.omega == bar.alpha)), dynamic_where(db, bar.alpha > 17),
dynamic_group_by(db, foo.omega), dynamic_having(db, avg(bar.alpha) > 19),
dynamic_order_by(db, foo.omega.asc(), foo.psi.order(sqlpp::sort_type::desc)),
sqlpp::dynamic_limit(db), sqlpp::dynamic_offset(db)),
custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega),
from(foo.join(bar).on(foo.omega == bar.alpha)), where(bar.alpha > 17),
group_by(foo.omega), having(avg(bar.alpha) > 19),
order_by(foo.omega.asc(), foo.psi.order(sqlpp::sort_type::desc)),
sqlpp::limit(7u), sqlpp::offset(3u)),
"SELECT DISTINCT tab_foo.omega FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega=tab_bar.alpha) WHERE "
"(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega "
"ASC,tab_foo.psi DESC ");

View File

@ -34,20 +34,9 @@ int DynamicWhere(int, char*[])
const auto bar = test::TabBar{};
auto db = MockDb{};
compare(__LINE__, dynamic_where(db), "");
compare(__LINE__, dynamic_where(db, bar.gamma), " WHERE tab_bar.gamma");
{
auto statement = sqlpp::dynamic_where(db);
statement.where.add(without_table_check(bar.gamma));
compare(__LINE__, statement, " WHERE tab_bar.gamma");
}
{
auto statement = dynamic_where(db, bar.gamma);
statement.where.add(without_table_check(bar.gamma));
compare(__LINE__, statement, " WHERE tab_bar.gamma AND tab_bar.gamma");
}
compare(__LINE__, sqlpp::unconditionally(), "");
compare(__LINE__, where(bar.gamma), " WHERE tab_bar.gamma");
#warning add tests with optional expressions
return 0;
}

View File

@ -77,60 +77,6 @@ int From(int, char* [])
.on(sqlpp::verbatim<sqlpp::boolean>("a.column_x>another_table.x"))),
" FROM unknown_table AS a INNER JOIN another_table ON a.column_x>another_table.x");
// Dynamic joins
const auto df = dynamic_from(db, foo);
compare(__LINE__, df, " FROM tab_foo");
{
auto dfa = df;
dfa.from.add(dynamic_cross_join(bar));
compare(__LINE__, dfa, " FROM tab_foo CROSS JOIN tab_bar");
}
{
auto dfa = df;
dfa.from.add(dynamic_join(bar).on(bar.alpha > foo.omega));
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
}
{
auto dfa = df;
dfa.from.add(dynamic_inner_join(bar).on(bar.alpha > foo.omega));
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
}
{
auto dfa = df;
dfa.from.add(dynamic_outer_join(bar).on(bar.alpha > foo.omega));
compare(__LINE__, dfa, " FROM tab_foo OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
}
{
auto dfa = df;
dfa.from.add(dynamic_left_outer_join(bar).on(bar.alpha > foo.omega));
compare(__LINE__, dfa, " FROM tab_foo LEFT OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
}
{
auto dfa = df;
dfa.from.add(dynamic_right_outer_join(bar).on(bar.alpha > foo.omega));
compare(__LINE__, dfa, " FROM tab_foo RIGHT OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
}
{
auto dfa = df;
dfa.from.add(dynamic_join(bar).unconditionally());
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar");
}
{
auto dfa = df;
dfa.from.add(dynamic_inner_join(bar).on(bar.alpha > foo.omega));
dfa.from.add(dynamic_outer_join(aFoo).on(without_table_check(bar.alpha > aFoo.omega)));
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega) OUTER JOIN tab_foo AS a "
"ON (tab_bar.alpha>a.omega)");
}
// Dynamic joins involving verbatim table
{
auto dfa = df;
dfa.from.add(
dynamic_inner_join(sqlpp::verbatim_table("unknown_table"))
.on(without_table_check(bar.alpha > sqlpp::verbatim<sqlpp::floating_point>("unknown_table.column_x"))));
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN unknown_table ON (tab_bar.alpha>unknown_table.column_x)");
}
#warning add tests for optional joins
return 0;
}

View File

@ -0,0 +1,59 @@
/*
* 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 "compare.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h>
int SelectColumns(int, char*[])
{
const auto foo = test::TabFoo{};
const auto bar = test::TabBar{};
// Single column
compare(__LINE__, select(foo.omega), "SELECT tab_foo.omega");
// Two columns
compare(__LINE__, select(foo.omega, bar.alpha), "SELECT tab_foo.omega,tab_bar.alpha");
// All columns of a table
compare(__LINE__, select(all_of(foo)), "SELECT tab_foo.delta,tab_foo.epsilon,tab_foo.omega,tab_foo.psi,tab_foo.book");
// All columns of a table plus one more
compare(__LINE__, select(all_of(foo), bar.alpha), "SELECT tab_foo.delta,tab_foo.epsilon,tab_foo.omega,tab_foo.psi,tab_foo.book,tab_bar.alpha");
// One more, plus all columns of a table
compare(__LINE__, select(bar.alpha, all_of(foo)), "SELECT tab_bar.alpha,tab_foo.delta,tab_foo.epsilon,tab_foo.omega,tab_foo.psi,tab_foo.book");
// Column and aggregate function
compare(__LINE__, select(foo.omega, count(bar.alpha)), "SELECT tab_foo.omega,COUNT(tab_bar.alpha) AS count_");
// Column aliases
compare(__LINE__, select(foo.omega.as(sqlpp::alias::o), count(bar.alpha).as(sqlpp::alias::a)), "SELECT tab_foo.omega AS o,COUNT(tab_bar.alpha) AS a");
#warning: add optional column tests
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2015, Roland Bock
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -23,22 +23,29 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include "compare.h"
#include "Sample.h"
#include "MockDb.h"
#include <sqlpp11/sqlpp11.h>
int BooleanExpression(int, char*[])
int SelectFlags(int, char*[])
{
MockDb db = {};
const auto t = test::TabBar{};
const auto foo = test::TabFoo{};
const auto bar = test::TabBar{};
auto x = boolean_expression(db, not(t.alpha == 7));
x = sqlpp::boolean_expression(db, true);
x = sqlpp::boolean_expression<MockDb>(t.beta.like("%cheesecake"));
x = x and boolean_expression(db, t.gamma);
// No flags
compare(__LINE__, select(foo.omega), "SELECT tab_foo.omega");
db(select(t.alpha).from(t).where(x));
// No flags
#warning: This should work
//compare(__LINE__, sqlpp::select_flags(), "");
// No flags
compare(__LINE__, select(foo.omega).flags(sqlpp::distinct), "SELECT DISTINCT tab_foo.omega");
// One flag
compare(__LINE__, select_flags(sqlpp::distinct), "DISTINCT ");
#warning: Add tests for dynamic select flags
return 0;
}

View File

@ -58,21 +58,6 @@ namespace
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename Expression>
void from_dynamic_check(const Expression& expression)
{
static auto db = MockDb{};
using CheckResult = sqlpp::check_from_dynamic_t<decltype(db), Expression>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_select(db, t.alpha).dynamic_from(expression));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
void static_from()
{
// OK
@ -90,80 +75,10 @@ namespace
// Try cross joins (missing condition)
from_static_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
}
void dynamic_from()
{
// OK
from_dynamic_check<sqlpp::consistent_t>(t);
from_dynamic_check<sqlpp::consistent_t>(t.cross_join(f));
from_dynamic_check<sqlpp::consistent_t>(t.join(f).on(t.alpha > f.omega));
// Try a bunch of non-tables
from_dynamic_check<sqlpp::assert_from_table_t>(7);
from_dynamic_check<sqlpp::assert_from_table_t>(t.alpha);
from_dynamic_check<sqlpp::assert_from_table_t>(t.beta);
from_dynamic_check<sqlpp::assert_from_table_t>(t.gamma);
from_dynamic_check<sqlpp::assert_from_table_t>(t.delta);
// Try cross joins (missing condition)
from_dynamic_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
}
template <typename Assert, typename FromImpl, typename Expression>
void dynamic_from_add_check(FromImpl from, const Expression& expression)
{
using CheckResult = sqlpp::check_from_add_t<FromImpl, Expression>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(from.add(expression));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
void dynamic_from_add()
{
static auto db = MockDb{};
auto fromT = dynamic_select(db, t.alpha).dynamic_from(t).from;
auto staticFrom = dynamic_select(db, t.alpha).from(t).from;
const auto fa = f.as(sqlpp::alias::a);
// OK
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_join(f).on(t.alpha > f.omega));
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_inner_join(f).on(t.alpha > f.omega));
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_left_outer_join(f).on(t.alpha > f.omega));
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_right_outer_join(f).on(t.alpha > f.omega));
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_outer_join(f).on(t.alpha > f.omega));
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_cross_join(f));
// Try a bunch of non dynamic joins
dynamic_from_add_check<sqlpp::assert_from_add_dynamic>(staticFrom, 7);
// Try a bunch of non dynamic joins
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, 7);
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, t.gamma);
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, join(f, f.as(sqlpp::alias::a)));
// Try incomplete dynamic join
dynamic_from_add_check<sqlpp::assert_from_add_not_dynamic_pre_join>(fromT, dynamic_join(f));
// Try joining the same table name
dynamic_from_add_check<sqlpp::assert_from_add_unique_names>(fromT, dynamic_cross_join(t));
dynamic_from_add_check<sqlpp::assert_from_add_unique_names>(fromT, dynamic_cross_join(f.as(t)));
// Try joining with a condition that requires other tables
dynamic_from_add_check<sqlpp::assert_from_add_no_required_tables>(fromT, dynamic_join(f).on(t.alpha > fa.omega));
// If you really think you know what you are doing, use without_table_check
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_join(f).on(t.alpha > without_table_check(fa.omega)));
}
}
int main(int, char* [])
{
static_from();
dynamic_from();
dynamic_from_add();
#warning add tests for optional joins
}

View File

@ -58,22 +58,6 @@ namespace
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename Expression>
auto having_dynamic_check(const Expression& expression) -> void
{
static auto db = MockDb{};
using CheckResult = sqlpp::check_having_dynamic_t<decltype(db), Expression>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType =
decltype(dynamic_select(db, all_of(t)).from(t).unconditionally().group_by(t.alpha).dynamic_having(expression));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
auto static_having() -> void
{
// OK
@ -103,46 +87,6 @@ namespace
having_static_check<sqlpp::assert_having_boolean_expression_t>(t.alpha.as(t.beta));
}
auto dynamic_having() -> void
{
// OK
having_dynamic_check<sqlpp::consistent_t>(t.gamma);
having_dynamic_check<sqlpp::consistent_t>(t.gamma == true);
// OK using aggregate functions in having
having_dynamic_check<sqlpp::consistent_t>(count(t.alpha) > 0);
having_dynamic_check<sqlpp::consistent_t>(t.gamma and count(t.alpha) > 0);
having_dynamic_check<sqlpp::consistent_t>(case_when(count(t.alpha) > 0).then(t.gamma).else_(not t.gamma));
// Try assignment as condition
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>(t.gamma = true);
// Try non-boolean expression
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>(t.alpha);
// Try builtin bool
having_dynamic_check<sqlpp::assert_having_not_cpp_bool_t>(true);
having_dynamic_check<sqlpp::assert_having_not_cpp_bool_t>(17 > 3);
// Try some other types as expressions
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>("true");
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>(17);
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>('c');
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>(nullptr);
having_dynamic_check<sqlpp::assert_having_boolean_expression_t>(t.alpha.as(t.beta));
// Try dynamic_having on a non-dynamic select
using CheckResult = sqlpp::check_having_dynamic_t<void, sqlpp::boolean_operand>;
using ExpectedCheckResult = std::is_same<CheckResult, sqlpp::assert_having_dynamic_statement_dynamic_t>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(select(all_of(t)).from(t).dynamic_having());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_having_dynamic_statement_dynamic_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename Statement, typename HavingCondition>
auto static_consistency_check(const Statement statement, const HavingCondition condtion) -> void
{
@ -188,6 +132,6 @@ namespace
int main(int, char* [])
{
static_having();
dynamic_having();
#warning: Add tests with optional expressions?
consistency_check();
}

View File

@ -58,21 +58,6 @@ namespace
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename... Assignments>
void set_dynamic_check(const Assignments&... assignments)
{
static auto db = MockDb{};
using CheckResult = sqlpp::check_insert_dynamic_set_t<decltype(db), Assignments...>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
static_assert(ExpectedCheckResult::value, "Unexpected check result");
print_type_on_error<CheckResult>(ExpectedCheckResult{});
using ReturnType = decltype(dynamic_insert_into(db, t).dynamic_set(assignments...));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
static_assert(ExpectedReturnType::value, "Unexpected return type");
print_type_on_error<ReturnType>(ExpectedReturnType{});
}
// column alpha is not allowed, column gamma is required
void static_set()
{
@ -113,61 +98,10 @@ namespace
set_static_check<sqlpp::assert_insert_set_single_table_t>(f.omega = 41, t.gamma = true);
}
// column alpha is not allowed, column gamma is required
void dynamic_set()
{
// OK
set_dynamic_check<sqlpp::consistent_t>(t.gamma = true);
set_dynamic_check<sqlpp::consistent_t>(t.beta = "fortytwo", t.gamma = true);
set_dynamic_check<sqlpp::consistent_t>(t.beta = "fortytwo", t.gamma = true, t.delta = 42);
set_dynamic_check<sqlpp::consistent_t>(t.delta = 42, t.beta = "fortytwo", t.gamma = true);
set_dynamic_check<sqlpp::consistent_t>(t.delta = 42, t.gamma = true, t.beta = "fortytwo");
set_dynamic_check<sqlpp::consistent_t>(t.gamma = true, t.delta = 42, t.beta = "fortytwo");
// Try setting alpha
set_dynamic_check<sqlpp::assert_insert_set_allowed_t>(t.alpha = 17, t.beta = "whatever");
set_dynamic_check<sqlpp::assert_insert_set_allowed_t>(t.beta = "whatever", t.alpha = 17);
// Omitting gamma is OK in the dynamic case, since we have to assume that it gets added later
set_dynamic_check<sqlpp::consistent_t>(t.delta = 42);
set_dynamic_check<sqlpp::consistent_t>(t.beta = "whatever");
// Same with no arguments
set_dynamic_check<sqlpp::consistent_t>();
// Try none-assignment arguments
set_dynamic_check<sqlpp::assert_insert_set_assignments_t>(t.delta == 42, t.delta = 42, t.beta = "fortytwo",
t.gamma = true);
set_dynamic_check<sqlpp::assert_insert_set_assignments_t>(17, t.delta = 42, t.beta = "fortytwo", t.gamma = true);
set_dynamic_check<sqlpp::assert_insert_set_assignments_t>(t.delta = 42, t.beta = "fortytwo", t.gamma = true,
"EEEK");
// Try duplicates
set_dynamic_check<sqlpp::assert_insert_set_no_duplicates_t>(t.delta = 41, t.delta = 42, t.beta = "fortytwo",
t.gamma = true);
set_dynamic_check<sqlpp::assert_insert_set_no_duplicates_t>(t.beta = "fortyone", t.delta = 41, t.beta = "fortytwo",
t.gamma = true);
set_dynamic_check<sqlpp::assert_insert_set_no_duplicates_t>(t.gamma = false, t.delta = 41, t.beta = "fortytwo",
t.gamma = true);
// Try multiple tables
set_dynamic_check<sqlpp::assert_insert_set_single_table_t>(f.omega = 41, t.gamma = true);
// Try dynamic_set on a non-dynamic insert
using CheckResult = sqlpp::check_insert_dynamic_set_t<void>;
using ExpectedCheckResult = std::is_same<CheckResult, sqlpp::assert_insert_dynamic_set_statement_dynamic_t>;
static_assert(ExpectedCheckResult::value, "Unexpected check result");
print_type_on_error<CheckResult>(ExpectedCheckResult{});
using ReturnType = decltype(insert_into(t).dynamic_set());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_insert_dynamic_set_statement_dynamic_t>;
static_assert(ExpectedReturnType::value, "Unexpected return type");
print_type_on_error<ReturnType>(ExpectedReturnType{});
}
}
int main(int, char* [])
{
static_set();
dynamic_set();
#warning add tests with optional expressions
}

View File

@ -173,107 +173,10 @@ namespace
on_static_check<sqlpp::assert_join_on_no_foreign_table_dependencies_t>(f_f, f.omega > fa.omega);
}
template <typename Assert, typename Table>
void join_dynamic_check(const Table& table)
{
using CheckResult = sqlpp::check_dynamic_pre_join_t<Table>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using JoinType = decltype(sqlpp::dynamic_join(table));
using InnerJoinType = decltype(sqlpp::dynamic_inner_join(table));
using LeftOuterJoinType = decltype(sqlpp::dynamic_left_outer_join(table));
using RightOuterJoinType = decltype(sqlpp::dynamic_right_outer_join(table));
using OuterJoinType = decltype(sqlpp::dynamic_outer_join(table));
using CrossJoinType = decltype(sqlpp::dynamic_cross_join(table));
using ExpectedReturnType = sqlpp::logic::all_t<
(Assert::value and sqlpp::is_dynamic_pre_join_t<JoinType>::value and
sqlpp::is_dynamic_pre_join_t<InnerJoinType>::value and
sqlpp::is_dynamic_pre_join_t<LeftOuterJoinType>::value and
sqlpp::is_dynamic_pre_join_t<RightOuterJoinType>::value and
sqlpp::is_dynamic_pre_join_t<OuterJoinType>::value and sqlpp::is_dynamic_join_t<CrossJoinType>::value) xor
(std::is_same<JoinType, Assert>::value and std::is_same<InnerJoinType, Assert>::value and
std::is_same<LeftOuterJoinType, Assert>::value and std::is_same<RightOuterJoinType, Assert>::value and
std::is_same<OuterJoinType, Assert>::value and std::is_same<CrossJoinType, Assert>::value)>;
print_type_on_error<JoinType>(ExpectedReturnType{});
print_type_on_error<InnerJoinType>(ExpectedReturnType{});
print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{});
print_type_on_error<RightOuterJoinType>(ExpectedReturnType{});
print_type_on_error<OuterJoinType>(ExpectedReturnType{});
print_type_on_error<CrossJoinType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename Lhs, typename Rhs>
void on_dynamic_check(const Lhs& lhs, const Rhs& rhs)
{
using CheckResult = sqlpp::check_dynamic_join_on_t<Lhs, Rhs>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ResultType = decltype(lhs.on(rhs));
using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_join_t<ResultType>::value) xor
std::is_same<ResultType, Assert>::value>;
print_type_on_error<ResultType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
void dynamic_join()
{
// Prepare a few table aliases for tests
const auto ta = t.as(sqlpp::alias::a);
const auto fa = f.as(sqlpp::alias::a);
// OK
join_dynamic_check<sqlpp::consistent_t>(t);
join_dynamic_check<sqlpp::consistent_t>(f);
join_dynamic_check<sqlpp::consistent_t>(ta);
join_dynamic_check<sqlpp::consistent_t>(fa);
join_dynamic_check<sqlpp::consistent_t>(sqlpp::verbatim_table("tab_sample"));
join_dynamic_check<sqlpp::consistent_t>(sqlpp::verbatim_table("tab_sample").as(sqlpp::alias::a));
// Try a bunch of non-tables
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(7);
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.alpha);
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.beta);
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.gamma);
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.delta);
// Try (pre) joins
join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.join(f));
join_dynamic_check<sqlpp::assert_dynamic_pre_join_no_join_t>(t.cross_join(f));
// Prepare a dynamic_pre_joins for tests:
const auto tj = dynamic_join(t);
const auto fj = dynamic_join(f);
const auto vj = dynamic_join(sqlpp::verbatim_table("tab_sample"));
// OK dynamic_join.on()
on_dynamic_check<sqlpp::consistent_t>(tj, t.alpha > f.omega);
on_dynamic_check<sqlpp::consistent_t>(fj, t.alpha < f.omega);
// Try dynamic_join.on(non-expression)
on_dynamic_check<sqlpp::assert_on_is_expression_t>(tj, true);
on_dynamic_check<sqlpp::assert_on_is_expression_t>(tj, 7);
on_dynamic_check<sqlpp::assert_on_is_expression_t>(tj, t);
// Try dynamic_join.on(non-boolean)
on_dynamic_check<sqlpp::assert_on_is_boolean_expression_t>(tj, t.alpha);
on_dynamic_check<sqlpp::assert_on_is_boolean_expression_t>(tj, t.beta);
on_dynamic_check<sqlpp::assert_on_is_boolean_expression_t>(tj, f.omega);
// OK dynamic_join.on(foreign-table)
on_dynamic_check<sqlpp::consistent_t>(tj, ta.alpha != 0);
on_dynamic_check<sqlpp::consistent_t>(tj, t.gamma);
on_dynamic_check<sqlpp::consistent_t>(tj, f.omega > fa.omega);
on_dynamic_check<sqlpp::consistent_t>(vj, t.alpha < f.omega);
}
}
int main(int, char* [])
{
static_join();
dynamic_join();
#warning add tests for optional from
}

View File

@ -58,21 +58,6 @@ namespace
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename... Expressions>
void update_set_dynamic_check(const Expressions&... expressions)
{
static auto db = MockDb{};
using CheckResult = sqlpp::check_update_dynamic_set_t<decltype(db), Expressions...>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_update(db, t).dynamic_set(expressions...));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
void static_update_set()
{
// OK
@ -96,43 +81,10 @@ namespace
update_set_static_check<sqlpp::assert_update_set_single_table_t>(t.gamma = true, f.omega = 7);
}
void dynamic_update_set()
{
// OK
update_set_dynamic_check<sqlpp::consistent_t>(t.gamma = true);
update_set_dynamic_check<sqlpp::consistent_t>(t.gamma = true, t.beta = "");
// Try to update nothing
update_set_dynamic_check<sqlpp::consistent_t>();
// Try condition as assignment
update_set_dynamic_check<sqlpp::assert_update_set_assignments_t>(t.gamma == true);
// Try duplicate columns
update_set_dynamic_check<sqlpp::assert_update_set_no_duplicates_t>(t.gamma = true, t.gamma = false);
update_set_dynamic_check<sqlpp::assert_update_set_no_duplicates_t>(t.gamma = true, t.beta = "", t.gamma = false);
// Try to update prohibited columns
update_set_dynamic_check<sqlpp::assert_update_set_allowed_t>(t.alpha = 42);
// Try to update multiple tables at once
update_set_dynamic_check<sqlpp::assert_update_set_single_table_t>(t.gamma = true, f.omega = 7);
// Try dynamic_set on a non-dynamic update
using CheckResult = sqlpp::check_update_dynamic_set_t<void, sqlpp::boolean_operand>;
using ExpectedCheckResult = std::is_same<CheckResult, sqlpp::assert_update_dynamic_set_statement_dynamic_t>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(update(t).dynamic_set());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_update_dynamic_set_statement_dynamic_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
}
int main(int, char* [])
{
static_update_set();
dynamic_update_set();
#warning: add tests with optional
}

View File

@ -57,21 +57,6 @@ namespace
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
template <typename Assert, typename Expression>
void where_dynamic_check(const Expression& expression)
{
static auto db = MockDb{};
using CheckResult = sqlpp::check_where_dynamic_t<decltype(db), Expression>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_remove_from(db, t).dynamic_where(expression));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
void static_where()
{
// OK
@ -102,50 +87,10 @@ namespace
case_when(count(t.alpha) > 0).then(t.gamma).else_(not t.gamma));
}
void dynamic_where()
{
// OK
where_dynamic_check<sqlpp::consistent_t>(t.gamma);
where_dynamic_check<sqlpp::consistent_t>(t.gamma == true);
// Try assignment as condition
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>(t.gamma = true);
// Try non-boolean expression
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>(t.alpha);
// Try builtin bool
where_dynamic_check<sqlpp::assert_where_arg_is_not_cpp_bool_t>(true);
where_dynamic_check<sqlpp::assert_where_arg_is_not_cpp_bool_t>(17 > 3);
// Try some other types as expressions
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>("true");
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>(17);
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>('c');
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>(nullptr);
where_dynamic_check<sqlpp::assert_where_arg_is_boolean_expression_t>(t.alpha.as(t.beta));
// Try using aggregate functions in where
where_dynamic_check<sqlpp::assert_where_arg_contains_no_aggregate_functions_t>(count(t.alpha) > 0);
where_dynamic_check<sqlpp::assert_where_arg_contains_no_aggregate_functions_t>(t.gamma and count(t.alpha) > 0);
where_dynamic_check<sqlpp::assert_where_arg_contains_no_aggregate_functions_t>(
case_when(count(t.alpha) > 0).then(t.gamma).else_(not t.gamma));
// Try dynamic_where on a non-dynamic remove
using CheckResult = sqlpp::check_where_dynamic_t<void, sqlpp::boolean_operand>;
using ExpectedCheckResult = std::is_same<CheckResult, sqlpp::assert_where_dynamic_used_with_dynamic_statement_t>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(remove_from(t).dynamic_where());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_where_dynamic_used_with_dynamic_statement_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type");
}
}
int main(int, char* [])
{
static_where();
dynamic_where();
#warning: Add test with optional expressions?
}

View File

@ -30,7 +30,6 @@ if (NOT MSVC)
endif ()
set(test_files
BooleanExpression.cpp
CustomQuery.cpp
DateTime.cpp
DateTimeParser.cpp

View File

@ -50,11 +50,6 @@ int Insert(int, char*[])
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
{
using T = decltype(dynamic_insert_into(db, t).dynamic_set());
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
db(insert_into(t).default_values());
db(insert_into(t).set(t.gamma = true, t.beta = "kirschauflauf"));
db(insert_into(t).set(t.gamma = sqlpp::default_value, t.beta = sqlpp::value_or_null("pie"),
@ -82,10 +77,7 @@ int Insert(int, char*[])
multi_time_insert.values.add(tabDateTime.colTimePoint = std::chrono::time_point_cast<std::chrono::microseconds>(
std::chrono::system_clock::now()));
auto i = dynamic_insert_into(db, t).dynamic_set();
i.insert_list.add(t.beta = "kirschauflauf");
printer.reset();
std::cerr << serialize(i, printer).str() << std::endl;
#warning add tests with optional
db(multi_insert);

View File

@ -139,29 +139,6 @@ int Interpret(int, char* [])
serialize(select(t.alpha).from(inner), printer).str();
}
// dynamic select
{
auto s = dynamic_select(db).dynamic_flags().dynamic_columns().from(t);
s.selected_columns.add(t.beta);
s.selected_columns.add(t.gamma);
serialize(s, printer).str();
}
{
auto s = dynamic_select(db).dynamic_flags().dynamic_columns().from(t);
s.select_flags.add(sqlpp::distinct);
s.selected_columns.add(t.beta);
s.selected_columns.add(t.gamma);
serialize(s, printer).str();
}
{
// Behold, dynamically constructed queries might compile but be illegal SQL
auto s = dynamic_select(db).dynamic_flags(sqlpp::distinct).dynamic_columns(t.alpha);
s.select_flags.add(sqlpp::all);
s.selected_columns.add(without_table_check(t.beta));
s.selected_columns.add(without_table_check(t.gamma));
serialize(s, printer).str();
}
// distinct aggregate
serialize(count(sqlpp::distinct, t.alpha % 7), printer).str();
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).str();
@ -181,13 +158,6 @@ int Interpret(int, char* [])
flatten(t.alpha == 7, db);
auto x = boolean_expression(db, t.alpha == 7);
x = sqlpp::boolean_expression<MockDb>(t.beta.like("%cheesecake"));
x = x and boolean_expression(db, t.gamma);
std::cerr << "----------------------------" << std::endl;
printer.reset();
std::cerr << serialize(x, printer).str() << std::endl;
printer.reset();
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).unconditionally())),
printer)

View File

@ -47,25 +47,14 @@ int Remove(int, char* [])
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
{
using T = decltype(dynamic_remove_from(db, t).dynamic_using().dynamic_where());
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
serialize(remove_from(t), printer).str();
serialize(remove_from(t).where(t.beta != "transparent"), printer).str();
serialize(remove_from(t).using_(t), printer).str();
serialize(remove_from(t).using_(f), printer).str();
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
r.using_.add(t);
r.where.add(t.beta != "transparent");
printer.reset();
std::cerr << serialize(r, printer).str() << std::endl;
#warning: add tests with optional using and optional where
printer.reset();
std::cerr << serialize(remove_from(t).unconditionally(), printer).str() << std::endl;
db(r);
remove_from(t).where(t.beta.in(select(f.delta).from(f).unconditionally()));
return 0;

View File

@ -141,41 +141,17 @@ int Select(int, char*[])
printer.reset();
std::cerr << serialize(stat, printer).str() << std::endl;
auto s0 = dynamic_select(db)
.columns(all_of(t))
.flags(sqlpp::all)
auto s = sqlpp::select()
.columns(t.alpha)
.flags(sqlpp::distinct)
.from(t)
.where(t.alpha > 0)
.where(t.alpha > 3)
.group_by(t.alpha)
.order_by(t.gamma.asc())
.having(t.gamma)
.limit(7u)
.offset(19u);
printer.reset();
std::cerr << serialize(s0, printer).str() << std::endl;
auto s = dynamic_select(db)
.dynamic_columns(all_of(t))
.dynamic_flags()
.dynamic_from(t)
.dynamic_where()
.dynamic_group_by(t.alpha)
.dynamic_order_by()
.dynamic_having(sum(t.alpha) > parameter(t.delta))
.dynamic_limit()
.dynamic_offset();
s.select_flags.add(sqlpp::distinct);
s.selected_columns.add(without_table_check(f.omega));
s.selected_columns.add(select(f.omega).from(f).unconditionally().as(f.delta));
s.from.add(dynamic_cross_join(f));
s.where.add(t.alpha > 7);
s.having.add(t.alpha > 7);
s.limit.set(3u);
s.offset.set(3u);
s.group_by.add(t.beta);
s.order_by.add(t.beta.asc());
s.order_by.add(t.delta.order(sqlpp::sort_type::desc));
.order_by(t.beta.asc())
.having(sum(t.alpha) > parameter(t.delta))
.limit(32u)
.offset(7u);
#warning add tests for optional everything
for (const auto& row : db(db.prepare(s)))
{
const sqlpp::optional<int64_t> a = row.alpha;

View File

@ -350,6 +350,8 @@ int SelectType(int, char*[])
std::cout << a << std::endl;
}
#warning add tests for dynamic everything.
/*
{
auto s = dynamic_select(db, all_of(t)).dynamic_from(t).dynamic_where().dynamic_limit().dynamic_offset();
s.from.add(dynamic_join(f).on(f.omega > t.alpha));
@ -375,6 +377,7 @@ int SelectType(int, char*[])
find_query.from.add(sqlpp::dynamic_join(f).on(t.alpha == f.omega));
find_query.selected_columns.add(sqlpp::without_table_check(f.omega.as(alias::b)));
}
*/
// Test that verbatim_table compiles
{

View File

@ -46,25 +46,14 @@ int Update(int, char*[])
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
{
using T = decltype(dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where());
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}
serialize(update(t), printer).str();
serialize(update(t).set(t.gamma = false), printer).str();
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).str();
serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta + "this is nonsense"), printer).str();
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
u.assignments.add(t.beta = "cannot update gamma a second time");
u.where.add(t.gamma != false);
printer.reset();
std::cerr << serialize(u, printer).str() << std::endl;
db(u);
auto values = [&t]() { return std::make_tuple(t.delta += t.alpha, t.beta = "no cake this time"); };
#warning add tests with dynamic set and dynamic where
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).unconditionally());
db(update(t)
.set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4"))