mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Can now prepare a select (tested with mysql)
This commit is contained in:
parent
b4baf38fab
commit
b031bda5fc
@ -41,13 +41,9 @@ namespace sqlpp
|
|||||||
template<typename T>\
|
template<typename T>\
|
||||||
struct _member_t\
|
struct _member_t\
|
||||||
{\
|
{\
|
||||||
template<typename... TT>\
|
|
||||||
_member_t(TT&&... t): name(std::forward<TT>(t)...) {}\
|
|
||||||
\
|
|
||||||
template<typename TT>\
|
|
||||||
_member_t& operator=(TT&& t) { name = std::forward<TT>(t); return *this; }\
|
|
||||||
\
|
|
||||||
T name;\
|
T name;\
|
||||||
|
T& operator()() { return name; }\
|
||||||
|
const T& operator()() const { return name; }\
|
||||||
};\
|
};\
|
||||||
};\
|
};\
|
||||||
};\
|
};\
|
||||||
|
@ -42,6 +42,12 @@ namespace sqlpp
|
|||||||
using value_type = Rhs;
|
using value_type = Rhs;
|
||||||
using _parameter_t = std::tuple<Lhs, Rhs>;
|
using _parameter_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
@ -67,6 +73,12 @@ namespace sqlpp
|
|||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
using _parameter_t = std::tuple<Lhs, Rhs>;
|
using _parameter_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
equal_t(L&& l, R&& r):
|
equal_t(L&& l, R&& r):
|
||||||
_lhs(std::forward<L>(l)),
|
_lhs(std::forward<L>(l)),
|
||||||
@ -107,6 +119,12 @@ namespace sqlpp
|
|||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
using _parameter_t = std::tuple<Lhs, Rhs>;
|
using _parameter_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
not_equal_t(L&& l, R&& r):
|
not_equal_t(L&& l, R&& r):
|
||||||
_lhs(std::forward<L>(l)),
|
_lhs(std::forward<L>(l)),
|
||||||
@ -147,6 +165,11 @@ namespace sqlpp
|
|||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
using _parameter_t = std::tuple<Lhs>;
|
using _parameter_t = std::tuple<Lhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
return set_parameter_index(_lhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
not_t(Lhs l):
|
not_t(Lhs l):
|
||||||
_lhs(l)
|
_lhs(l)
|
||||||
{}
|
{}
|
||||||
@ -184,6 +207,12 @@ namespace sqlpp
|
|||||||
using _value_type = typename O::_value_type;
|
using _value_type = typename O::_value_type;
|
||||||
using _parameter_t = std::tuple<Lhs, Rhs>;
|
using _parameter_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
binary_expression_t(Lhs&& l, Rhs&& r):
|
binary_expression_t(Lhs&& l, Rhs&& r):
|
||||||
_lhs(std::move(l)),
|
_lhs(std::move(l)),
|
||||||
_rhs(std::move(r))
|
_rhs(std::move(r))
|
||||||
|
@ -51,7 +51,7 @@ namespace sqlpp
|
|||||||
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
||||||
|
|
||||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment
|
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||||
|
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
|
@ -65,6 +65,11 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
return set_parameter_index(_expressions, index);
|
||||||
|
}
|
||||||
|
|
||||||
using _parameter_t = std::tuple<Expr...>;
|
using _parameter_t = std::tuple<Expr...>;
|
||||||
_parameter_t _expressions;
|
_parameter_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
|
@ -43,7 +43,7 @@ namespace sqlpp
|
|||||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||||
using _parameter_t = std::tuple<ValueType, Pattern>;
|
using _parameter_t = std::tuple<ValueType, Pattern>;
|
||||||
|
|
||||||
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
|
struct _value_type: public ValueType::_base_value_type // we require fully defined boolean here
|
||||||
{
|
{
|
||||||
using _is_named_expression = std::true_type;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
|
@ -40,15 +40,25 @@ namespace sqlpp
|
|||||||
using _parameter_type = typename ValueType::template _parameter_t<TrivialValueIsNull>;
|
using _parameter_type = typename ValueType::template _parameter_t<TrivialValueIsNull>;
|
||||||
using _is_parameter = std::true_type;
|
using _is_parameter = std::true_type;
|
||||||
using _is_expression_t = std::true_type;
|
using _is_expression_t = std::true_type;
|
||||||
|
using _member_t = typename NameType::_name_t::template _member_t<_parameter_type>;
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
static_assert(Db::_supports_parameter, "parameter not supported by current database");
|
static_assert(Db::_supports_prepared, "prepared statements not supported by current database");
|
||||||
os << " ? "; // FIXME: Need to support positional placeholders and also type indicators for postgres for instance
|
static_assert(Db::_use_questionmark_parameter or Db::_use_positional_dollar_parameter, "no known way to serialize parameter placeholders for current database");
|
||||||
|
if (Db::_use_questionmark_parameter)
|
||||||
|
os << '?';
|
||||||
|
else if (Db::_use_positional_dollar_parameter)
|
||||||
|
os << '$' << index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
using _member_t = typename NameType::_name_t::template _member_t<_parameter_type>;
|
constexpr bool _is_trivial() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t index;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename NamedExpr, bool TrivialValueIsNull = trivial_value_is_null_t<typename std::decay<NamedExpr>::type>::value>
|
template<typename NamedExpr, bool TrivialValueIsNull = trivial_value_is_null_t<typename std::decay<NamedExpr>::type>::value>
|
||||||
|
@ -41,42 +41,7 @@ namespace sqlpp
|
|||||||
template<typename... Parameter>
|
template<typename... Parameter>
|
||||||
struct parameter_list_t<std::tuple<Parameter...>>: public Parameter::_member_t...
|
struct parameter_list_t<std::tuple<Parameter...>>: public Parameter::_member_t...
|
||||||
{
|
{
|
||||||
parameter_list_t():
|
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
||||||
Parameter::_member_t()...,
|
|
||||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
parameter_list_t(const parameter_list_t& rhs)
|
|
||||||
noexcept(std::is_nothrow_copy_constructible<std::tuple<typename Parameter::_member_t...>>::value):
|
|
||||||
Parameter::_member_t(static_cast<const typename Parameter::_member_t&>(rhs))...,
|
|
||||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
parameter_list_t(parameter_list_t&& rhs)
|
|
||||||
noexcept(std::is_nothrow_move_constructible<std::tuple<typename Parameter::_member_t...>>::value):
|
|
||||||
Parameter::_member_t(std::move(static_cast<typename Parameter::_member_t&>(rhs)))...,
|
|
||||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
parameter_list_t& operator=(const parameter_list_t& rhs)
|
|
||||||
noexcept(std::is_nothrow_copy_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
|
|
||||||
{
|
|
||||||
_parameter_tuple = rhs._parameter_tuple;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter_list_t& operator=(parameter_list_t&& rhs)
|
|
||||||
noexcept(std::is_nothrow_move_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
|
|
||||||
{
|
|
||||||
_parameter_tuple = std::move(rhs._parameter_tuple);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~parameter_list_t() = default;
|
|
||||||
|
|
||||||
using parameter_tuple_t = std::tuple<typename Parameter::_parameter_type&...>;
|
|
||||||
using size = std::tuple_size<parameter_tuple_t>;
|
|
||||||
parameter_tuple_t _parameter_tuple;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
|
@ -38,7 +38,7 @@ namespace sqlpp
|
|||||||
using _result_row_t = typename Select::_result_row_t;
|
using _result_row_t = typename Select::_result_row_t;
|
||||||
using _parameter_list_t = typename Select::_parameter_list_t;
|
using _parameter_list_t = typename Select::_parameter_list_t;
|
||||||
using _dynamic_names_t = typename Select::_dynamic_names_t;
|
using _dynamic_names_t = typename Select::_dynamic_names_t;
|
||||||
using _handle_t = typename Db::_prepared_handle_t;
|
using _handle_t = typename Db::template _prepared_query_t<Select>;
|
||||||
|
|
||||||
auto run(Db& db) const
|
auto run(Db& db) const
|
||||||
-> result_t<decltype(db.run_prepared_select(this))>
|
-> result_t<decltype(db.run_prepared_select(this))>
|
||||||
|
@ -587,20 +587,16 @@ namespace sqlpp
|
|||||||
return {db.select(*this)};
|
return {db.select(*this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
prepared_select_t<Db, select_t> run(Db& db) const
|
prepared_select_t<typename std::decay<Db>::type, select_t> prepare(Db& db) const
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
// FIXME: Check for missing aliases (if references are used)
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||||
|
|
||||||
std::ostringstream oss;
|
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||||
serialize(oss, db);
|
|
||||||
return {db.prepare_select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names};
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
ExpressionList _expression_list;
|
ExpressionList _expression_list;
|
||||||
|
@ -64,6 +64,11 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
return set_parameter_index(_expressions, index);
|
||||||
|
}
|
||||||
|
|
||||||
using _parameter_t = std::tuple<Expr...>;
|
using _parameter_t = std::tuple<Expr...>;
|
||||||
_parameter_t _expressions;
|
_parameter_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
|
@ -83,10 +83,6 @@ int main()
|
|||||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t<true>, decltype(npl.alpha)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t<true>, decltype(npl.alpha)>::value, "type requirement");
|
||||||
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t<true>, decltype(npl.beta)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t<true>, decltype(npl.beta)>::value, "type requirement");
|
||||||
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t<false>, decltype(npl.gamma)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t<false>, decltype(npl.gamma)>::value, "type requirement");
|
||||||
|
|
||||||
static_assert(std::is_same<decltype(std::get<0>(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement");
|
|
||||||
static_assert(std::is_same<decltype(std::get<1>(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement");
|
|
||||||
static_assert(std::is_same<decltype(std::get<2>(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wonderful, now take a look at the parameter list of a select
|
// Wonderful, now take a look at the parameter list of a select
|
||||||
@ -99,10 +95,6 @@ int main()
|
|||||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t<true>, decltype(npl.alpha)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t<true>, decltype(npl.alpha)>::value, "type requirement");
|
||||||
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t<true>, decltype(npl.beta)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t<true>, decltype(npl.beta)>::value, "type requirement");
|
||||||
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t<false>, decltype(npl.gamma)>::value, "type requirement");
|
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t<false>, decltype(npl.gamma)>::value, "type requirement");
|
||||||
|
|
||||||
static_assert(std::is_same<decltype(std::get<0>(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement");
|
|
||||||
static_assert(std::is_same<decltype(std::get<1>(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement");
|
|
||||||
static_assert(std::is_same<decltype(std::get<2>(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement");
|
|
||||||
npl.alpha = 7;
|
npl.alpha = 7;
|
||||||
auto x = npl;
|
auto x = npl;
|
||||||
x = npl;
|
x = npl;
|
||||||
|
@ -87,6 +87,8 @@ struct TabFoo: sqlpp::table_base_t<
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T tabFoo;
|
T tabFoo;
|
||||||
|
T& operator()() { return tabFoo; }
|
||||||
|
const T& operator()() const { return tabFoo; }
|
||||||
};
|
};
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize_impl(std::ostream& os, Db& db) const
|
void serialize_impl(std::ostream& os, Db& db) const
|
||||||
@ -179,6 +181,8 @@ struct TabSample: sqlpp::table_base_t<
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T tabSample;
|
T tabSample;
|
||||||
|
T& operator()() { return tabSample; }
|
||||||
|
const T& operator()() const { return tabSample; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
|
Loading…
Reference in New Issue
Block a user