mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'feature/crtp-to-composition-for-statements' into develop
This commit is contained in:
commit
3e9eab8773
@ -27,8 +27,8 @@
|
||||
#ifndef SQLPP_ANY_H
|
||||
#define SQLPP_ANY_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -57,6 +57,8 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
using _table_set = ::sqlpp::detail::type_set<>; // FIXME: Can selects leak tables here?
|
||||
|
||||
any_t(Select select):
|
||||
_select(select)
|
||||
{}
|
||||
|
@ -84,6 +84,14 @@ namespace sqlpp
|
||||
return { *this, {t} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator =(T t) const
|
||||
-> typename std::enable_if<not(_value_type::template _constraint<typename vendor::wrap_operand<T>::type>::value and not std::is_same<column_t, T>::value),
|
||||
vendor::assignment_t<column_t, typename vendor::wrap_operand<T>::type>>::type
|
||||
{
|
||||
static_assert(sqlpp::vendor::wrong_t<T>::value, "invalid assignment operand");
|
||||
}
|
||||
|
||||
auto operator =(sqlpp::null_t) const
|
||||
->vendor::assignment_t<column_t, sqlpp::null_t>
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ namespace sqlpp
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = no_value_t;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto value(T t) -> typename operand_t<T, is_value_t>::type
|
||||
{
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
static_assert(not is_value_t<T>::value, "value() is to be called with non-sql-type like int, or string");
|
||||
return { t };
|
||||
}
|
||||
@ -55,6 +56,7 @@ namespace sqlpp
|
||||
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
verbatim_t(std::string verbatim): _verbatim(verbatim) {}
|
||||
verbatim_t(const verbatim_t&) = default;
|
||||
@ -100,6 +102,7 @@ namespace sqlpp
|
||||
struct value_list_t // to be used in .in() method
|
||||
{
|
||||
using _container_t = Container;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;// FIXME: Could it be something else?
|
||||
using _value_type = typename operand_t<typename _container_t::value_type, is_value_t>::type::_value_type;
|
||||
|
||||
value_list_t(_container_t container):
|
||||
|
@ -34,49 +34,49 @@
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/single_table.h>
|
||||
#include <sqlpp11/vendor/insert_value_list.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/vendor/policy.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<
|
||||
typename Table,
|
||||
typename InsertValueList
|
||||
// INSERT
|
||||
template<typename Database = void,
|
||||
typename Table = vendor::no_single_table_t,
|
||||
typename InsertValueList = vendor::no_insert_value_list_t
|
||||
>
|
||||
struct check_insert_t
|
||||
struct insert_t
|
||||
{
|
||||
static_assert(Table::_table_set::template is_superset_of<typename InsertValueList::_table_set>::value, "inserted columns do not match the table in insert_into");
|
||||
//static_assert(not (vendor::is_noop<InsertList>::value and vendor::is_noop<ColumnList>::value) , "calling set() or default_values()");
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database, typename... Policies>
|
||||
struct insert_t: public vendor::policy_t<Policies>..., public vendor::crtp_wrapper_t<insert_t<Database, Policies...>, Policies>...
|
||||
{
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policy_update_t = insert_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
static_assert(Table::_table_set::template is_superset_of<typename InsertValueList::_table_set>::value, "columns do not match the table they are to be inserted into");
|
||||
|
||||
using _database_t = Database;
|
||||
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _table_set = typename Table::_table_set;
|
||||
|
||||
template<typename Needle, typename Replacement, typename... Policies>
|
||||
struct _policies_update_impl
|
||||
{
|
||||
using type = insert_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policies_update_t = typename _policies_update_impl<Needle, Replacement, Table, InsertValueList>::type;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Table, InsertValueList>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
||||
|
||||
// Constructors
|
||||
insert_t()
|
||||
{}
|
||||
|
||||
static_assert(detail::check_insert_t<Policies...>::value, "invalid insert_into");
|
||||
|
||||
template<typename Whatever>
|
||||
insert_t(insert_t i, Whatever whatever):
|
||||
vendor::policy_t<Policies>(i, whatever)...
|
||||
template<typename X>
|
||||
insert_t(X x, Table table):
|
||||
_table(table),
|
||||
_insert_value_list(x._insert_value_list)
|
||||
{}
|
||||
|
||||
template<typename Insert, typename Whatever>
|
||||
insert_t(Insert i, Whatever whatever):
|
||||
vendor::policy_t<Policies>(i, whatever)...
|
||||
template<typename X>
|
||||
insert_t(X x, InsertValueList insert_value_list):
|
||||
_table(x._table),
|
||||
_insert_value_list(insert_value_list)
|
||||
{}
|
||||
|
||||
insert_t(const insert_t&) = default;
|
||||
@ -85,6 +85,56 @@ namespace sqlpp
|
||||
insert_t& operator=(insert_t&&) = default;
|
||||
~insert_t() = default;
|
||||
|
||||
// type update functions
|
||||
auto default_values()
|
||||
-> _policies_update_t<vendor::no_insert_value_list_t, vendor::insert_default_values_t>
|
||||
{
|
||||
static_assert(is_noop_t<InsertValueList>::value, "cannot combine default_values() with other methods");
|
||||
return { *this, vendor::insert_default_values_t{} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _policies_update_t<vendor::no_insert_value_list_t, vendor::column_list_t<Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<InsertValueList>::value, "cannot combine columns() with other methods");
|
||||
return { *this, vendor::column_list_t<Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _policies_update_t<vendor::no_insert_value_list_t, vendor::insert_list_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<InsertValueList>::value, "cannot combine set() with other methods");
|
||||
return { *this, vendor::insert_list_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _policies_update_t<vendor::no_insert_value_list_t, vendor::insert_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<InsertValueList>::value, "cannot combine dynamic_set() with other methods");
|
||||
static_assert(_is_dynamic::value, "dynamic_set must not be called in a static statement");
|
||||
return { *this, vendor::insert_list_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
// value adding methods
|
||||
template<typename... Args>
|
||||
void add_set(Args... args)
|
||||
{
|
||||
static_assert(is_insert_list_t<InsertValueList>::value, "cannot call add_set() before dynamic_set()");
|
||||
static_assert(is_dynamic_t<InsertValueList>::value, "cannot call add_set() before dynamic_set()");
|
||||
return _insert_value_list.add_set(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_values(Args... args)
|
||||
{
|
||||
static_assert(is_column_list_t<InsertValueList>::value, "cannot call add_values() before columns()");
|
||||
return _insert_value_list.add_values(args...);
|
||||
}
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
@ -99,7 +149,6 @@ namespace sqlpp
|
||||
std::size_t _run(Db& db) const
|
||||
{
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
static_assert(detail::check_insert_t<Policies...>::value, "Cannot run this insert expression");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
@ -107,9 +156,11 @@ namespace sqlpp
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
static_assert(detail::check_insert_t<Policies...>::value, "Cannot prepare this insert expression");
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
|
||||
InsertValueList _insert_value_list;
|
||||
Table _table;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
@ -122,28 +173,25 @@ namespace sqlpp
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "INSERT INTO ";
|
||||
interpret(t._single_table(), context);
|
||||
interpret(t._insert_value_list(), context);
|
||||
interpret(t._table, context);
|
||||
interpret(t._insert_value_list, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_insert_t = insert_t<Database, vendor::no_single_table_t, vendor::no_insert_value_list_t>;
|
||||
|
||||
template<typename Table>
|
||||
constexpr auto insert_into(Table table)
|
||||
-> insert_t<void, vendor::single_table_t<void, Table>, vendor::no_insert_value_list_t>
|
||||
-> insert_t<void, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_insert_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { insert_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
template<typename Database, typename Table>
|
||||
constexpr auto dynamic_insert_into(const Database&, Table table)
|
||||
-> insert_t<Database, vendor::single_table_t<void, Table>, vendor::no_insert_value_list_t>
|
||||
-> insert_t<Database, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_insert_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { insert_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ namespace sqlpp
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = no_value_t;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
};
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_PARAMETER_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -38,6 +39,7 @@ namespace sqlpp
|
||||
using _is_parameter = std::true_type;
|
||||
using _is_expression_t = std::true_type;
|
||||
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
||||
using _table_set = sqlpp::detail::type_set<>;
|
||||
|
||||
parameter_t()
|
||||
{}
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include <sqlpp11/vendor/single_table.h>
|
||||
#include <sqlpp11/vendor/using.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/vendor/policy.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -50,27 +48,52 @@ namespace sqlpp
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database, typename... Policies>
|
||||
struct remove_t: public vendor::policy_t<Policies>..., public vendor::crtp_wrapper_t<remove_t<Database, Policies...>, Policies>...
|
||||
// REMOVE
|
||||
template<typename Database,
|
||||
typename Table = vendor::no_single_table_t,
|
||||
typename Using = vendor::no_using_t,
|
||||
typename Where = vendor::no_where_t
|
||||
>
|
||||
struct remove_t
|
||||
{
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policy_update_t = remove_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
|
||||
using _database_t = Database;
|
||||
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
template<typename Needle, typename Replacement, typename... Policies>
|
||||
struct _policies_update_impl
|
||||
{
|
||||
using type = remove_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policies_update_t = typename _policies_update_impl<Needle, Replacement, Table, Using, Where>::type;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Table, Using, Where>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<remove_t>::type;
|
||||
|
||||
// Constructors
|
||||
remove_t()
|
||||
{}
|
||||
|
||||
template<typename Whatever>
|
||||
remove_t(remove_t r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
template<typename X>
|
||||
remove_t(X x, Table table):
|
||||
_table(table),
|
||||
_using(x._using),
|
||||
_where(x._where)
|
||||
{}
|
||||
|
||||
template<typename Remove, typename Whatever>
|
||||
remove_t(Remove r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
template<typename X>
|
||||
remove_t(X x, Using using_):
|
||||
_table(x._table),
|
||||
_using(using_),
|
||||
_where(x._where)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
remove_t(X x, Where where):
|
||||
_table(x._table),
|
||||
_using(x._using),
|
||||
_where(where)
|
||||
{}
|
||||
|
||||
remove_t(const remove_t&) = default;
|
||||
@ -79,6 +102,59 @@ namespace sqlpp
|
||||
remove_t& operator=(remove_t&&) = default;
|
||||
~remove_t() = default;
|
||||
|
||||
// type update functions
|
||||
template<typename... Args>
|
||||
auto using_(Args... args)
|
||||
-> _policies_update_t<vendor::no_using_t, vendor::using_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Using>::value, "cannot call using_()/dynamic_using() twice");
|
||||
return { *this, vendor::using_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_using(Args... args)
|
||||
-> _policies_update_t<vendor::no_using_t, vendor::using_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Using>::value, "cannot call using_()/dynamic_using() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
||||
return { *this, vendor::using_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
return { *this, vendor::where_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *this, vendor::where_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
// value adding methods
|
||||
template<typename... Args>
|
||||
void add_using(Args... args)
|
||||
{
|
||||
static_assert(is_using_t<Using>::value, "cannot call add_using() before dynamic_using()");
|
||||
static_assert(is_dynamic_t<Using>::value, "cannot call add_using() before dynamic_using()");
|
||||
return _using.add_using(args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_where(Args... args)
|
||||
{
|
||||
static_assert(is_where_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
static_assert(is_dynamic_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
return _where.add_where(*this, args...);
|
||||
}
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
@ -93,7 +169,7 @@ namespace sqlpp
|
||||
std::size_t _run(Db& db) const
|
||||
{
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
|
||||
static_assert(detail::check_remove_t<Policies...>::value, "Cannot run this remove expression");
|
||||
//static_assert(detail::check_remove_t<Policies...>::value, "Cannot run this remove expression");
|
||||
return db.remove(*this);
|
||||
}
|
||||
|
||||
@ -101,9 +177,13 @@ namespace sqlpp
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_remove_t<Database, remove_t>
|
||||
{
|
||||
static_assert(detail::check_remove_t<Policies...>::value, "Cannot run this remove expression");
|
||||
//static_assert(detail::check_remove_t<Policies...>::value, "Cannot run this remove expression");
|
||||
return {{}, db.prepare_remove(*this)};
|
||||
}
|
||||
|
||||
Table _table;
|
||||
Using _using;
|
||||
Where _where;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
@ -116,29 +196,26 @@ namespace sqlpp
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "DELETE FROM";
|
||||
interpret(t._single_table(), context);
|
||||
interpret(t._using(), context);
|
||||
interpret(t._where(), context);
|
||||
interpret(t._table, context);
|
||||
interpret(t._using, context);
|
||||
interpret(t._where, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_remove_t = remove_t<Database, vendor::no_single_table_t, vendor::no_using_t, vendor::no_where_t>;
|
||||
|
||||
template<typename Table>
|
||||
constexpr auto remove_from(Table table)
|
||||
-> remove_t<void, vendor::single_table_t<void, Table>, vendor::no_using_t, vendor::no_where_t>
|
||||
-> remove_t<void, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_remove_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { remove_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
template<typename Database, typename Table>
|
||||
constexpr auto dynamic_remove_from(const Database&, Table table)
|
||||
-> remove_t<Database, vendor::single_table_t<void, Table>, vendor::no_using_t, vendor::no_where_t>
|
||||
-> remove_t<Database, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_remove_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { remove_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
#include <sqlpp11/vendor/wrong.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/vendor/policy.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
#include <sqlpp11/detail/copy_tuple_args.h>
|
||||
@ -55,74 +53,180 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
template<
|
||||
typename FlagList,
|
||||
typename ColumnList,
|
||||
typename From,
|
||||
typename Where,
|
||||
typename GroupBy,
|
||||
typename Having,
|
||||
typename OrderBy,
|
||||
typename Limit,
|
||||
typename Offset
|
||||
typename From
|
||||
>
|
||||
struct select_helper_t
|
||||
{
|
||||
using _column_list_t = ColumnList;
|
||||
using _from_t = ColumnList;
|
||||
|
||||
static_assert(is_noop_t<ColumnList>::value or sqlpp::is_select_column_list_t<ColumnList>::value, "Yikes");
|
||||
static_assert(is_noop_t<From>::value or sqlpp::is_from_t<From>::value, "Yikes");
|
||||
using _value_type = typename std::conditional<
|
||||
sqlpp::is_from_t<From>::value,
|
||||
typename ColumnList::_value_type,
|
||||
no_value_t // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
|
||||
>::type;
|
||||
template<typename Database>
|
||||
struct can_run_t
|
||||
{
|
||||
//static_assert(is_where_t<Where>::value, "cannot select remove without having a where condition, use .where(true) to remove all rows");
|
||||
//static_assert(not vendor::is_noop<ColumnList>::value, "cannot run select without having selected anything");
|
||||
//static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
//static_assert(is_where_t<Where>::value, "cannot run select without having a where condition, use .where(true) to select all rows");
|
||||
// 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.
|
||||
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// SELECT
|
||||
template<typename Database, typename... Policies>
|
||||
struct select_t: public vendor::policy_t<Policies>..., public vendor::crtp_wrapper_t<select_t<Database, Policies...>, Policies>...,
|
||||
public detail::select_helper_t<Policies...>::_value_type::template operators<select_t<Database, Policies...>>
|
||||
template<typename Database = void,
|
||||
typename FlagList = vendor::no_select_flag_list_t,
|
||||
typename ColumnList = vendor::no_select_column_list_t,
|
||||
typename From = vendor::no_from_t,
|
||||
typename Where = vendor::no_where_t,
|
||||
typename GroupBy = vendor::no_group_by_t,
|
||||
typename Having = vendor::no_having_t,
|
||||
typename OrderBy = vendor::no_order_by_t,
|
||||
typename Limit = vendor::no_limit_t,
|
||||
typename Offset = vendor::no_offset_t
|
||||
>
|
||||
struct select_t: public detail::select_helper_t<ColumnList, From>::_value_type::template operators<select_t<Database, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>>
|
||||
{
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policy_update_t = select_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
|
||||
using _database_t = Database;
|
||||
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
using _column_list_t = typename detail::select_helper_t<Policies...>::_column_list_t;
|
||||
template<typename Needle, typename Replacement, typename... Policies>
|
||||
struct _policies_update_impl
|
||||
{
|
||||
using type = select_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policies_update_t = typename _policies_update_impl<Needle, Replacement, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>::type;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
using _column_list_t = ColumnList;
|
||||
using _result_row_t = typename _column_list_t::_result_row_t;
|
||||
using _dynamic_names_t = typename _column_list_t::_dynamic_names_t;
|
||||
|
||||
using _is_select = std::true_type;
|
||||
using _requires_braces = std::true_type;
|
||||
|
||||
using _value_type = typename detail::select_helper_t<Policies...>::_value_type;
|
||||
using _value_type = typename detail::select_helper_t<ColumnList, From>::_value_type;
|
||||
using _name_t = typename _column_list_t::_name_t;
|
||||
|
||||
// Constructors
|
||||
select_t()
|
||||
{}
|
||||
|
||||
template<typename Whatever>
|
||||
select_t(select_t r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
template<typename X>
|
||||
select_t(X x, FlagList flag_list):
|
||||
_flag_list(flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename Remove, typename Whatever>
|
||||
select_t(Remove r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
template<typename X>
|
||||
select_t(X x, ColumnList column_list):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, From from):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, Where where):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, GroupBy group_by):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, Having having):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, OrderBy order_by):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(order_by),
|
||||
_limit(x._limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, Limit limit):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(limit),
|
||||
_offset(x._offset)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
select_t(X x, Offset offset):
|
||||
_flag_list(x._flag_list),
|
||||
_column_list(x._column_list),
|
||||
_from(x._from),
|
||||
_where(x._where),
|
||||
_group_by(x._group_by),
|
||||
_having(x._having),
|
||||
_order_by(x._order_by),
|
||||
_limit(x._limit),
|
||||
_offset(offset)
|
||||
{}
|
||||
|
||||
select_t(const select_t& r) = default;
|
||||
@ -131,7 +235,230 @@ namespace sqlpp
|
||||
select_t& operator=(select_t&& r) = default;
|
||||
~select_t() = default;
|
||||
|
||||
// Indicators
|
||||
// type update functions
|
||||
template<typename... Args>
|
||||
auto flags(Args... args)
|
||||
-> _policies_update_t<vendor::no_select_flag_list_t, vendor::select_flag_list_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<FlagList>::value, "flags()/dynamic_flags() must not be called twice");
|
||||
return { *this, vendor::select_flag_list_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_flags(Args... args)
|
||||
-> _policies_update_t<vendor::no_select_flag_list_t, vendor::select_flag_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<FlagList>::value, "flags()/dynamic_flags() must not be called twice");
|
||||
static_assert(_is_dynamic::value, "dynamic_flags must not be called in a static statement");
|
||||
return { *this, vendor::select_flag_list_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _policies_update_t<vendor::no_select_column_list_t, vendor::select_column_list_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<ColumnList>::value, "columns()/dynamic_columns() must not be called twice");
|
||||
return { *this, vendor::select_column_list_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_columns(Args... args)
|
||||
-> _policies_update_t<vendor::no_select_column_list_t, vendor::select_column_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<ColumnList>::value, "columns()/dynamic_columns() must not be called twice");
|
||||
static_assert(_is_dynamic::value, "dynamic_columns must not be called in a static statement");
|
||||
return { *this, vendor::select_column_list_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _policies_update_t<vendor::no_from_t, vendor::from_t<void, Args...>>
|
||||
{
|
||||
return { *this, vendor::from_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_from(Args... args)
|
||||
-> _policies_update_t<vendor::no_from_t, vendor::from_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { *this, vendor::from_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
return { *this, vendor::where_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *this, vendor::where_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto group_by(Args... args)
|
||||
-> _policies_update_t<vendor::no_group_by_t, vendor::group_by_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<GroupBy>::value, "cannot call group_by()/dynamic_group_by() twice");
|
||||
return { *this, vendor::group_by_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_group_by(Args... args)
|
||||
-> _policies_update_t<vendor::no_group_by_t, vendor::group_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<GroupBy>::value, "cannot call group_by()/dynamic_group_by() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { *this, vendor::group_by_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto having(Args... args)
|
||||
-> _policies_update_t<vendor::no_having_t, vendor::having_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Having>::value, "cannot call having()/dynamic_having() twice");
|
||||
return { *this, vendor::having_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_having(Args... args)
|
||||
-> _policies_update_t<vendor::no_having_t, vendor::having_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Having>::value, "cannot call having()/dynamic_having() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { *this, vendor::having_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto order_by(Args... args)
|
||||
-> _policies_update_t<vendor::no_order_by_t, vendor::order_by_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<OrderBy>::value, "cannot call order_by()/dynamic_order_by() twice");
|
||||
return { *this, vendor::order_by_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_order_by(Args... args)
|
||||
-> _policies_update_t<vendor::no_order_by_t, vendor::order_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<OrderBy>::value, "cannot call order_by()/dynamic_order_by() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { *this, vendor::order_by_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
auto limit(Arg arg)
|
||||
-> _policies_update_t<vendor::no_limit_t, vendor::limit_t<typename vendor::wrap_operand<Arg>::type>>
|
||||
{
|
||||
static_assert(is_noop_t<Limit>::value, "cannot call limit()/dynamic_limit() twice");
|
||||
return { *this, vendor::limit_t<typename vendor::wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_limit()
|
||||
-> _policies_update_t<vendor::no_limit_t, vendor::dynamic_limit_t<_database_t>>
|
||||
{
|
||||
static_assert(is_noop_t<Limit>::value, "cannot call limit()/dynamic_limit() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { *this, vendor::dynamic_limit_t<_database_t>{} };
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
auto offset(Arg arg)
|
||||
-> _policies_update_t<vendor::no_offset_t, vendor::offset_t<typename vendor::wrap_operand<Arg>::type>>
|
||||
{
|
||||
static_assert(is_noop_t<Offset>::value, "cannot call offset()/dynamic_offset() twice");
|
||||
return { *this, vendor::offset_t<typename vendor::wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_offset()
|
||||
-> _policies_update_t<vendor::no_offset_t, vendor::dynamic_offset_t<_database_t>>
|
||||
{
|
||||
static_assert(is_noop_t<Offset>::value, "cannot call offset()/dynamic_offset() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { *this, vendor::dynamic_offset_t<_database_t>{} };
|
||||
}
|
||||
|
||||
// value adding methods
|
||||
template<typename... Args>
|
||||
void add_flag(Args... args)
|
||||
{
|
||||
static_assert(is_select_flag_list_t<FlagList>::value, "cannot call add_flag() before dynamic_flags()");
|
||||
static_assert(is_dynamic_t<FlagList>::value, "cannot call add_flag() before dynamic_flags()");
|
||||
return _flag_list.add_flag(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_column(Args... args)
|
||||
{
|
||||
static_assert(is_select_column_list_t<ColumnList>::value, "cannot call add_column() before dynamic_columns()");
|
||||
static_assert(is_dynamic_t<ColumnList>::value, "cannot call add_column() before dynamic_columns()");
|
||||
return _column_list.add_column(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_from(Args... args)
|
||||
{
|
||||
static_assert(is_from_t<From>::value, "cannot call add_from() before dynamic_from()");
|
||||
static_assert(is_dynamic_t<From>::value, "cannot call add_using() before dynamic_from()");
|
||||
return _from.add_from(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_where(Args... args)
|
||||
{
|
||||
static_assert(is_where_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
static_assert(is_dynamic_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
return _where.add_where(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_group_by(Args... args)
|
||||
{
|
||||
static_assert(is_group_by_t<GroupBy>::value, "cannot call add_group_by() before dynamic_group_by()");
|
||||
static_assert(is_dynamic_t<GroupBy>::value, "cannot call add_group_by() before dynamic_group_by()");
|
||||
return _group_by.add_group_by(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_having(Args... args)
|
||||
{
|
||||
static_assert(is_having_t<Having>::value, "cannot call add_having() before dynamic_having()");
|
||||
static_assert(is_dynamic_t<Having>::value, "cannot call add_having() before dynamic_having()");
|
||||
return _having.add_having(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_order_by(Args... args)
|
||||
{
|
||||
static_assert(is_order_by_t<OrderBy>::value, "cannot call add_order_by() before dynamic_order_by()");
|
||||
static_assert(is_dynamic_t<OrderBy>::value, "cannot call add_order_by() before dynamic_order_by()");
|
||||
return _order_by.add_order_by(*this, args...);
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
void set_limit(Arg arg)
|
||||
{
|
||||
static_assert(is_limit_t<Limit>::value, "cannot call add_limit() before dynamic_limit()");
|
||||
static_assert(is_dynamic_t<Limit>::value, "cannot call add_limit() before dynamic_limit()");
|
||||
return _limit.set_limit(arg);
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
void set_offset(Arg arg)
|
||||
{
|
||||
static_assert(is_offset_t<Offset>::value, "cannot call add_offset() before dynamic_offset()");
|
||||
static_assert(is_dynamic_t<Offset>::value, "cannot call add_offset() before dynamic_offset()");
|
||||
return _offset.set_offset(arg);
|
||||
}
|
||||
|
||||
// PseudoTable
|
||||
template<typename AliasProvider>
|
||||
struct _pseudo_table_t
|
||||
{
|
||||
@ -148,7 +475,7 @@ namespace sqlpp
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return _column_list_t::_dynamic_columns._dynamic_expression_names;
|
||||
return _column_list._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
@ -166,12 +493,25 @@ namespace sqlpp
|
||||
return _result_row_t::static_size() + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
struct can_run_t
|
||||
{
|
||||
//static_assert(is_where_t<Where>::value, "cannot select remove without having a where condition, use .where(true) to remove all rows");
|
||||
//static_assert(not vendor::is_noop<ColumnList>::value, "cannot run select without having selected anything");
|
||||
//static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
//static_assert(is_where_t<Where>::value, "cannot run select without having a where condition, use .where(true) to select all rows");
|
||||
// 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.
|
||||
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(*this)), _result_row_t>
|
||||
{
|
||||
static_assert(detail::select_helper_t<Policies...>::template can_run_t<Db>::value, "Cannot execute select statement");
|
||||
static_assert(can_run_t<Db>::value, "Cannot execute select statement");
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
return {db.select(*this), get_dynamic_names()};
|
||||
}
|
||||
@ -181,10 +521,20 @@ namespace sqlpp
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_select_t<Db, select_t>
|
||||
{
|
||||
static_assert(detail::select_helper_t<Policies...>::template can_run_t<Db>::value, "Cannot prepare select statement");
|
||||
static_assert(can_run_t<Db>::value, "Cannot prepare select statement");
|
||||
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
|
||||
FlagList _flag_list;
|
||||
ColumnList _column_list;
|
||||
From _from;
|
||||
Where _where;
|
||||
GroupBy _group_by;
|
||||
Having _having;
|
||||
OrderBy _order_by;
|
||||
Limit _limit;
|
||||
Offset _offset;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
@ -198,15 +548,15 @@ namespace sqlpp
|
||||
{
|
||||
context << "SELECT ";
|
||||
|
||||
interpret(t._flag_list(), context);
|
||||
interpret(t._column_list(), context);
|
||||
interpret(t._from(), context);
|
||||
interpret(t._where(), context);
|
||||
interpret(t._group_by(), context);
|
||||
interpret(t._having(), context);
|
||||
interpret(t._order_by(), context);
|
||||
interpret(t._limit(), context);
|
||||
interpret(t._offset(), context);
|
||||
interpret(t._flag_list, context);
|
||||
interpret(t._column_list, context);
|
||||
interpret(t._from, context);
|
||||
interpret(t._where, context);
|
||||
interpret(t._group_by, context);
|
||||
interpret(t._having, context);
|
||||
interpret(t._order_by, context);
|
||||
interpret(t._limit, context);
|
||||
interpret(t._offset, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -233,32 +583,29 @@ namespace sqlpp
|
||||
decltype(std::tuple_cat(as_tuple<Columns>::_(std::declval<Columns>())...))>;
|
||||
}
|
||||
|
||||
|
||||
blank_select_t<void> select() // FIXME: These should be constexpr
|
||||
select_t<void> select() // FIXME: These should be constexpr
|
||||
{
|
||||
return { blank_select_t<void>() };
|
||||
return { select_t<void>() };
|
||||
}
|
||||
|
||||
template<typename... Columns>
|
||||
auto select(Columns... columns)
|
||||
-> vendor::update_policies_t<blank_select_t<void>,
|
||||
vendor::no_select_column_list_t,
|
||||
detail::make_select_column_list_t<void, Columns...>>
|
||||
-> select_t<void, vendor::no_select_flag_list_t, detail::make_select_column_list_t<void, Columns...>>
|
||||
{
|
||||
return { blank_select_t<void>(), detail::make_select_column_list_t<void, Columns...>(std::tuple_cat(detail::as_tuple<Columns>::_(columns)...)) };
|
||||
return { select_t<void>(), detail::make_select_column_list_t<void, Columns...>(std::tuple_cat(detail::as_tuple<Columns>::_(columns)...)) };
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
blank_select_t<Database> dynamic_select(const Database&)
|
||||
select_t<Database> dynamic_select(const Database&)
|
||||
{
|
||||
return { blank_select_t<Database>() };
|
||||
return { select_t<Database>() };
|
||||
}
|
||||
|
||||
template<typename Database, typename... Columns>
|
||||
auto dynamic_select(const Database&, Columns... columns)
|
||||
-> vendor::update_policies_t<blank_select_t<Database>, vendor::no_select_column_list_t, detail::make_select_column_list_t<void, Columns...>>
|
||||
-> select_t<Database, vendor::no_select_flag_list_t, detail::make_select_column_list_t<void, Columns...>>
|
||||
{
|
||||
return { blank_select_t<Database>(), detail::make_select_column_list_t<void, Columns...>(std::tuple_cat(detail::as_tuple<Columns>::_(columns)...)) };
|
||||
return { select_t<Database>(), detail::make_select_column_list_t<void, Columns...>(std::tuple_cat(detail::as_tuple<Columns>::_(columns)...)) };
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#ifndef SQLPP_SELECT_FLAGS_H
|
||||
#define SQLPP_SELECT_FLAGS_H
|
||||
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SELECT_FWD_H
|
||||
#define SQLPP_SELECT_FWD_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Policies>
|
||||
struct select_t;
|
||||
}
|
||||
#endif
|
@ -179,6 +179,12 @@ namespace sqlpp
|
||||
return { *static_cast<const Base*>(this), {t} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator +=(T t) const -> decltype(std::declval<Base>() = std::declval<Base>() + t)
|
||||
{
|
||||
return *static_cast<const Base*>(this) = operator +(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
vendor::like_t<Base, typename _operand_t<T>::type> like(T t) const
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ namespace sqlpp
|
||||
{
|
||||
using _operand_t = Operand;
|
||||
using _value_type = typename _operand_t::_value_type;
|
||||
using _table_set = typename _operand_t::_table_set;
|
||||
|
||||
tvin_t(Operand operand):
|
||||
_value(operand)
|
||||
@ -74,6 +75,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct tvin_wrap_t
|
||||
{
|
||||
using _table_set = typename T::_table_set;
|
||||
static constexpr bool _is_trivial()
|
||||
{
|
||||
return false;
|
||||
@ -94,6 +96,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct tvin_wrap_t<tvin_t<T>>
|
||||
{
|
||||
using _table_set = typename T::_table_set;
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _value._is_trivial();
|
||||
|
@ -93,6 +93,7 @@ namespace sqlpp
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_noop);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_join);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_pseudo_table);
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include <sqlpp11/vendor/update_list.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/vendor/policy.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -44,7 +42,7 @@ namespace sqlpp
|
||||
{
|
||||
template<
|
||||
typename Table,
|
||||
typename Assignments,
|
||||
typename UpdateList,
|
||||
typename Where
|
||||
>
|
||||
struct check_update_t
|
||||
@ -53,27 +51,53 @@ namespace sqlpp
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database, typename... Policies>
|
||||
struct update_t: public vendor::policy_t<Policies>..., public vendor::crtp_wrapper_t<update_t<Database, Policies...>, Policies>...
|
||||
template<typename Database = void,
|
||||
typename Table = vendor::no_single_table_t,
|
||||
typename UpdateList = vendor::no_update_list_t,
|
||||
typename Where = vendor::no_where_t>
|
||||
struct update_t
|
||||
{
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policy_update_t = update_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
static_assert(Table::_table_set::template is_superset_of<typename UpdateList::_table_set>::value, "updated columns do not match the table");
|
||||
static_assert(Table::_table_set::template is_superset_of<typename Where::_table_set>::value, "where condition does not match updated table");
|
||||
|
||||
using _database_t = Database;
|
||||
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
template<typename Needle, typename Replacement, typename... Policies>
|
||||
struct _policies_update_impl
|
||||
{
|
||||
using type = update_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _policies_update_t = typename _policies_update_impl<Needle, Replacement, Table, UpdateList, Where>::type;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Table, UpdateList, Where>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
||||
|
||||
update_t()
|
||||
{}
|
||||
|
||||
template<typename Whatever>
|
||||
update_t(update_t r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
// Constructors
|
||||
template<typename X>
|
||||
update_t(X x, Table table):
|
||||
_table(table),
|
||||
_update_list(x._update_list),
|
||||
_where(x._where)
|
||||
{}
|
||||
|
||||
template<typename Remove, typename Whatever>
|
||||
update_t(Remove r, Whatever whatever):
|
||||
vendor::policy_t<Policies>(r, whatever)...
|
||||
template<typename X>
|
||||
update_t(X x, UpdateList update_list):
|
||||
_table(x._table),
|
||||
_update_list(update_list),
|
||||
_where(x._where)
|
||||
{}
|
||||
|
||||
template<typename X>
|
||||
update_t(X x, Where where):
|
||||
_table(x._table),
|
||||
_update_list(x._update_list),
|
||||
_where(where)
|
||||
{}
|
||||
|
||||
update_t(const update_t&) = default;
|
||||
@ -82,6 +106,59 @@ namespace sqlpp
|
||||
update_t& operator=(update_t&&) = default;
|
||||
~update_t() = default;
|
||||
|
||||
// type update functions
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _policies_update_t<vendor::no_update_list_t, vendor::update_list_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<UpdateList>::value, "cannot call set()/dynamic_set() twice");
|
||||
return { *this, vendor::update_list_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> _policies_update_t<vendor::no_update_list_t, vendor::update_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<UpdateList>::value, "cannot call set()/dynamic_set() twice");
|
||||
static_assert(_is_dynamic::value, "dynamic_set must not be called in a static statement");
|
||||
return { *this, vendor::update_list_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<void, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
return { *this, vendor::where_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> _policies_update_t<vendor::no_where_t, vendor::where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(is_noop_t<Where>::value, "cannot call where()/dynamic_where() twice");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *this, vendor::where_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
|
||||
// value adding methods
|
||||
template<typename... Args>
|
||||
void add_set(Args... args)
|
||||
{
|
||||
static_assert(is_update_list_t<UpdateList>::value, "cannot call add_set() before dynamic_set()");
|
||||
static_assert(is_dynamic_t<UpdateList>::value, "cannot call add_set() before dynamic_set()");
|
||||
return _update_list.add_set(*this, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void add_where(Args... args)
|
||||
{
|
||||
static_assert(is_where_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
static_assert(is_dynamic_t<Where>::value, "cannot call add_where() before dynamic_where()");
|
||||
return _where.add_where(*this, args...);
|
||||
}
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
@ -96,7 +173,6 @@ namespace sqlpp
|
||||
std::size_t _run(Db& db) const
|
||||
{
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||
static_assert(detail::check_update_t<Policies...>::value, "Cannot run this update expression");
|
||||
return db.update(*this);
|
||||
}
|
||||
|
||||
@ -104,9 +180,12 @@ namespace sqlpp
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_update_t<Database, update_t>
|
||||
{
|
||||
static_assert(detail::check_update_t<Policies...>::value, "Cannot run this update expression");
|
||||
return {{}, db.prepare_update(*this)};
|
||||
}
|
||||
|
||||
Table _table;
|
||||
UpdateList _update_list;
|
||||
Where _where;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
@ -119,29 +198,26 @@ namespace sqlpp
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "UPDATE ";
|
||||
interpret(t._single_table(), context);
|
||||
interpret(t._update_list(), context);
|
||||
interpret(t._where(), context);
|
||||
interpret(t._table, context);
|
||||
interpret(t._update_list, context);
|
||||
interpret(t._where, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_update_t = update_t<Database, vendor::no_single_table_t, vendor::no_update_list_t, vendor::no_where_t>;
|
||||
|
||||
template<typename Table>
|
||||
constexpr auto update(Table table)
|
||||
-> update_t<void, vendor::single_table_t<void, Table>, vendor::no_update_list_t, vendor::no_where_t>
|
||||
-> update_t<void, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_update_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { update_t<void>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
template<typename Database, typename Table>
|
||||
constexpr auto dynamic_update(const Database&, Table table)
|
||||
-> update_t<Database, vendor::single_table_t<void, Table>, vendor::no_update_list_t, vendor::no_where_t>
|
||||
-> update_t<Database, vendor::single_table_t<void, Table>>
|
||||
{
|
||||
return { blank_update_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
return { update_t<Database>(), vendor::single_table_t<void, Table>{table} };
|
||||
}
|
||||
|
||||
}
|
||||
|
1
include/sqlpp11/vendor/assignment.h
vendored
1
include/sqlpp11/vendor/assignment.h
vendored
@ -44,6 +44,7 @@ namespace sqlpp
|
||||
using _column_t = Lhs;
|
||||
using value_type = Rhs;
|
||||
using _parameter_tuple_t = std::tuple<_column_t, Rhs>;
|
||||
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
|
||||
|
||||
static_assert(not std::is_same<Rhs, null_t>::value or can_be_null_t<_column_t>::value, "column cannot be null");
|
||||
|
||||
|
1
include/sqlpp11/vendor/concat.h
vendored
1
include/sqlpp11/vendor/concat.h
vendored
@ -40,6 +40,7 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
static_assert(sqlpp::detail::and_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename First::_table_set, typename Args::_table_set...>::type;
|
||||
|
||||
struct _value_type: public First::_value_type::_base_value_type
|
||||
{
|
||||
|
57
include/sqlpp11/vendor/crtp_wrapper.h
vendored
57
include/sqlpp11/vendor/crtp_wrapper.h
vendored
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_VENDOR_CRTP_WRAPPER_H
|
||||
#define SQLPP_VENDOR_CRTP_WRAPPER_H
|
||||
|
||||
#include <sqlpp11/vendor/wrong.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename T>
|
||||
struct get_database_impl;
|
||||
|
||||
template<template<typename, typename...> class Statement, typename Database, typename... Policies>
|
||||
struct get_database_impl<Statement<Database, Policies...>>
|
||||
{
|
||||
using type = Database;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using get_database_t = typename get_database_impl<T>::type;
|
||||
|
||||
template<typename Derived, typename Policy>
|
||||
struct crtp_wrapper_t
|
||||
{
|
||||
static_assert(wrong_t<Derived, Policy>::value, "missing crtp policy specialization");
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
4
include/sqlpp11/vendor/expression.h
vendored
4
include/sqlpp11/vendor/expression.h
vendored
@ -44,6 +44,7 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = ::sqlpp::detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
equal_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
@ -88,6 +89,7 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = ::sqlpp::detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
not_equal_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
@ -132,6 +134,7 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = ::sqlpp::detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs>;
|
||||
using _table_set = typename Lhs::_table_set;
|
||||
|
||||
logical_not_t(Lhs l):
|
||||
_lhs(l)
|
||||
@ -168,6 +171,7 @@ namespace sqlpp
|
||||
using _rhs_t = Rhs;
|
||||
using _value_type = typename O::_value_type;
|
||||
using _parameter_tuple_t = std::tuple<_lhs_t, _rhs_t>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
|
||||
|
||||
binary_expression_t(_lhs_t lhs, _rhs_t rhs):
|
||||
_lhs(lhs),
|
||||
|
34
include/sqlpp11/vendor/from.h
vendored
34
include/sqlpp11/vendor/from.h
vendored
@ -27,13 +27,11 @@
|
||||
#ifndef SQLPP_FROM_H
|
||||
#define SQLPP_FROM_H
|
||||
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -66,47 +64,21 @@ namespace sqlpp
|
||||
from_t& operator=(from_t&&) = default;
|
||||
~from_t() = default;
|
||||
|
||||
template<typename Table>
|
||||
void add_from(Table table)
|
||||
template<typename Select, typename Table>
|
||||
void add_from(const Select&, Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_from can only be called for dynamic_from");
|
||||
static_assert(is_table_t<Table>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
const from_t& _from() const { return *this; }
|
||||
std::tuple<Tables...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
struct no_from_t
|
||||
{
|
||||
const no_from_t& _from() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, from_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_from_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_from_t, from_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), from_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_from(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_from_t, from_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), from_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
33
include/sqlpp11/vendor/group_by.h
vendored
33
include/sqlpp11/vendor/group_by.h
vendored
@ -33,7 +33,6 @@
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -64,8 +63,8 @@ namespace sqlpp
|
||||
group_by_t& operator=(group_by_t&&) = default;
|
||||
~group_by_t() = default;
|
||||
|
||||
template<typename Expression>
|
||||
void add_group_by(Expression expression)
|
||||
template<typename Statement, typename Expression>
|
||||
void add_group_by(const Statement&, Expression expression)
|
||||
{
|
||||
static_assert(is_table_t<Expression>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_expressions.emplace_back(expression);
|
||||
@ -78,33 +77,7 @@ namespace sqlpp
|
||||
|
||||
struct no_group_by_t
|
||||
{
|
||||
using _is_group_by = std::true_type;
|
||||
const no_group_by_t& _group_by() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, group_by_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_group_by_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto group_by(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_group_by_t, group_by_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), group_by_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_group_by(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_group_by_t, group_by_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), group_by_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
30
include/sqlpp11/vendor/having.h
vendored
30
include/sqlpp11/vendor/having.h
vendored
@ -32,7 +32,6 @@
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -69,40 +68,13 @@ namespace sqlpp
|
||||
_dynamic_expressions.emplace_back(expr);
|
||||
}
|
||||
|
||||
const having_t& _having() const { return *this; }
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
struct no_having_t
|
||||
{
|
||||
using _is_having = std::true_type;
|
||||
const no_having_t& _having() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, having_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_having_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto having(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_having_t, having_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), having_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_having(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_having_t, having_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), having_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
1
include/sqlpp11/vendor/in.h
vendored
1
include/sqlpp11/vendor/in.h
vendored
@ -56,6 +56,7 @@ namespace sqlpp
|
||||
T in;
|
||||
};
|
||||
};
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Operand::_table_set, typename Args::_table_set...>::type;
|
||||
|
||||
in_t(Operand operand, Args... args):
|
||||
_operand(operand),
|
||||
|
3
include/sqlpp11/vendor/insert_value.h
vendored
3
include/sqlpp11/vendor/insert_value.h
vendored
@ -32,6 +32,7 @@
|
||||
#include <sqlpp11/tvin.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -43,6 +44,7 @@ namespace sqlpp
|
||||
struct type_if
|
||||
{
|
||||
using type = Type;
|
||||
using _table_set = typename Type::_table_set;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
@ -50,6 +52,7 @@ namespace sqlpp
|
||||
{
|
||||
struct type
|
||||
{
|
||||
using _table_set = sqlpp::detail::type_set<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
102
include/sqlpp11/vendor/insert_value_list.h
vendored
102
include/sqlpp11/vendor/insert_value_list.h
vendored
@ -32,8 +32,6 @@
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/insert_value.h>
|
||||
#include <sqlpp11/vendor/simple_column.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -42,10 +40,8 @@ namespace sqlpp
|
||||
// COLUMN AND VALUE LIST
|
||||
struct insert_default_values_t
|
||||
{
|
||||
using _is_insert_list = std::true_type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
using _is_dynamic = std::false_type;
|
||||
const insert_default_values_t& _insert_value_list() const { return *this; }
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
@ -67,8 +63,11 @@ namespace sqlpp
|
||||
|
||||
static_assert(not sqlpp::detail::or_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
static_assert(_is_dynamic::value ? (_table_set::size::value < 2) : (_table_set::size::value == 1), "set() contains assignments for tables from several columns");
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables");
|
||||
|
||||
insert_list_t(Assignments... assignment):
|
||||
_assignments(assignment...),
|
||||
@ -82,17 +81,20 @@ namespace sqlpp
|
||||
insert_list_t& operator=(insert_list_t&&) = default;
|
||||
~insert_list_t() = default;
|
||||
|
||||
template<typename Assignment>
|
||||
void add_set(Assignment assignment)
|
||||
template<typename Insert, typename Assignment>
|
||||
void add_set(const Insert&, Assignment assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<Assignment>::value, "set() arguments require to be assigments");
|
||||
static_assert(not must_not_insert_t<Assignment>::value, "set() argument must not be used in insert");
|
||||
static_assert(is_assignment_t<Assignment>::value, "add_set() arguments require to be assigments");
|
||||
static_assert(not must_not_insert_t<Assignment>::value, "add_set() argument must not be used in insert");
|
||||
using _column_table_set = typename Assignment::_column_t::_table_set;
|
||||
using _value_table_set = typename Assignment::value_type::_table_set;
|
||||
static_assert(_value_table_set::template is_subset_of<typename Insert::_table_set>::value, "add_set() contains a column from a foreign table");
|
||||
static_assert(_column_table_set::template is_subset_of<typename Insert::_table_set>::value, "add_set() contains a value from a foreign table");
|
||||
_dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
_dynamic_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
|
||||
|
||||
const insert_list_t& _insert_value_list() const { return *this; }
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::value_type...> _values;
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
@ -129,9 +131,14 @@ namespace sqlpp
|
||||
column_list_t& operator=(column_list_t&&) = default;
|
||||
~column_list_t() = default;
|
||||
|
||||
void add_values(vendor::insert_value_t<Columns>... values)
|
||||
template<typename... Assignments>
|
||||
void add_values(Assignments... assignments)
|
||||
{
|
||||
_insert_values.emplace_back(values...);
|
||||
static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
|
||||
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||
add_values_impl(_args_correct{}, assignments...); // dispatch to prevent error messages due to incorrect arguments
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
@ -139,70 +146,25 @@ namespace sqlpp
|
||||
return _insert_values.empty();
|
||||
}
|
||||
|
||||
const column_list_t& _insert_value_list() const { return *this; }
|
||||
std::tuple<simple_column_t<Columns>...> _columns;
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
|
||||
private:
|
||||
template<typename... Assignments>
|
||||
void add_values_impl(const std::true_type&, Assignments... assignments)
|
||||
{
|
||||
_insert_values.emplace_back(vendor::insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
void add_values_impl(const std::false_type&, Assignments... assignments);
|
||||
|
||||
};
|
||||
|
||||
struct no_insert_value_list_t
|
||||
{
|
||||
using _is_noop = std::true_type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
const no_insert_value_list_t& _insert_value_list() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, insert_default_values_t>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, column_list_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, insert_list_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_insert_value_list_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
struct delayed_t
|
||||
{
|
||||
using type = Derived;
|
||||
};
|
||||
|
||||
template<typename Arg = void>
|
||||
auto default_values()
|
||||
-> vendor::update_policies_t<typename delayed_t<Arg>::type, no_insert_value_list_t, insert_default_values_t>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), insert_default_values_t{} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_insert_value_list_t, column_list_t<Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), column_list_t<Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_insert_value_list_t, insert_list_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), insert_list_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_insert_value_list_t, insert_list_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_insert_list must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), insert_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
1
include/sqlpp11/vendor/like.h
vendored
1
include/sqlpp11/vendor/like.h
vendored
@ -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 _parameter_tuple_t = std::tuple<Operand, Pattern>;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Operand::_table_set, typename Pattern::_table_set>::type;
|
||||
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
|
45
include/sqlpp11/vendor/limit.h
vendored
45
include/sqlpp11/vendor/limit.h
vendored
@ -29,7 +29,6 @@
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -52,7 +51,6 @@ namespace sqlpp
|
||||
limit_t& operator=(limit_t&&) = default;
|
||||
~limit_t() = default;
|
||||
|
||||
const limit_t& _limit() const { return *this; }
|
||||
Limit _value;
|
||||
};
|
||||
|
||||
@ -88,54 +86,13 @@ namespace sqlpp
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
const dynamic_limit_t& _limit() const { return *this; }
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
struct no_limit_t
|
||||
{
|
||||
using _is_limit = std::true_type;
|
||||
const no_limit_t& _limit() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Limit>
|
||||
struct crtp_wrapper_t<Derived, limit_t<Limit>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived, typename Database>
|
||||
struct crtp_wrapper_t<Derived, dynamic_limit_t<Database>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_limit_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
struct delayed_get_database_t
|
||||
{
|
||||
using type = get_database_t<Derived>;
|
||||
};
|
||||
|
||||
template<typename Arg>
|
||||
auto limit(Arg arg)
|
||||
-> vendor::update_policies_t<Derived, no_limit_t, limit_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
typename wrap_operand<Arg>::type value = {arg};
|
||||
return { static_cast<Derived&>(*this), limit_t<typename wrap_operand<Arg>::type>(value) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_limit(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_limit_t, dynamic_limit_t<typename delayed_get_database_t<Args...>::type>>
|
||||
{
|
||||
static_assert(sizeof...(Args) < 2, "dynamic_limit must be called with zero or one arguments");
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), dynamic_limit_t<typename delayed_get_database_t<Args...>::type>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
1
include/sqlpp11/vendor/noop.h
vendored
1
include/sqlpp11/vendor/noop.h
vendored
@ -35,6 +35,7 @@ namespace sqlpp
|
||||
{
|
||||
struct noop
|
||||
{
|
||||
using is_noop = std::true_type;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
|
45
include/sqlpp11/vendor/offset.h
vendored
45
include/sqlpp11/vendor/offset.h
vendored
@ -29,7 +29,6 @@
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -52,8 +51,6 @@ namespace sqlpp
|
||||
offset_t& operator=(offset_t&&) = default;
|
||||
~offset_t() = default;
|
||||
|
||||
const offset_t& _offset() const { return *this; }
|
||||
|
||||
Offset _value;
|
||||
};
|
||||
|
||||
@ -89,53 +86,13 @@ namespace sqlpp
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
const dynamic_offset_t& _offset() const { return *this; }
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
struct no_offset_t
|
||||
{
|
||||
using _is_offset = std::true_type;
|
||||
const no_offset_t& _offset() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Offset>
|
||||
struct crtp_wrapper_t<Derived, offset_t<Offset>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived, typename Database>
|
||||
struct crtp_wrapper_t<Derived, dynamic_offset_t<Database>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_offset_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
struct delayed_get_database_t
|
||||
{
|
||||
using type = get_database_t<Derived>;
|
||||
};
|
||||
|
||||
template<typename Arg>
|
||||
auto offset(Arg arg)
|
||||
-> vendor::update_policies_t<Derived, no_offset_t, offset_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
typename wrap_operand<Arg>::type value = {arg};
|
||||
return { static_cast<Derived&>(*this), offset_t<typename wrap_operand<Arg>::type>(value) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_offset(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_offset_t, dynamic_offset_t<typename delayed_get_database_t<Args...>::type>>
|
||||
{
|
||||
static_assert(sizeof...(Args) < 2, "dynamic_offset must be called with zero or one arguments");
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), dynamic_offset_t<typename delayed_get_database_t<Args...>::type>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
35
include/sqlpp11/vendor/order_by.h
vendored
35
include/sqlpp11/vendor/order_by.h
vendored
@ -28,12 +28,10 @@
|
||||
#define SQLPP_ORDER_BY_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -63,47 +61,20 @@ namespace sqlpp
|
||||
order_by_t& operator=(order_by_t&&) = default;
|
||||
~order_by_t() = default;
|
||||
|
||||
template<typename Expression>
|
||||
void add_order_by(Expression expressions)
|
||||
template<typename Statement, typename Expression>
|
||||
void add_order_by(const Statement&, Expression expressions)
|
||||
{
|
||||
static_assert(is_sort_order_t<Expression>::value, "order_by arguments require to be sort-order expressions");
|
||||
_dynamic_expressions.push_back(expressions);
|
||||
}
|
||||
|
||||
const order_by_t& _order_by() const { return *this; }
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
struct no_order_by_t
|
||||
{
|
||||
using _is_order_by = std::true_type;
|
||||
const no_order_by_t& _order_by() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, order_by_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_order_by_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto order_by(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_order_by_t, order_by_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), order_by_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_order_by(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_order_by_t, order_by_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), order_by_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
62
include/sqlpp11/vendor/policy.h
vendored
62
include/sqlpp11/vendor/policy.h
vendored
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_VENDOR_POLICY_H
|
||||
#define SQLPP_VENDOR_POLICY_H
|
||||
|
||||
#include <sqlpp11/vendor/wrong.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename PolicyImpl>
|
||||
struct policy_t: public PolicyImpl
|
||||
{
|
||||
policy_t()
|
||||
{}
|
||||
|
||||
template<typename Whatever>
|
||||
policy_t(const Whatever&, policy_t policy):
|
||||
PolicyImpl(policy)
|
||||
{}
|
||||
|
||||
template<typename Whatever>
|
||||
policy_t(const Whatever&, PolicyImpl impl):
|
||||
PolicyImpl(impl)
|
||||
{}
|
||||
|
||||
template<typename Derived, typename Whatever>
|
||||
policy_t(Derived derived, const Whatever&):
|
||||
PolicyImpl(derived)
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
35
include/sqlpp11/vendor/select_column_list.h
vendored
35
include/sqlpp11/vendor/select_column_list.h
vendored
@ -29,7 +29,6 @@
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/result_row.h>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/vendor/field.h>
|
||||
@ -38,7 +37,6 @@
|
||||
#include <sqlpp11/vendor/named_interpretable.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -184,8 +182,8 @@ namespace sqlpp
|
||||
select_column_list_t& operator=(select_column_list_t&&) = default;
|
||||
~select_column_list_t() = default;
|
||||
|
||||
template<typename Expr>
|
||||
void add_column(Expr namedExpr)
|
||||
template<typename Select, typename Expr>
|
||||
void add_column(const Select&, Expr namedExpr)
|
||||
{
|
||||
static_assert(is_named_expression_t<Expr>::value, "select() arguments require to be named expressions");
|
||||
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
|
||||
@ -199,7 +197,7 @@ namespace sqlpp
|
||||
|
||||
struct no_select_column_list_t
|
||||
{
|
||||
using _is_select_column_list = std::true_type;
|
||||
using _is_noop = std::true_type;
|
||||
using _result_row_t = ::sqlpp::result_row_t<>;
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;
|
||||
using _value_type = no_value_t;
|
||||
@ -210,33 +208,6 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "Cannot use a select as a table when no columns have been selected yet");
|
||||
};
|
||||
|
||||
const no_select_column_list_t& _column_list() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, select_column_list_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_select_column_list_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_select_column_list_t, select_column_list_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), select_column_list_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_columns(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_select_column_list_t, select_column_list_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_columns must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), select_column_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
33
include/sqlpp11/vendor/select_flag_list.h
vendored
33
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -28,13 +28,11 @@
|
||||
#define SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/select_flags.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -63,8 +61,8 @@ namespace sqlpp
|
||||
select_flag_list_t& operator=(select_flag_list_t&&) = default;
|
||||
~select_flag_list_t() = default;
|
||||
|
||||
template<typename Flag>
|
||||
void add_flag(Flag flag)
|
||||
template<typename Select, typename Flag>
|
||||
void add_flag(const Select&, Flag flag)
|
||||
{
|
||||
static_assert(is_select_flag_t<Flag>::value, "flag arguments require to be select flags");
|
||||
_dynamic_flags.emplace_back(flag);
|
||||
@ -77,34 +75,9 @@ namespace sqlpp
|
||||
|
||||
struct no_select_flag_list_t
|
||||
{
|
||||
using _is_select_flag_list = std::true_type;
|
||||
const no_select_flag_list_t& _flag_list() const { return *this; }
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, select_flag_list_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_select_flag_list_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto flags(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_select_flag_list_t, select_flag_list_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), select_flag_list_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_flags(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_select_flag_list_t, select_flag_list_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_flags must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), select_flag_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Flags>
|
||||
|
15
include/sqlpp11/vendor/single_table.h
vendored
15
include/sqlpp11/vendor/single_table.h
vendored
@ -28,8 +28,6 @@
|
||||
#define SQLPP_VENDOR_SINGLE_TABLE_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -54,7 +52,6 @@ namespace sqlpp
|
||||
single_table_t& operator=(single_table_t&&) = default;
|
||||
~single_table_t() = default;
|
||||
|
||||
const single_table_t& _single_table() const { return *this; }
|
||||
using _table_set = typename Table::_table_set;
|
||||
Table _table;
|
||||
};
|
||||
@ -62,18 +59,6 @@ namespace sqlpp
|
||||
struct no_single_table_t
|
||||
{
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
const no_single_table_t& _single_table() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename Table>
|
||||
struct crtp_wrapper_t<Derived, single_table_t<Database, Table>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_single_table_t>
|
||||
{
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
40
include/sqlpp11/vendor/update_list.h
vendored
40
include/sqlpp11/vendor/update_list.h
vendored
@ -52,6 +52,12 @@ namespace sqlpp
|
||||
|
||||
static_assert(not ::sqlpp::detail::or_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||
static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables");
|
||||
|
||||
update_list_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
{}
|
||||
@ -62,48 +68,22 @@ namespace sqlpp
|
||||
update_list_t& operator=(update_list_t&&) = default;
|
||||
~update_list_t() = default;
|
||||
|
||||
template<typename Assignment>
|
||||
void add_set(Assignment assignment)
|
||||
template<typename Update, typename Assignment>
|
||||
void add_set(const Update&, Assignment assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<Assignment>::value, "set() arguments require to be assigments");
|
||||
static_assert(not must_not_update_t<typename Assignment::_column_t>::value, "set() argument must not be updated");
|
||||
_dynamic_assignments.emplace_back(assignment);
|
||||
}
|
||||
|
||||
const update_list_t& _update_list() const { return *this; }
|
||||
_parameter_tuple_t _assignments;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
|
||||
};
|
||||
|
||||
struct no_update_list_t
|
||||
{
|
||||
using _is_update_list = std::true_type;
|
||||
const no_update_list_t& _update_list() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, update_list_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_update_list_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_update_list_t, update_list_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), update_list_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_set(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_update_list_t, update_list_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_update_list must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), update_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
29
include/sqlpp11/vendor/using.h
vendored
29
include/sqlpp11/vendor/using.h
vendored
@ -32,7 +32,6 @@
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -71,39 +70,13 @@ namespace sqlpp
|
||||
_dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
const using_t& _using() const { return *this; }
|
||||
_parameter_tuple_t _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
struct no_using_t
|
||||
{
|
||||
const no_using_t& _using() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrapper
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, using_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_using_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto using_(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_using_t, using_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), using_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_using(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_using_t, using_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_using must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), using_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
47
include/sqlpp11/vendor/where.h
vendored
47
include/sqlpp11/vendor/where.h
vendored
@ -32,8 +32,6 @@
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -49,10 +47,13 @@ namespace sqlpp
|
||||
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
||||
static_assert(sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in where()");
|
||||
static_assert(not sqlpp::detail::or_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
|
||||
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Expressions::_table_set...>::type;
|
||||
|
||||
where_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
@ -63,15 +64,14 @@ namespace sqlpp
|
||||
where_t& operator=(where_t&&) = default;
|
||||
~where_t() = default;
|
||||
|
||||
template<typename E>
|
||||
void add_where(E expr)
|
||||
template<typename Statement, typename Expression>
|
||||
void add_where(const Statement&, Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_where can only be called for dynamic_where");
|
||||
static_assert(is_expression_t<E>::value, "invalid expression argument in add_where()");
|
||||
_dynamic_expressions.emplace_back(expr);
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_where()");
|
||||
_dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
const where_t& _where() const { return *this; }
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
@ -81,6 +81,7 @@ namespace sqlpp
|
||||
{
|
||||
using _is_where = std::true_type;
|
||||
using _is_dynamic = std::false_type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
where_t(bool condition):
|
||||
_condition(condition)
|
||||
@ -92,39 +93,13 @@ namespace sqlpp
|
||||
where_t& operator=(where_t&&) = default;
|
||||
~where_t() = default;
|
||||
|
||||
const where_t& _where() const { return *this; }
|
||||
bool _condition;
|
||||
};
|
||||
|
||||
struct no_where_t
|
||||
{
|
||||
using _is_where = std::true_type;
|
||||
const no_where_t& _where() const { return *this; }
|
||||
};
|
||||
|
||||
// CRTP Wrappers
|
||||
template<typename Derived, typename Database, typename... Args>
|
||||
struct crtp_wrapper_t<Derived, where_t<Database, Args...>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct crtp_wrapper_t<Derived, no_where_t>
|
||||
{
|
||||
template<typename... Args>
|
||||
auto where(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_where_t, where_t<void, Args...>>
|
||||
{
|
||||
return { static_cast<Derived&>(*this), where_t<void, Args...>(args...) };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_where(Args... args)
|
||||
-> vendor::update_policies_t<Derived, no_where_t, where_t<get_database_t<Derived>, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { static_cast<Derived&>(*this), where_t<get_database_t<Derived>, Args...>(args...) };
|
||||
}
|
||||
using _is_noop = std::true_type;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
|
83
include/sqlpp11/vendor/wrap_operand.h
vendored
83
include/sqlpp11/vendor/wrap_operand.h
vendored
@ -29,6 +29,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -47,6 +48,21 @@ namespace sqlpp
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = sqlpp::detail::boolean;
|
||||
using _value_t = bool;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
boolean_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
boolean_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
boolean_operand(const boolean_operand&) = default;
|
||||
boolean_operand(boolean_operand&&) = default;
|
||||
boolean_operand& operator=(const boolean_operand&) = default;
|
||||
boolean_operand& operator=(boolean_operand&&) = default;
|
||||
~boolean_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
@ -65,22 +81,36 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct integral_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = ::sqlpp::detail::integral;
|
||||
using _value_t = T;
|
||||
using _value_t = int64_t;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
integral_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
integral_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, integral_operand<T>>
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, integral_operand>
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
using Operand = integral_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
@ -90,22 +120,36 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct floating_point_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = ::sqlpp::detail::floating_point;
|
||||
using _value_t = T;
|
||||
using _value_t = double;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
floating_point_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
floating_point_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
_value_t _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, floating_point_operand<T>>
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, floating_point_operand>
|
||||
{
|
||||
using Operand = floating_point_operand<T>;
|
||||
using Operand = floating_point_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
@ -119,6 +163,21 @@ namespace sqlpp
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = ::sqlpp::detail::text;
|
||||
using _value_t = std::string;
|
||||
using _table_set = ::sqlpp::detail::type_set<>;
|
||||
|
||||
text_operand():
|
||||
_t{}
|
||||
{}
|
||||
|
||||
text_operand(_value_t t):
|
||||
_t(t)
|
||||
{}
|
||||
|
||||
text_operand(const text_operand&) = default;
|
||||
text_operand(text_operand&&) = default;
|
||||
text_operand& operator=(const text_operand&) = default;
|
||||
text_operand& operator=(text_operand&&) = default;
|
||||
~text_operand() = default;
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
@ -152,13 +211,13 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = integral_operand<T>;
|
||||
using type = integral_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand<T>;
|
||||
using type = floating_point_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
11
include/sqlpp11/vendor/wrong.h
vendored
11
include/sqlpp11/vendor/wrong.h
vendored
@ -32,15 +32,20 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// A template that always returns false
|
||||
// To be used with static assert, for instance, to ensure it
|
||||
// fires only when the template is instantiated.
|
||||
template<class ...T>
|
||||
struct wrong_t
|
||||
template<typename... T>
|
||||
struct wrong
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
using type = std::false_type;
|
||||
};
|
||||
}
|
||||
template<typename... T>
|
||||
using wrong_t = typename detail::wrong<T...>::type;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -19,5 +19,6 @@ find_package(PythonInterp REQUIRED)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_LIST_DIR}/Sample.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/ddl2cpp ${CMAKE_CURRENT_LIST_DIR}/sample.sql Sample test
|
||||
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/sample.sql
|
||||
)
|
||||
|
||||
|
@ -35,6 +35,7 @@ DbMock::_context_t printer(std::cerr);
|
||||
int main()
|
||||
{
|
||||
test::TabBar t;
|
||||
test::TabFoo f;
|
||||
|
||||
auto x = t.alpha = 7;
|
||||
auto y = t.beta = "kaesekuchen";
|
||||
@ -57,8 +58,13 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
interpret(insert_into(t).default_values(), printer).flush();
|
||||
interpret(insert_into(t), printer).flush();
|
||||
interpret(insert_into(t).set(t.beta = "kirschauflauf"), printer).flush();
|
||||
interpret(insert_into(t).columns(t.beta), printer).flush();
|
||||
auto multi_insert = insert_into(t).columns(t.beta, t.delta);
|
||||
multi_insert.add_values(t.beta = "cheesecake", t.delta = 1);
|
||||
multi_insert.add_values(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||
i.add_set(t.beta = "kirschauflauf");
|
||||
interpret(i, printer).flush();
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sqlpp11/remove.h>
|
||||
#include <sqlpp11/select.h>
|
||||
#include "Sample.h"
|
||||
#include "MockDb.h"
|
||||
#include "is_regular.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "Sample.h"
|
||||
#include "MockDb.h"
|
||||
#include "is_regular.h"
|
||||
@ -31,7 +32,6 @@
|
||||
#include <sqlpp11/functions.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
@ -175,6 +175,8 @@ int main()
|
||||
// Test a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t));
|
||||
static_assert(sqlpp::is_select_column_list_t<decltype(T::_column_list)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_from_t<decltype(T::_from)>::value, "Must not be noop");
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -271,7 +273,7 @@ int main()
|
||||
// Test that select(all_of(tab)) is expanded in select
|
||||
{
|
||||
auto a = select(all_of(t));
|
||||
auto b = select(t.alpha, t.beta, t.gamma);
|
||||
auto b = select(t.alpha, t.beta, t.gamma, t.delta);
|
||||
//auto c = select(t);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by select()");
|
||||
//static_assert(std::is_same<decltype(b), decltype(c)>::value, "t has to be expanded by select()");
|
||||
@ -280,14 +282,14 @@ int main()
|
||||
// Test that select(all_of(tab)) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(alias::a, all_of(t));
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma);
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma, t.delta);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
// Test that select(tab) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(alias::a, all_of(t));
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma);
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma, t.delta);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "t has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ DbMock::_context_t printer(std::cerr);
|
||||
int main()
|
||||
{
|
||||
test::TabBar t;
|
||||
test::TabFoo f;
|
||||
|
||||
auto x = t.alpha = 7;
|
||||
auto y = t.beta = "kaesekuchen";
|
||||
@ -58,6 +59,7 @@ int main()
|
||||
interpret(update(t), printer).flush();
|
||||
interpret(update(t).set(t.gamma = false), printer).flush();
|
||||
interpret(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).flush();
|
||||
interpret(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).flush();
|
||||
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||
u.add_set(t.gamma = false);
|
||||
interpret(u, printer).flush();
|
||||
|
@ -35,6 +35,7 @@ CREATE TABLE tab_bar
|
||||
(
|
||||
alpha bigint AUTO_INCREMENT,
|
||||
beta varchar(255) NULL DEFAULT "",
|
||||
gamma bool NOT NULL
|
||||
gamma bool NOT NULL,
|
||||
delta int
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user