0
0
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:
Roland Bock 2013-12-28 22:52:54 +01:00
parent b4baf38fab
commit b031bda5fc
12 changed files with 64 additions and 62 deletions

View File

@ -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; }\
};\ };\
};\ };\
};\ };\

View File

@ -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))

View File

@ -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>

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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>

View File

@ -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

View File

@ -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))>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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>