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

interpret works for insert now

Also added explicit .default_values() method
This commit is contained in:
rbock 2014-01-13 23:05:48 +01:00
parent eb9f92543e
commit fa18ce5476
4 changed files with 100 additions and 83 deletions

View File

@ -59,11 +59,10 @@ namespace sqlpp
column_t& operator=(column_t&&) = default;
~column_t() = default;
template<typename Db>
void serialize_name(std::ostream& os, Db& db) const
{
os << _name_t::_get_name();
}
static constexpr const char* _get_name()
{
return _name_t::_get_name();
}
template<typename alias_provider>
expression_alias_t<column_t, typename std::decay<alias_provider>::type> as(alias_provider&&) const

View File

@ -39,6 +39,7 @@
namespace sqlpp
{
template<
typename Database = void,
typename Table = noop,
@ -58,15 +59,27 @@ namespace sqlpp
template<typename AssignmentT>
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
using use_default_values_t = insert_t<Database, Table, insert_default_values_t>;
using _parameter_tuple_t = std::tuple<Table, InsertList>;
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
auto default_values()
-> use_default_values_t
{
static_assert(std::is_same<InsertList, noop>::value, "cannot call default_values() after set() or default_values()");
// FIXME: Need to check if all required columns are set
return {
_table,
{},
};
}
template<typename... Assignment>
auto set(Assignment&&... assignment)
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>>
{
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() twice");
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
// FIXME: Need to check if all required columns are set
return {
_table,
@ -78,7 +91,7 @@ namespace sqlpp
auto dynamic_set(Assignment&&... assignment)
-> set_insert_list_t<insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>>
{
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() twice");
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
return {
_table,
insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
@ -95,29 +108,6 @@ namespace sqlpp
return *this;
}
template<typename Db>
const insert_t& serialize(std::ostream& os, Db& db) const
{
os << "INSERT INTO ";
_table.serialize(os, db);
if (is_noop<InsertList>::value)
{
detail::serialize_empty_insert_list(os, db);
}
else
{
_insert_list.serialize(os, db);
}
return *this;
}
template<typename Db>
insert_t& serialize(std::ostream& os, Db& db)
{
static_cast<const insert_t*>(this)->serialize(os, db);
return *this;
}
static constexpr size_t _get_static_no_of_parameters()
{
return _parameter_list_t::size::value;
@ -131,6 +121,7 @@ namespace sqlpp
template<typename Db>
std::size_t run(Db& db) const
{
// FIXME: check if set or default_values() has ben called
constexpr bool calledSet = not is_noop<InsertList>::value;
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
static_assert(calledSet or not requireSet, "calling set() required for given table");
@ -146,22 +137,27 @@ namespace sqlpp
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
static_assert(calledSet or not requireSet, "calling set() required for given table");
_set_parameter_index(0);
return {{}, db.prepare_insert(*this)};
}
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_table, index);
index = set_parameter_index(_insert_list, index);
return index;
}
Table _table;
InsertList _insert_list;
};
template<typename Context, typename Database, typename Table, typename InsertList>
struct interpreter_t<Context, insert_t<Database, Table, InsertList>>
{
using T = insert_t<Database, Table, InsertList>;
static Context& _(const T& t, Context& context)
{
context << "INSERT INTO ";
interpret(t._table, context);
interpret(t._insert_list, context);
return context;
}
};
template<typename Table>
insert_t<void, typename std::decay<Table>::type> insert_into(Table&& table)
{

View File

@ -34,30 +34,43 @@
namespace sqlpp
{
namespace detail
struct insert_default_values_t
{
template<typename Db>
void serialize_empty_insert_list(std::ostream& os, const Db& db)
{
using _is_insert_list = std::true_type;
using _is_dynamic = std::false_type;
};
if (connector_has_empty_list_insert_t<typename std::decay<Db>::type>::value)
os << " () VALUES()";
else
os << " DEFAULT VALUES";
template<typename Context>
struct interpreter_t<Context, insert_default_values_t>
{
using T = insert_default_values_t;
static Context& _(const T& t, Context& context)
{
context << " DEFAULT VALUES";
return context;
}
};
template<typename Column>
struct insert_column
struct insert_column_t
{
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
_column.serialize_name(os, db);
}
Column _column;
};
}
template<typename Context, typename Column>
struct interpreter_t<Context, insert_column_t<Column>>
{
using T = insert_column_t<Column>;
static Context& _(const T& t, Context& context)
{
context << t._column._get_name();
return context;
}
};
template<typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
struct insert_list_t
{
@ -95,43 +108,47 @@ namespace sqlpp
{
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
static_assert(not ProhibitPredicate<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
_dynamic_columns.emplace_back(detail::insert_column<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
if (sizeof...(Assignments) + _dynamic_columns.size() == 0)
{
detail::serialize_empty_insert_list(os, db);
}
else
{
constexpr bool first = sizeof...(Assignments) == 0;
os << " (";
detail::serialize_tuple(os, db, _columns, ',');
_dynamic_columns.serialize(os, db, first);
os << ") VALUES (";
detail::serialize_tuple(os, db, _values, ',');
_dynamic_values.serialize(os, db, first);
os << ")";
}
}
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_values, index);
return index;
}
std::tuple<detail::insert_column<typename Assignments::column_type>...> _columns;
std::tuple<insert_column_t<typename Assignments::column_type>...> _columns;
_parameter_tuple_t _values;
typename detail::serializable_list<Database> _dynamic_columns;
typename detail::serializable_list<Database> _dynamic_values;
};
template<typename Context, typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
struct interpreter_t<Context, insert_list_t<Database, ProhibitPredicate, Assignments...>>
{
using T = insert_list_t<Database, ProhibitPredicate, Assignments...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
{
interpret(insert_default_values_t(), context);
}
else
{
context << " (";
interpret_tuple(t._columns, ",", context);
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
context << ',';
interpret_serializable_list(t._dynamic_columns, ',', context);
context << ") VALUES(";
interpret_tuple(t._values, ",", context);
if (sizeof...(Assignments) and not t._dynamic_values.empty())
context << ',';
interpret_serializable_list(t._dynamic_values, ',', context);
context << ")";
}
return context;
}
};
}
#endif

View File

@ -26,6 +26,7 @@
#include "TabSample.h"
#include "MockDb.h"
#include <sqlpp11/select.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/functions.h>
#include <iostream>
@ -54,5 +55,9 @@ int main()
interpret(parameter(t.alpha), printer).flush();
interpret(t.alpha == parameter(t.alpha), printer).flush();
interpret(insert_into(t), printer).flush();
interpret(insert_into(t).default_values(), printer).flush();
interpret(insert_into(t).set(t.gamma = true), printer).flush();
return 0;
}