0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Can extract parameters from expression

This commit is contained in:
Roland Bock 2013-11-22 09:42:28 +01:00
parent 1aa67c6604
commit 8f99a03359
12 changed files with 136 additions and 6 deletions

View File

@ -63,6 +63,7 @@ namespace sqlpp
using _is_boolean = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = bool;
struct plus_
{

View File

@ -40,6 +40,7 @@ namespace sqlpp
using _is_assignment = std::true_type;
using column_type = Lhs;
using value_type = Rhs;
using _parameters = std::tuple<Lhs, Rhs>;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
@ -64,6 +65,7 @@ namespace sqlpp
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
{
using _value_type = ValueType;
using _parameters = std::tuple<Lhs, Rhs>;
template<typename L, typename R>
equal_t(L&& l, R&& r):
@ -103,6 +105,7 @@ namespace sqlpp
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
{
using _value_type = ValueType;
using _parameters = std::tuple<Lhs, Rhs>;
template<typename L, typename R>
not_equal_t(L&& l, R&& r):
@ -142,10 +145,10 @@ namespace sqlpp
struct not_t: public ValueType::template operators<not_t<Lhs>>
{
using _value_type = ValueType;
using _parameters = std::tuple<Lhs>;
template<typename L>
not_t(L&& l):
_lhs(std::forward<L>(l))
not_t(Lhs l):
_lhs(l)
{}
not_t(const not_t&) = default;
@ -179,6 +182,7 @@ namespace sqlpp
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
{
using _value_type = typename O::_value_type;
using _parameters = std::tuple<Lhs, Rhs>;
binary_expression_t(Lhs&& l, Rhs&& r):
_lhs(std::move(l)),

View File

@ -46,6 +46,7 @@ namespace sqlpp
using _is_floating_point = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = double;
template<size_t index>
struct _result_entry_t

View File

@ -28,6 +28,8 @@
#define SQLPP_FUNCTIONS_H
#include <sstream>
#include <sqlpp11/parameter.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/column_types.h>
#include <sqlpp11/exists.h>

View File

@ -46,6 +46,7 @@ namespace sqlpp
using _is_integral = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = int64_t;
template<size_t index>
struct _result_entry_t

View File

@ -41,6 +41,7 @@ namespace sqlpp
{
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
using _parameters = std::tuple<ValueType, Pattern>;
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
{

View File

@ -37,6 +37,8 @@ namespace sqlpp
struct parameter_t
{
using _is_parameter = std::true_type;
using _value_type = ValueType;
using _is_expression_t = std::true_type;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
@ -45,8 +47,15 @@ namespace sqlpp
os << " ? ";
}
using _member_t = NameType::_name_t::_member_t<ValueType::_cpp_value_type>;
using _member_t = typename NameType::_name_t::template _member_t<typename ValueType::_cpp_value_type>;
};
template<typename NamedExpr>
auto parameter(NamedExpr&& namedExpr)
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type>
{
return {};
}
}
#endif

View File

@ -24,8 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_PARAMETER_H
#define SQLPP_PARAMETER_H
#ifndef SQLPP_PARAMETER_LIST_H
#define SQLPP_PARAMETER_LIST_H
#include <tuple>
@ -56,6 +56,35 @@ namespace sqlpp
std::tuple<const typename Parameter::type&...> _parameter_tuple;
};
namespace detail
{
template<typename Exp, typename Enable = void>
struct get_parameter_tuple
{
using type = std::tuple<>;
};
template<typename Exp>
struct get_parameter_tuple<Exp, typename std::enable_if<is_parameter_t<Exp>::value, void>::type>
{
using type = std::tuple<Exp>;
};
template<typename... Param>
struct get_parameter_tuple<std::tuple<Param...>, void>
{
// cat together parameter tuples
using type = decltype(std::tuple_cat(std::declval<typename get_parameter_tuple<Param>::type>()...));
};
template<typename Exp>
struct get_parameter_tuple<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameters, void>::value, void>::type>
{
using type = typename get_parameter_tuple<typename Exp::_parameters>::type;
};
}
}
#endif

View File

@ -46,6 +46,7 @@ namespace sqlpp
using _is_text = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = std::string;
template<size_t index>
struct _result_entry_t

View File

@ -116,6 +116,7 @@ namespace sqlpp
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
SQLPP_TYPE_TRAIT_GENERATOR(is_parameter);
SQLPP_CONNECTOR_TRAIT_GENERATOR(has_empty_list_insert);

View File

@ -8,4 +8,5 @@ build_and_run(RemoveTest)
build_and_run(UpdateTest)
build_and_run(SelectTest)
build_and_run(FunctionTest)
build_and_run(PreparedTest)

79
tests/PreparedTest.cpp Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2013, 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 "TabSample.h"
#include "MockDb.h"
#include "is_regular.h"
#include <sqlpp11/functions.h>
#include <iostream>
DbMock db = {};
int main()
{
TabSample t;
TabFoo f;
// empty parameter lists
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.alpha)>::type;
static_assert(std::is_same<T, std::tuple<>>::value, "type requirement");
}
// single parameter
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(parameter(t.alpha))>::type;
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
}
// single parameter
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(parameter(t.alpha))>::type;
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
}
// single parameter in expression
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.alpha == parameter(t.alpha))>::type;
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
}
// single parameter in larger expression
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.beta.like("%") and t.alpha == parameter(t.alpha) or t.gamma != false)>::type;
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
}
// three parameters in expression
{
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma))>::type;
static_assert(std::tuple_size<T>::value == 3, "type requirement");
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.beta)), decltype(parameter(t.alpha)),decltype(parameter(t.gamma))>>::value, "type requirement");
}
return 0;
}