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:
parent
eb9f92543e
commit
fa18ce5476
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user