mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 12:51:13 +08:00
Remove dynamic query components
This commit is contained in:
parent
bda77c620b
commit
c347b5d11c
@ -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
|
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/result_row.h>
|
#include <sqlpp11/result_row.h>
|
||||||
@ -234,7 +233,6 @@ namespace sqlpp
|
|||||||
// The cte_t is displayed as AliasProviderName except within the with:
|
// The cte_t is displayed as AliasProviderName except within the with:
|
||||||
// - the with needs the
|
// - the with needs the
|
||||||
// AliasProviderName AS (ColumnNames) (select/union)
|
// AliasProviderName AS (ColumnNames) (select/union)
|
||||||
// The result row of the select should not have dynamic parts
|
|
||||||
template <typename AliasProvider>
|
template <typename AliasProvider>
|
||||||
struct cte_ref_t
|
struct cte_ref_t
|
||||||
{
|
{
|
||||||
@ -253,8 +251,6 @@ namespace sqlpp
|
|||||||
static_assert(not required_ctes_of<Statement>::template count<AliasProvider>(),
|
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 "
|
"common table expression must not self-reference in the first part, use union_all/union_distinct "
|
||||||
"for recursion");
|
"for recursion");
|
||||||
static_assert(is_static_result_row_t<get_result_row_t<Statement>>::value,
|
|
||||||
"ctes must not have dynamically added columns");
|
|
||||||
|
|
||||||
return {statement};
|
return {statement};
|
||||||
}
|
}
|
||||||
|
@ -135,13 +135,4 @@ namespace sqlpp
|
|||||||
return custom_query_t<void, wrap_operand_t<Parts>...>(parts...);
|
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
|
} // namespace sqlpp
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -26,9 +26,7 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sqlpp11/dynamic_join.h>
|
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/no_data.h>
|
#include <sqlpp11/no_data.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
@ -52,43 +50,8 @@ namespace sqlpp
|
|||||||
~from_data_t() = default;
|
~from_data_t() = default;
|
||||||
|
|
||||||
Table _table;
|
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
|
// FROM
|
||||||
template <typename Database, typename Table>
|
template <typename Database, typename Table>
|
||||||
struct from_t
|
struct from_t
|
||||||
@ -104,7 +67,6 @@ namespace sqlpp
|
|||||||
struct _impl_t
|
struct _impl_t
|
||||||
{
|
{
|
||||||
using _database_t = Database;
|
using _database_t = Database;
|
||||||
using _is_dynamic = is_database<_database_t>;
|
|
||||||
using _table_t = Table;
|
using _table_t = Table;
|
||||||
|
|
||||||
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
|
// 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:
|
public:
|
||||||
_data_t _data;
|
_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_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_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>
|
template <typename Table>
|
||||||
struct check_from
|
struct check_from
|
||||||
{
|
{
|
||||||
@ -196,11 +137,6 @@ namespace sqlpp
|
|||||||
template <typename Table>
|
template <typename Table>
|
||||||
using check_from_static_t = check_from_t<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
|
struct no_from_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||||
@ -264,14 +200,6 @@ namespace sqlpp
|
|||||||
return _from_impl<void>(Check{}, table);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename Table>
|
template <typename Database, typename Check, typename Table>
|
||||||
auto _from_impl(Check, Table table) const -> inconsistent<Check>;
|
auto _from_impl(Check, Table table) const -> inconsistent<Check>;
|
||||||
@ -292,10 +220,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << " FROM ";
|
context << " FROM ";
|
||||||
serialize(t._table, context);
|
serialize(t._table, context);
|
||||||
if (not t._dynamic_tables.empty())
|
|
||||||
{
|
|
||||||
interpret_list(t._dynamic_tables, "", context);
|
|
||||||
}
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,10 +229,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_from_t>().from(std::forward<T>(t));
|
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
|
} // namespace sqlpp
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
@ -51,7 +50,6 @@ namespace sqlpp
|
|||||||
~group_by_data_t() = default;
|
~group_by_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
std::tuple<Expressions...> _expressions;
|
||||||
interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -65,9 +63,7 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_group_by>;
|
using _traits = make_traits<no_value_t, tag::is_group_by>;
|
||||||
using _nodes = detail::type_vector<Expressions...>;
|
using _nodes = detail::type_vector<Expressions...>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
using _provided_aggregates = detail::make_type_set_t<Expressions...>;
|
||||||
using _provided_aggregates = typename std::
|
|
||||||
conditional<_is_dynamic::value, detail::type_set<>, detail::make_type_set_t<Expressions...>>::type;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -219,16 +193,6 @@ namespace sqlpp
|
|||||||
return _group_by_impl<void>(check_group_by_t<Expressions...>{}, expressions...);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Expressions>
|
template <typename Database, typename Check, typename... Expressions>
|
||||||
auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
|
auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
|
||||||
@ -250,17 +214,8 @@ namespace sqlpp
|
|||||||
template <typename Context, typename Database, typename... Expressions>
|
template <typename Context, typename Database, typename... Expressions>
|
||||||
Context& serialize(const group_by_data_t<Database, Expressions...>& t, Context& context)
|
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 ";
|
context << " GROUP BY ";
|
||||||
interpret_tuple(t._expressions, ',', context);
|
interpret_tuple(t._expressions, ',', context);
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
{
|
|
||||||
context << ',';
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,10 +225,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_group_by_t>().group_by(std::forward<T>(t)...);
|
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
|
} // namespace sqlpp
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
@ -51,7 +50,6 @@ namespace sqlpp
|
|||||||
~having_data_t() = default;
|
~having_data_t() = default;
|
||||||
|
|
||||||
Expression _expression;
|
Expression _expression;
|
||||||
interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -68,8 +66,6 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_having>;
|
using _traits = make_traits<no_value_t, tag::is_having>;
|
||||||
using _nodes = detail::type_vector<Expression>;
|
using _nodes = detail::type_vector<Expression>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = having_data_t<Database, Expression>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -154,8 +128,6 @@ namespace sqlpp
|
|||||||
"sqlpp::value(bool_expresson) if you really want to use a bool value here");
|
"sqlpp::value(bool_expresson) if you really want to use a bool value here");
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_having_boolean_expression_t,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_having_boolean_expression_t,
|
||||||
"having() argument has to be an sqlpp boolean expression.");
|
"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>
|
template <typename Expression>
|
||||||
struct check_having
|
struct check_having
|
||||||
@ -172,11 +144,6 @@ namespace sqlpp
|
|||||||
template <typename Expression>
|
template <typename Expression>
|
||||||
using check_having_static_t = check_having_t<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>
|
template <typename... Exprs>
|
||||||
constexpr auto are_all_parameters_expressions() -> bool
|
constexpr auto are_all_parameters_expressions() -> bool
|
||||||
{
|
{
|
||||||
@ -257,21 +224,6 @@ namespace sqlpp
|
|||||||
return _having_impl<void>(Check{}, expression);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename Expression>
|
template <typename Database, typename Check, typename Expression>
|
||||||
auto _having_impl(Check, Expression expression) const -> inconsistent<Check>;
|
auto _having_impl(Check, Expression expression) const -> inconsistent<Check>;
|
||||||
@ -292,11 +244,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << " HAVING ";
|
context << " HAVING ";
|
||||||
serialize(t._expression, context);
|
serialize(t._expression, context);
|
||||||
if (not t._dynamic_expressions.empty())
|
|
||||||
{
|
|
||||||
context << " AND ";
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +253,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_having_t>().having(std::forward<T>(t));
|
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
|
} // namespace sqlpp
|
||||||
|
@ -109,18 +109,4 @@ namespace sqlpp
|
|||||||
return {blank_insert_t<void>().into(table)};
|
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
|
} // namespace sqlpp
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <sqlpp11/expression_fwd.h>
|
#include <sqlpp11/expression_fwd.h>
|
||||||
#include <sqlpp11/insert_value.h>
|
#include <sqlpp11/insert_value.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/no_data.h>
|
#include <sqlpp11/no_data.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
@ -137,8 +136,6 @@ namespace sqlpp
|
|||||||
// (connector-container requires assignments)
|
// (connector-container requires assignments)
|
||||||
std::tuple<simple_column_t<lhs_t<Assignments>>...> _columns;
|
std::tuple<simple_column_t<lhs_t<Assignments>>...> _columns;
|
||||||
std::tuple<rhs_t<Assignments>...> _values;
|
std::tuple<rhs_t<Assignments>...> _values;
|
||||||
interpretable_list_t<Database> _dynamic_columns;
|
|
||||||
interpretable_list_t<Database> _dynamic_values;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <size_t... Indexes>
|
template <size_t... Indexes>
|
||||||
@ -636,34 +633,14 @@ namespace sqlpp
|
|||||||
template <typename Context, typename Database, typename... Assignments>
|
template <typename Context, typename Database, typename... Assignments>
|
||||||
Context& serialize(const insert_list_data_t<Database, Assignments...>& t, Context& context)
|
Context& serialize(const insert_list_data_t<Database, Assignments...>& t, Context& context)
|
||||||
{
|
{
|
||||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
context << " (";
|
||||||
{
|
interpret_tuple(t._columns, ",", context);
|
||||||
serialize(insert_default_values_data_t(), context);
|
context << ")";
|
||||||
}
|
context << " VALUES(";
|
||||||
else
|
interpret_tuple(t._values, ",", context);
|
||||||
{
|
context << ")";
|
||||||
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;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Assignments>
|
template <typename... Assignments>
|
||||||
auto insert_set(Assignments... assignments)
|
auto insert_set(Assignments... assignments)
|
||||||
@ -672,13 +649,6 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_insert_value_list_t>().set(assignments...);
|
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>
|
template <typename... Columns>
|
||||||
auto insert_columns(Columns... cols)
|
auto insert_columns(Columns... cols)
|
||||||
-> decltype(statement_t<void, no_insert_value_list_t>().columns(cols...))
|
-> decltype(statement_t<void, no_insert_value_list_t>().columns(cols...))
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_limit_is_unsigned_integral,
|
||||||
"argument for limit() must be an unsigned integral expressions");
|
"argument for limit() must be an unsigned integral expressions");
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -267,11 +177,6 @@ namespace sqlpp
|
|||||||
return _limit_impl(check_limit_t<Arg>{}, wrap_operand_t<Arg>{arg});
|
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:
|
private:
|
||||||
template <typename Check, typename Arg>
|
template <typename Check, typename Arg>
|
||||||
auto _limit_impl(Check, Arg arg) const -> inconsistent<Check>;
|
auto _limit_impl(Check, Arg arg) const -> inconsistent<Check>;
|
||||||
@ -285,17 +190,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Interpreters
|
// 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>
|
template <typename Context, typename Limit>
|
||||||
Context& serialize(const limit_data_t<Limit>& t, Context& context)
|
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));
|
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
|
} // namespace sqlpp
|
||||||
|
@ -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
|
|
@ -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,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_offset_is_unsigned_integral,
|
||||||
"argument for offset() must be an integral expressions");
|
"argument for offset() must be an integral expressions");
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -279,13 +177,6 @@ namespace sqlpp
|
|||||||
return _offset_impl(check_offset_t<Arg>{}, wrap_operand_t<Arg>{arg});
|
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:
|
private:
|
||||||
template <typename Check, typename Arg>
|
template <typename Check, typename Arg>
|
||||||
auto _offset_impl(Check, Arg arg) const -> inconsistent<Check>;
|
auto _offset_impl(Check, Arg arg) const -> inconsistent<Check>;
|
||||||
@ -307,26 +198,10 @@ namespace sqlpp
|
|||||||
return context;
|
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>
|
template <typename T>
|
||||||
auto offset(T&& t) -> decltype(statement_t<void, no_offset_t>().offset(std::forward<T>(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));
|
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
|
} // namespace sqlpp
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/unconditional.h>
|
#include <sqlpp11/unconditional.h>
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
@ -51,7 +50,6 @@ namespace sqlpp
|
|||||||
~order_by_data_t() = default;
|
~order_by_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
std::tuple<Expressions...> _expressions;
|
||||||
interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -65,8 +63,6 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_order_by>;
|
using _traits = make_traits<no_value_t, tag::is_order_by>;
|
||||||
using _nodes = detail::type_vector<Expressions...>;
|
using _nodes = detail::type_vector<Expressions...>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -217,16 +191,6 @@ namespace sqlpp
|
|||||||
return _order_by_impl<void>(check_order_by_t<Expressions...>{}, expressions...);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Expressions>
|
template <typename Database, typename Check, typename... Expressions>
|
||||||
auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
|
auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
|
||||||
@ -248,17 +212,8 @@ namespace sqlpp
|
|||||||
template <typename Context, typename Database, typename... Expressions>
|
template <typename Context, typename Database, typename... Expressions>
|
||||||
Context& serialize(const order_by_data_t<Database, Expressions...>& t, Context& context)
|
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 ";
|
context << " ORDER BY ";
|
||||||
interpret_tuple(t._expressions, ',', context);
|
interpret_tuple(t._expressions, ',', context);
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
{
|
|
||||||
context << ',';
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,10 +223,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_order_by_t>().order_by(std::forward<T>(t)...);
|
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
|
} // namespace sqlpp
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/where.h>
|
#include <sqlpp11/where.h>
|
||||||
|
|
||||||
@ -57,7 +56,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
on_conflict_data_t<ConflictTarget> _conflict_target;
|
on_conflict_data_t<ConflictTarget> _conflict_target;
|
||||||
std::tuple<Assignments...> _assignments;
|
std::tuple<Assignments...> _assignments;
|
||||||
// interpretable_list_t<Database> _dynamic_assignments;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Where data
|
// Where data
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#include <sqlpp11/expression_fwd.h>
|
#include <sqlpp11/expression_fwd.h>
|
||||||
#include <sqlpp11/field_spec.h>
|
#include <sqlpp11/field_spec.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/named_interpretable.h>
|
|
||||||
#include <sqlpp11/operand_check.h>
|
#include <sqlpp11/operand_check.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/result_row.h>
|
#include <sqlpp11/result_row.h>
|
||||||
@ -70,66 +69,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
} // namespace detail
|
} // 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>
|
template <typename Database, typename... Columns>
|
||||||
struct returning_column_list_data_t
|
struct returning_column_list_data_t
|
||||||
{
|
{
|
||||||
@ -145,7 +84,6 @@ namespace sqlpp
|
|||||||
returning_column_list_data_t& operator=(returning_column_list_data_t&&) = default;
|
returning_column_list_data_t& operator=(returning_column_list_data_t&&) = default;
|
||||||
|
|
||||||
std::tuple<Columns...> _columns;
|
std::tuple<Columns...> _columns;
|
||||||
dynamic_returning_column_list<Database> _dynamic_columns;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// static asserts...
|
// static asserts...
|
||||||
@ -160,7 +98,6 @@ namespace sqlpp
|
|||||||
using _traits = typename detail::returning_traits<Columns...>::_traits;
|
using _traits = typename detail::returning_traits<Columns...>::_traits;
|
||||||
using _nodes = ::sqlpp::detail::type_vector<Columns...>;
|
using _nodes = ::sqlpp::detail::type_vector<Columns...>;
|
||||||
using _alias_t = typename detail::returning_traits<Columns...>::_alias_t;
|
using _alias_t = typename detail::returning_traits<Columns...>::_alias_t;
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
struct _column_type
|
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;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -281,12 +185,7 @@ namespace sqlpp
|
|||||||
template <typename Db, typename Column>
|
template <typename Db, typename Column>
|
||||||
using _field_t = typename _deferred_field_t<Db, Column>::type;
|
using _field_t = typename _deferred_field_t<Db, Column>::type;
|
||||||
|
|
||||||
template <typename Db>
|
using _result_row_t = result_row_t < Db, _field_t<Db, Columns>... >;
|
||||||
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;
|
|
||||||
|
|
||||||
template <typename AliasProvider>
|
template <typename AliasProvider>
|
||||||
struct _deferred_table_t
|
struct _deferred_table_t
|
||||||
@ -310,14 +209,9 @@ namespace sqlpp
|
|||||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
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
|
size_t get_no_of_result_columns() const
|
||||||
{
|
{
|
||||||
return sizeof...(Columns) + get_dynamic_names().size();
|
return sizeof...(Columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto ..
|
// auto ..
|
||||||
@ -325,26 +219,26 @@ namespace sqlpp
|
|||||||
auto _run(Db& db, const Composite& composite) const
|
auto _run(Db& db, const Composite& composite) const
|
||||||
-> result_t<decltype(db.select(composite)), _result_row_t<Db>>
|
-> result_t<decltype(db.select(composite)), _result_row_t<Db>>
|
||||||
{
|
{
|
||||||
return {db.select(composite), get_dynamic_names()};
|
return {db.select(composite)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Db>
|
template <typename Db>
|
||||||
auto _run(Db& db) const -> result_t<decltype(db.select(std::declval<_statement_t>())), _result_row_t<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
|
// Prepare
|
||||||
template <typename Db, typename Composite>
|
template <typename Db, typename Composite>
|
||||||
auto _prepare(Db& db, const Composite& composite) const -> prepared_select_t<Db, _statement_t, 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>
|
template <typename Db>
|
||||||
auto _prepare(Db& db) const -> prepared_select_t<Db, _statement_t>
|
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...));
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Args>
|
template <typename Database, typename Check, typename... Args>
|
||||||
auto _returning_impl(const std::false_type&, std::tuple<Args...> args) const -> inconsistent<Check>;
|
auto _returning_impl(const std::false_type&, std::tuple<Args...> args) const -> inconsistent<Check>;
|
||||||
@ -484,9 +364,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << " RETURNING ";
|
context << " RETURNING ";
|
||||||
interpret_tuple(t._columns, ',', context);
|
interpret_tuple(t._columns, ',', context);
|
||||||
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
|
||||||
context << ',';
|
|
||||||
serialize(t._dynamic_columns, context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,14 +40,13 @@ namespace sqlpp
|
|||||||
|
|
||||||
using _result_row_t = typename Statement::template _result_row_t<Database>;
|
using _result_row_t = typename Statement::template _result_row_t<Database>;
|
||||||
using _parameter_list_t = make_parameter_list_t<Composite>;
|
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 _prepared_statement_t = typename Database::_prepared_statement_t;
|
||||||
|
|
||||||
using _run_check = consistent_t;
|
using _run_check = consistent_t;
|
||||||
|
|
||||||
auto _run(Database& db) const -> result_t<decltype(db.run_prepared_select(*this)), _result_row_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
|
void _bind_params() const
|
||||||
@ -56,7 +55,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
_parameter_list_t params;
|
_parameter_list_t params;
|
||||||
_dynamic_names_t _dynamic_names;
|
|
||||||
mutable _prepared_statement_t _prepared_statement;
|
mutable _prepared_statement_t _prepared_statement;
|
||||||
};
|
};
|
||||||
} // namespace sqlpp
|
} // namespace sqlpp
|
||||||
|
@ -108,17 +108,4 @@ namespace sqlpp
|
|||||||
return {blank_remove_t<void>().from(table)};
|
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
|
} // namespace sqlpp
|
||||||
|
@ -71,9 +71,8 @@ namespace sqlpp
|
|||||||
public:
|
public:
|
||||||
result_t() = default;
|
result_t() = default;
|
||||||
|
|
||||||
template <typename DynamicNames>
|
result_t(db_result_t&& result)
|
||||||
result_t(db_result_t&& result, const DynamicNames& dynamic_names)
|
: _result(std::move(result)), _result_row()
|
||||||
: _result(std::move(result)), _result_row(dynamic_names)
|
|
||||||
{
|
{
|
||||||
_result.next(_result_row);
|
_result.next(_result_row);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <sqlpp11/compat/string_view.h>
|
#include <sqlpp11/compat/string_view.h>
|
||||||
#include <sqlpp11/data_types/text.h>
|
#include <sqlpp11/data_types/text.h>
|
||||||
#include <sqlpp11/detail/index_sequence.h>
|
#include <sqlpp11/detail/index_sequence.h>
|
||||||
#include <sqlpp11/dynamic_select_column_list.h>
|
|
||||||
#include <sqlpp11/field_spec.h>
|
#include <sqlpp11/field_spec.h>
|
||||||
#include <sqlpp11/no_name.h>
|
#include <sqlpp11/no_name.h>
|
||||||
#include <sqlpp11/result_row_fwd.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(const result_row_t&) = delete;
|
||||||
result_row_t(result_row_t&&) = default;
|
result_row_t(result_row_t&&) = default;
|
||||||
result_row_t& operator=(const result_row_t&) = delete;
|
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;
|
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>
|
template <typename T>
|
||||||
struct is_static_result_row_impl
|
struct is_static_result_row_impl
|
||||||
|
@ -90,18 +90,4 @@ namespace sqlpp
|
|||||||
return blank_select_t<void>().columns(columns...);
|
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
|
} // namespace sqlpp
|
||||||
|
@ -30,11 +30,9 @@
|
|||||||
#include <sqlpp11/auto_alias.h>
|
#include <sqlpp11/auto_alias.h>
|
||||||
#include <sqlpp11/detail/column_tuple_merge.h>
|
#include <sqlpp11/detail/column_tuple_merge.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/dynamic_select_column_list.h>
|
|
||||||
#include <sqlpp11/expression_fwd.h>
|
#include <sqlpp11/expression_fwd.h>
|
||||||
#include <sqlpp11/field_spec.h>
|
#include <sqlpp11/field_spec.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/named_interpretable.h>
|
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/result_row.h>
|
#include <sqlpp11/result_row.h>
|
||||||
#include <sqlpp11/select_pseudo_table.h>
|
#include <sqlpp11/select_pseudo_table.h>
|
||||||
@ -85,7 +83,6 @@ namespace sqlpp
|
|||||||
~select_column_list_data_t() = default;
|
~select_column_list_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Columns...> _columns;
|
std::tuple<Columns...> _columns;
|
||||||
dynamic_select_column_list<Database> _dynamic_columns;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -106,8 +103,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
using _alias_t = typename detail::select_traits<Columns...>::_alias_t;
|
using _alias_t = typename detail::select_traits<Columns...>::_alias_t;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
struct _column_type
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -234,11 +201,7 @@ namespace sqlpp
|
|||||||
using _field_t = typename _deferred_field_t<Db, Column>::type;
|
using _field_t = typename _deferred_field_t<Db, Column>::type;
|
||||||
|
|
||||||
template <typename Db>
|
template <typename Db>
|
||||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
using _result_row_t = result_row_t<Db, _field_t<Db, Columns>...>;
|
||||||
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;
|
|
||||||
|
|
||||||
template <typename AliasProvider>
|
template <typename AliasProvider>
|
||||||
struct _deferred_table_t
|
struct _deferred_table_t
|
||||||
@ -262,40 +225,35 @@ namespace sqlpp
|
|||||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
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
|
size_t get_no_of_result_columns() const
|
||||||
{
|
{
|
||||||
return sizeof...(Columns) + _get_statement().get_selected_columns()._data._dynamic_columns.size();
|
return sizeof...(Columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
template <typename Db, typename Composite>
|
template <typename Db, typename Composite>
|
||||||
auto _run(Db& db, const Composite& composite) const -> result_t<decltype(db.select(composite)), _result_row_t<Db>>
|
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>
|
template <typename Db>
|
||||||
auto _run(Db& db) const -> result_t<decltype(db.select(std::declval<_statement_t>())), _result_row_t<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
|
// Prepare
|
||||||
template <typename Db, typename Composite>
|
template <typename Db, typename Composite>
|
||||||
auto _prepare(Db& db, const Composite& composite) const -> prepared_select_t<Db, _statement_t, 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>
|
template <typename Db>
|
||||||
auto _prepare(Db& db) const -> prepared_select_t<Db, _statement_t>
|
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...));
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Args>
|
template <typename Database, typename Check, typename... Args>
|
||||||
auto _columns_impl(Check, std::tuple<Args...> args) const -> inconsistent<Check>;
|
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)
|
Context& serialize(const select_column_list_data_t<Database, Columns...>& t, Context& context)
|
||||||
{
|
{
|
||||||
interpret_tuple(t._columns, ',', context);
|
interpret_tuple(t._columns, ',', context);
|
||||||
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
|
||||||
{
|
|
||||||
context << ',';
|
|
||||||
}
|
|
||||||
serialize(t._dynamic_columns, context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,10 +381,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_select_column_list_t>().columns(std::forward<T>(t)...);
|
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
|
} // namespace sqlpp
|
||||||
|
@ -51,7 +51,6 @@ namespace sqlpp
|
|||||||
~select_flag_list_data_t() = default;
|
~select_flag_list_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Flags...> _flags;
|
std::tuple<Flags...> _flags;
|
||||||
interpretable_list_t<Database> _dynamic_flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// SELECT FLAGS
|
// SELECT FLAGS
|
||||||
@ -61,8 +60,6 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_select_flag_list>;
|
using _traits = make_traits<no_value_t, tag::is_select_flag_list>;
|
||||||
using _nodes = detail::type_vector<Flags...>;
|
using _nodes = detail::type_vector<Flags...>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -207,16 +182,6 @@ namespace sqlpp
|
|||||||
return _flags_impl<void>(check_select_flags_t<Flags...>{}, flgs...);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Flags>
|
template <typename Database, typename Check, typename... Flags>
|
||||||
auto _flags_impl(Check, Flags... flgs) const -> inconsistent<Check>;
|
auto _flags_impl(Check, Flags... flgs) const -> inconsistent<Check>;
|
||||||
@ -243,11 +208,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << ' ';
|
context << ' ';
|
||||||
}
|
}
|
||||||
interpret_list(t._dynamic_flags, ',', context);
|
|
||||||
if (not t._dynamic_flags.empty())
|
|
||||||
{
|
|
||||||
context << ' ';
|
|
||||||
}
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +217,4 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_select_flag_list_t>().flags(std::forward<T>(t));
|
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
|
} // namespace sqlpp
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include <sqlpp11/select.h>
|
#include <sqlpp11/select.h>
|
||||||
#include <sqlpp11/functions.h>
|
#include <sqlpp11/functions.h>
|
||||||
#include <sqlpp11/transaction.h>
|
#include <sqlpp11/transaction.h>
|
||||||
#include <sqlpp11/boolean_expression.h>
|
|
||||||
#include <sqlpp11/without_table_check.h>
|
#include <sqlpp11/without_table_check.h>
|
||||||
#include <sqlpp11/schema_qualified_table.h>
|
#include <sqlpp11/schema_qualified_table.h>
|
||||||
#include <sqlpp11/custom_query.h>
|
#include <sqlpp11/custom_query.h>
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/result_row.h>
|
#include <sqlpp11/result_row.h>
|
||||||
|
@ -103,11 +103,4 @@ namespace sqlpp
|
|||||||
return {blank_update_t<void>().single_table(table)};
|
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
|
} // namespace sqlpp
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -48,7 +47,6 @@ namespace sqlpp
|
|||||||
~update_list_data_t() = default;
|
~update_list_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Assignments...> _assignments;
|
std::tuple<Assignments...> _assignments;
|
||||||
interpretable_list_t<Database> _dynamic_assignments;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -61,7 +59,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::is_update_list>;
|
using _traits = make_traits<no_value_t, tag::is_update_list>;
|
||||||
using _nodes = detail::type_vector<Assignments...>;
|
using _nodes = detail::type_vector<Assignments...>;
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -149,8 +120,7 @@ namespace sqlpp
|
|||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_set_single_table_t,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_set_single_table_t,
|
||||||
"set() contains assignments for columns from more than one table");
|
"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_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
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename Assignment>
|
template <typename Assignment>
|
||||||
@ -182,17 +152,6 @@ namespace sqlpp
|
|||||||
template <typename... Assignments>
|
template <typename... Assignments>
|
||||||
using check_update_static_set_t = typename check_update_static_set<Assignments...>::type;
|
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
|
struct no_update_list_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::is_where>;
|
using _traits = make_traits<no_value_t, tag::is_where>;
|
||||||
@ -265,15 +224,6 @@ namespace sqlpp
|
|||||||
return _set_impl<void>(Check{}, assignments);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Assignments>
|
template <typename Database, typename Check, typename... Assignments>
|
||||||
auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
|
auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
|
||||||
@ -294,11 +244,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << " SET ";
|
context << " SET ";
|
||||||
interpret_tuple(t._assignments, ",", context);
|
interpret_tuple(t._assignments, ",", context);
|
||||||
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
|
|
||||||
{
|
|
||||||
context << ',';
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_assignments, ',', context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
} // namespace sqlpp
|
} // namespace sqlpp
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
@ -49,7 +48,6 @@ namespace sqlpp
|
|||||||
~using_data_t() = default;
|
~using_data_t() = default;
|
||||||
|
|
||||||
std::tuple<Tables...> _tables;
|
std::tuple<Tables...> _tables;
|
||||||
interpretable_list_t<Database> _dynamic_tables;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// USING
|
// USING
|
||||||
@ -59,8 +57,6 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_using_>;
|
using _traits = make_traits<no_value_t, tag::is_using_>;
|
||||||
using _nodes = detail::type_vector<Tables...>;
|
using _nodes = detail::type_vector<Tables...>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = using_data_t<Database, Tables...>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -208,16 +184,6 @@ namespace sqlpp
|
|||||||
return {_using_impl<void>(check_using_t<Tables...>{}, tables...)};
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename... Tables>
|
template <typename Database, typename Check, typename... Tables>
|
||||||
auto _using_impl(Check, Tables... tables) const -> inconsistent<Check>;
|
auto _using_impl(Check, Tables... tables) const -> inconsistent<Check>;
|
||||||
@ -238,17 +204,8 @@ namespace sqlpp
|
|||||||
template <typename Context, typename Database, typename... Tables>
|
template <typename Context, typename Database, typename... Tables>
|
||||||
Context& serialize(const using_data_t<Database, Tables...>& t, Context& context)
|
Context& serialize(const using_data_t<Database, Tables...>& t, Context& context)
|
||||||
{
|
{
|
||||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
context << " USING ";
|
context << " USING ";
|
||||||
interpret_tuple(t._tables, ',', context);
|
interpret_tuple(t._tables, ',', context);
|
||||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
|
||||||
{
|
|
||||||
context << ',';
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_tables, ',', context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
} // namespace sqlpp
|
} // namespace sqlpp
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/statement_fwd.h>
|
#include <sqlpp11/statement_fwd.h>
|
||||||
@ -53,7 +52,6 @@ namespace sqlpp
|
|||||||
~where_data_t() = default;
|
~where_data_t() = default;
|
||||||
|
|
||||||
Expression _expression;
|
Expression _expression;
|
||||||
interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(
|
SQLPP_PORTABLE_STATIC_ASSERT(
|
||||||
@ -67,8 +65,6 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, tag::is_where>;
|
using _traits = make_traits<no_value_t, tag::is_where>;
|
||||||
using _nodes = detail::type_vector<Expression>;
|
using _nodes = detail::type_vector<Expression>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = where_data_t<Database, Expression>;
|
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:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
};
|
};
|
||||||
@ -215,8 +186,6 @@ namespace sqlpp
|
|||||||
"where() argument has to be an sqlpp boolean expression.");
|
"where() argument has to be an sqlpp boolean expression.");
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_arg_contains_no_aggregate_functions_t,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_arg_contains_no_aggregate_functions_t,
|
||||||
"at least one aggregate function used in where()");
|
"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 &
|
// workaround for msvc bugs https://connect.microsoft.com/VisualStudio/Feedback/Details/2086629 &
|
||||||
// https://connect.microsoft.com/VisualStudio/feedback/details/2173198
|
// https://connect.microsoft.com/VisualStudio/feedback/details/2173198
|
||||||
@ -247,15 +216,6 @@ namespace sqlpp
|
|||||||
template <typename Expression>
|
template <typename Expression>
|
||||||
using check_where_static_t = check_where_t<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
|
// NO WHERE YET
|
||||||
template <bool WhereRequired>
|
template <bool WhereRequired>
|
||||||
struct no_where_t
|
struct no_where_t
|
||||||
@ -330,21 +290,6 @@ namespace sqlpp
|
|||||||
return _where_impl<void>(Check{}, expression);
|
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:
|
private:
|
||||||
template <typename Database, typename Check, typename Expression>
|
template <typename Database, typename Check, typename Expression>
|
||||||
auto _where_impl(Check, Expression expression) const -> inconsistent<Check>;
|
auto _where_impl(Check, Expression expression) const -> inconsistent<Check>;
|
||||||
@ -365,23 +310,12 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << " WHERE ";
|
context << " WHERE ";
|
||||||
serialize(t._expression, context);
|
serialize(t._expression, context);
|
||||||
if (not t._dynamic_expressions.empty())
|
|
||||||
{
|
|
||||||
context << " AND ";
|
|
||||||
}
|
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Context, typename Database>
|
template <typename Context, typename Database>
|
||||||
Context& serialize(const where_data_t<Database, unconditional_t>& t, Context& context)
|
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;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,20 +331,6 @@ namespace sqlpp
|
|||||||
return statement_t<void, no_where_t<false>>().where(std::forward<T>(t));
|
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())
|
inline auto unconditionally() -> decltype(statement_t<void, no_where_t<false>>().unconditionally())
|
||||||
{
|
{
|
||||||
return statement_t<void, no_where_t<false>>().unconditionally();
|
return statement_t<void, no_where_t<false>>().unconditionally();
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <sqlpp11/column_fwd.h>
|
#include <sqlpp11/column_fwd.h>
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/no_data.h>
|
#include <sqlpp11/no_data.h>
|
||||||
#include <sqlpp11/parameter_list.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
|
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 _parameters = detail::type_vector_cat_t<parameters_of<Expressions>...>;
|
||||||
|
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = with_data_t<Database, Expressions...>;
|
using _data_t = with_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ set(test_files
|
|||||||
Operator.cpp
|
Operator.cpp
|
||||||
Over.cpp
|
Over.cpp
|
||||||
SelectAs.cpp
|
SelectAs.cpp
|
||||||
|
SelectColumns.cpp
|
||||||
|
SelectFlags.cpp
|
||||||
Some.cpp
|
Some.cpp
|
||||||
Sum.cpp
|
Sum.cpp
|
||||||
TableAlias.cpp
|
TableAlias.cpp
|
||||||
|
@ -35,7 +35,6 @@ int CustomQuery(int, char*[])
|
|||||||
{
|
{
|
||||||
const auto foo = test::TabFoo{};
|
const auto foo = test::TabFoo{};
|
||||||
const auto bar = test::TabBar{};
|
const auto bar = test::TabBar{};
|
||||||
auto db = MockDb{};
|
|
||||||
|
|
||||||
// Unconditionally
|
// Unconditionally
|
||||||
compare(__LINE__,
|
compare(__LINE__,
|
||||||
@ -55,11 +54,11 @@ int CustomQuery(int, char*[])
|
|||||||
// A full select statement made individual clauses
|
// A full select statement made individual clauses
|
||||||
compare(
|
compare(
|
||||||
__LINE__,
|
__LINE__,
|
||||||
custom_query(sqlpp::select(), dynamic_select_flags(db, sqlpp::distinct), dynamic_select_columns(db, foo.omega),
|
custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega),
|
||||||
dynamic_from(db, foo.join(bar).on(foo.omega == bar.alpha)), dynamic_where(db, bar.alpha > 17),
|
from(foo.join(bar).on(foo.omega == bar.alpha)), where(bar.alpha > 17),
|
||||||
dynamic_group_by(db, foo.omega), dynamic_having(db, avg(bar.alpha) > 19),
|
group_by(foo.omega), having(avg(bar.alpha) > 19),
|
||||||
dynamic_order_by(db, foo.omega.asc(), foo.psi.order(sqlpp::sort_type::desc)),
|
order_by(foo.omega.asc(), foo.psi.order(sqlpp::sort_type::desc)),
|
||||||
sqlpp::dynamic_limit(db), sqlpp::dynamic_offset(db)),
|
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 "
|
"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 "
|
"(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 ");
|
"ASC,tab_foo.psi DESC ");
|
||||||
|
@ -34,20 +34,9 @@ int DynamicWhere(int, char*[])
|
|||||||
const auto bar = test::TabBar{};
|
const auto bar = test::TabBar{};
|
||||||
auto db = MockDb{};
|
auto db = MockDb{};
|
||||||
|
|
||||||
compare(__LINE__, dynamic_where(db), "");
|
compare(__LINE__, sqlpp::unconditionally(), "");
|
||||||
compare(__LINE__, dynamic_where(db, bar.gamma), " WHERE tab_bar.gamma");
|
compare(__LINE__, where(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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#warning add tests with optional expressions
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -77,60 +77,6 @@ int From(int, char* [])
|
|||||||
.on(sqlpp::verbatim<sqlpp::boolean>("a.column_x>another_table.x"))),
|
.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");
|
" FROM unknown_table AS a INNER JOIN another_table ON a.column_x>another_table.x");
|
||||||
|
|
||||||
// Dynamic joins
|
#warning add tests for optional 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)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
59
tests/core/serialize/SelectColumns.cpp
Normal file
59
tests/core/serialize/SelectColumns.cpp
Normal 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;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015, Roland Bock
|
* Copyright (c) 2024, Roland Bock
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@ -23,22 +23,29 @@
|
|||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include "compare.h"
|
||||||
#include "Sample.h"
|
#include "Sample.h"
|
||||||
#include "MockDb.h"
|
|
||||||
#include <sqlpp11/sqlpp11.h>
|
#include <sqlpp11/sqlpp11.h>
|
||||||
|
|
||||||
int BooleanExpression(int, char*[])
|
int SelectFlags(int, char*[])
|
||||||
{
|
{
|
||||||
MockDb db = {};
|
const auto foo = test::TabFoo{};
|
||||||
const auto t = test::TabBar{};
|
const auto bar = test::TabBar{};
|
||||||
|
|
||||||
auto x = boolean_expression(db, not(t.alpha == 7));
|
// No flags
|
||||||
x = sqlpp::boolean_expression(db, true);
|
compare(__LINE__, select(foo.omega), "SELECT tab_foo.omega");
|
||||||
x = sqlpp::boolean_expression<MockDb>(t.beta.like("%cheesecake"));
|
|
||||||
x = x and boolean_expression(db, t.gamma);
|
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
@ -58,21 +58,6 @@ namespace
|
|||||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
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()
|
void static_from()
|
||||||
{
|
{
|
||||||
// OK
|
// OK
|
||||||
@ -90,80 +75,10 @@ namespace
|
|||||||
// Try cross joins (missing condition)
|
// Try cross joins (missing condition)
|
||||||
from_static_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
|
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* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_from();
|
static_from();
|
||||||
dynamic_from();
|
#warning add tests for optional joins
|
||||||
dynamic_from_add();
|
|
||||||
}
|
}
|
||||||
|
@ -58,22 +58,6 @@ namespace
|
|||||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
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
|
auto static_having() -> void
|
||||||
{
|
{
|
||||||
// OK
|
// OK
|
||||||
@ -103,46 +87,6 @@ namespace
|
|||||||
having_static_check<sqlpp::assert_having_boolean_expression_t>(t.alpha.as(t.beta));
|
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>
|
template <typename Assert, typename Statement, typename HavingCondition>
|
||||||
auto static_consistency_check(const Statement statement, const HavingCondition condtion) -> void
|
auto static_consistency_check(const Statement statement, const HavingCondition condtion) -> void
|
||||||
{
|
{
|
||||||
@ -188,6 +132,6 @@ namespace
|
|||||||
int main(int, char* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_having();
|
static_having();
|
||||||
dynamic_having();
|
#warning: Add tests with optional expressions?
|
||||||
consistency_check();
|
consistency_check();
|
||||||
}
|
}
|
||||||
|
@ -58,21 +58,6 @@ namespace
|
|||||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
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
|
// column alpha is not allowed, column gamma is required
|
||||||
void static_set()
|
void static_set()
|
||||||
{
|
{
|
||||||
@ -113,61 +98,10 @@ namespace
|
|||||||
set_static_check<sqlpp::assert_insert_set_single_table_t>(f.omega = 41, t.gamma = true);
|
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* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_set();
|
static_set();
|
||||||
dynamic_set();
|
#warning add tests with optional expressions
|
||||||
}
|
}
|
||||||
|
@ -173,107 +173,10 @@ namespace
|
|||||||
on_static_check<sqlpp::assert_join_on_no_foreign_table_dependencies_t>(f_f, f.omega > fa.omega);
|
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* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_join();
|
static_join();
|
||||||
dynamic_join();
|
#warning add tests for optional from
|
||||||
}
|
}
|
||||||
|
@ -58,21 +58,6 @@ namespace
|
|||||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
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()
|
void static_update_set()
|
||||||
{
|
{
|
||||||
// OK
|
// OK
|
||||||
@ -96,43 +81,10 @@ namespace
|
|||||||
update_set_static_check<sqlpp::assert_update_set_single_table_t>(t.gamma = true, f.omega = 7);
|
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* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_update_set();
|
static_update_set();
|
||||||
dynamic_update_set();
|
#warning: add tests with optional
|
||||||
}
|
}
|
||||||
|
@ -57,22 +57,7 @@ namespace
|
|||||||
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Assert, typename Expression>
|
void static_where()
|
||||||
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
|
// OK
|
||||||
where_static_check<sqlpp::consistent_t>(t.gamma);
|
where_static_check<sqlpp::consistent_t>(t.gamma);
|
||||||
@ -102,50 +87,10 @@ namespace
|
|||||||
case_when(count(t.alpha) > 0).then(t.gamma).else_(not t.gamma));
|
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* [])
|
int main(int, char* [])
|
||||||
{
|
{
|
||||||
static_where();
|
static_where();
|
||||||
dynamic_where();
|
#warning: Add test with optional expressions?
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ if (NOT MSVC)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(test_files
|
set(test_files
|
||||||
BooleanExpression.cpp
|
|
||||||
CustomQuery.cpp
|
CustomQuery.cpp
|
||||||
DateTime.cpp
|
DateTime.cpp
|
||||||
DateTimeParser.cpp
|
DateTimeParser.cpp
|
||||||
|
@ -50,11 +50,6 @@ int Insert(int, char*[])
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
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).default_values());
|
||||||
db(insert_into(t).set(t.gamma = true, t.beta = "kirschauflauf"));
|
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"),
|
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>(
|
multi_time_insert.values.add(tabDateTime.colTimePoint = std::chrono::time_point_cast<std::chrono::microseconds>(
|
||||||
std::chrono::system_clock::now()));
|
std::chrono::system_clock::now()));
|
||||||
|
|
||||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
#warning add tests with optional
|
||||||
i.insert_list.add(t.beta = "kirschauflauf");
|
|
||||||
printer.reset();
|
|
||||||
std::cerr << serialize(i, printer).str() << std::endl;
|
|
||||||
|
|
||||||
db(multi_insert);
|
db(multi_insert);
|
||||||
|
|
||||||
|
@ -139,29 +139,6 @@ int Interpret(int, char* [])
|
|||||||
serialize(select(t.alpha).from(inner), printer).str();
|
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
|
// distinct aggregate
|
||||||
serialize(count(sqlpp::distinct, t.alpha % 7), printer).str();
|
serialize(count(sqlpp::distinct, t.alpha % 7), printer).str();
|
||||||
serialize(avg(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);
|
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();
|
printer.reset();
|
||||||
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).unconditionally())),
|
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).unconditionally())),
|
||||||
printer)
|
printer)
|
||||||
|
@ -47,25 +47,14 @@ int Remove(int, char* [])
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
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), printer).str();
|
||||||
serialize(remove_from(t).where(t.beta != "transparent"), 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_(t), printer).str();
|
||||||
serialize(remove_from(t).using_(f), printer).str();
|
serialize(remove_from(t).using_(f), printer).str();
|
||||||
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
|
#warning: add tests with optional using and optional where
|
||||||
r.using_.add(t);
|
|
||||||
r.where.add(t.beta != "transparent");
|
|
||||||
printer.reset();
|
|
||||||
std::cerr << serialize(r, printer).str() << std::endl;
|
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(remove_from(t).unconditionally(), printer).str() << std::endl;
|
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()));
|
remove_from(t).where(t.beta.in(select(f.delta).from(f).unconditionally()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -141,41 +141,17 @@ int Select(int, char*[])
|
|||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(stat, printer).str() << std::endl;
|
std::cerr << serialize(stat, printer).str() << std::endl;
|
||||||
|
|
||||||
auto s0 = dynamic_select(db)
|
auto s = sqlpp::select()
|
||||||
.columns(all_of(t))
|
.columns(t.alpha)
|
||||||
.flags(sqlpp::all)
|
.flags(sqlpp::distinct)
|
||||||
.from(t)
|
.from(t)
|
||||||
.where(t.alpha > 0)
|
.where(t.alpha > 3)
|
||||||
.group_by(t.alpha)
|
.group_by(t.alpha)
|
||||||
.order_by(t.gamma.asc())
|
.order_by(t.beta.asc())
|
||||||
.having(t.gamma)
|
.having(sum(t.alpha) > parameter(t.delta))
|
||||||
.limit(7u)
|
.limit(32u)
|
||||||
.offset(19u);
|
.offset(7u);
|
||||||
|
#warning add tests for optional everything
|
||||||
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));
|
|
||||||
for (const auto& row : db(db.prepare(s)))
|
for (const auto& row : db(db.prepare(s)))
|
||||||
{
|
{
|
||||||
const sqlpp::optional<int64_t> a = row.alpha;
|
const sqlpp::optional<int64_t> a = row.alpha;
|
||||||
|
@ -350,6 +350,8 @@ int SelectType(int, char*[])
|
|||||||
std::cout << a << std::endl;
|
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();
|
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));
|
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.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)));
|
find_query.selected_columns.add(sqlpp::without_table_check(f.omega.as(alias::b)));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Test that verbatim_table compiles
|
// Test that verbatim_table compiles
|
||||||
{
|
{
|
||||||
|
@ -46,25 +46,14 @@ int Update(int, char*[])
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
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), printer).str();
|
||||||
serialize(update(t).set(t.gamma = false), 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.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();
|
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"); };
|
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")).unconditionally());
|
||||||
db(update(t)
|
db(update(t)
|
||||||
.set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4"))
|
.set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4"))
|
||||||
|
Loading…
Reference in New Issue
Block a user