diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index fb22fe58..af251d69 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -120,459 +120,6 @@ namespace sqlpp using _name_t = typename ColumnList::_name_t; - // The standard constructors, assigment operators and destructor - constexpr select_t(FlagList flag_list, ColumnList column_list, From from, - Where where, GroupBy group_by, Having having, - OrderBy order_by, Limit limit, Offset offset): - _flags(flag_list), - _columns(column_list), - _from(from), - _where(where), - _group_by(group_by), - _having(having), - _order_by(order_by), - _limit(limit), - _offset(offset) - { - } - - select_t(const select_t& rhs) = default; - select_t(select_t&& rhs) = default; - select_t& operator=(const select_t& rhs) = default; - select_t& operator=(select_t&& rhs) = default; - ~select_t() = default; - - // select functions - template - auto flags(Flag... flag) - -> set_flag_list_t>> - { - static_assert(not FlagList::size::value, "cannot call dynamic_flags() after specifying them the first time"); - static_assert(not ColumnList::size::value, "cannot call columns() after specifying them the first time"); - return { - {std::tuple{flag...}}, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - auto dynamic_flags(Flag... flag) - -> set_flag_list_t>> - { - static_assert(not std::is_same::value, "cannot call dynamic_flags() in a non-dynamic select"); - static_assert(not FlagList::size::value, "cannot call dynamic_flags() after specifying them the first time"); - static_assert(not ColumnList::size::value, "cannot call columns() after specifying them the first time"); - return { - {std::tuple{flag...}}, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - select_t& add_flag(Flag flag) - { - static_assert(is_dynamic_t::value, "cannot call add_flag() in a non-dynamic column list"); - - _flags.add(flag); - - return *this; - } - - template - auto columns(Column... column) - -> set_column_list_t>> - { - static_assert(not ColumnList::size::value, "cannot call columns() after specifying them the first time"); - return { - _flags, - {std::tuple{column...}}, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - auto dynamic_columns(Column... column) - -> set_column_list_t>> - { - static_assert(not std::is_same::value, "cannot call dynamic_columns() in a non-dynamic select"); - static_assert(not ColumnList::size::value, "cannot call dynamic_columns() after specifying them the first time"); - return { - _flags, - {std::tuple{column...}}, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - select_t& add_column(NamedExpr namedExpr) - { - static_assert(is_dynamic_t::value, "cannot call add_column() in a non-dynamic column list"); - - _columns.add(namedExpr); - - return *this; - } - - template - auto from(Table... table) - -> set_from_t> - { - static_assert(not vendor::is_noop::value, "cannot call from() without having selected anything"); - static_assert(vendor::is_noop::value, "cannot call from() twice for a single select"); - return { - _flags, - _columns, - {std::tuple{table...}}, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - auto dynamic_from(Table... table) - -> set_from_t> - { - static_assert(not std::is_same::value, "cannot call dynamic_from() in a non-dynamic select"); - static_assert(not vendor::is_noop::value, "cannot call from() without having selected anything"); - static_assert(vendor::is_noop::value, "cannot call from() twice for a single select"); - return { - _flags, - _columns, - {std::tuple{table...}}, - _where, - _group_by, - _having, - _order_by, - _limit, - _offset - }; - } - - template - select_t& add_from(Table table) - { - static_assert(not vendor::is_noop::value, "cannot call add_from() without having selected anything"); - static_assert(is_dynamic_t::value, "cannot call add_from() in a non-dynamic from"); - - _from.add(table); - - return *this; - } - - template - auto where(Expr... expr) - -> set_where_t> - { - static_assert(not vendor::is_noop::value, "cannot call where() without a from()"); - static_assert(vendor::is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); - return { - _flags, - _columns, - _from, - {std::tuple{expr...}}, - _group_by, - _having, - _order_by, - _limit, - _offset, - }; - } - - template - auto dynamic_where(Expr... expr) - -> set_where_t> - { - static_assert(not vendor::is_noop::value, "cannot call dynamic_where() without a from()"); - static_assert(vendor::is_noop::value, "cannot call where() or dynamic_where() twice for a single select"); - return { - _flags, - _columns, - _from, - {std::tuple{expr...}}, - _group_by, - _having, - _order_by, - _limit, - _offset, - }; - } - - template - select_t& add_where(Expr expr) - { - static_assert(is_dynamic_t::value, "cannot call add_where() with a non-dynamic where"); - - _where.add(expr); - - return *this; - } - - template - auto group_by(Col... column) - -> set_group_by_t> - { - static_assert(not vendor::is_noop::value, "cannot call group_by() without a from()"); - static_assert(vendor::is_noop::value, "cannot call group_by() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - {std::tuple{column...}}, - _having, - _order_by, - _limit, - _offset, - }; - } - - template - auto dynamic_group_by(Col... column) - -> set_group_by_t> - { - static_assert(not vendor::is_noop::value, "cannot call group_by() without a from()"); - static_assert(vendor::is_noop::value, "cannot call group_by() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - {std::tuple{column...}}, - _having, - _order_by, - _limit, - _offset, - }; - } - - template - select_t& add_group_by(Expr expr) - { - static_assert(is_dynamic_t::value, "cannot call add_group_by() in a non-dynamic group_by"); - - _group_by.add(expr); - - return *this; - } - - template - auto having(Expr... expr) - -> set_having_t> - { - static_assert(not vendor::is_noop::value, "cannot call having() without a group_by"); - static_assert(vendor::is_noop::value, "cannot call having() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - {std::tuple{expr...}}, - _order_by, - _limit, - _offset, - }; - } - - template - auto dynamic_having(Expr... expr) - -> set_having_t> - { - static_assert(not vendor::is_noop::value, "cannot call having() without a group_by"); - static_assert(vendor::is_noop::value, "cannot call having() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - {std::tuple{expr...}}, - _order_by, - _limit, - _offset, - }; - } - - template - select_t& add_having(Expr expr) - { - static_assert(is_dynamic_t::value, "cannot call add_having() in a non-dynamic having"); - - _having.add(expr); - - return *this; - } - - template - auto order_by(OrderExpr... expr) - -> set_order_by_t> - { - static_assert(not vendor::is_noop::value, "cannot call order_by() without a from()"); - static_assert(vendor::is_noop::value, "cannot call order_by() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - {std::tuple{expr...}}, - _limit, - _offset, - }; - } - - template - auto dynamic_order_by(OrderExpr... expr) - -> set_order_by_t> - { - static_assert(not vendor::is_noop::value, "cannot call order_by() without a from()"); - static_assert(vendor::is_noop::value, "cannot call order_by() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - {std::tuple{expr...}}, - _limit, - _offset, - }; - } - - template - select_t& add_order_by(Expr expr) - { - static_assert(is_dynamic_t::value, "cannot call add_order_by() in a non-dynamic order_by"); - - _order_by.add(expr); - - return *this; - } - - template - auto limit(Expr limit) - -> set_limit_t::type>> - { - static_assert(not vendor::is_noop::value, "cannot call limit() without a from()"); - static_assert(vendor::is_noop::value, "cannot call limit() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - {limit}, - _offset, - }; - } - - auto dynamic_limit(std::size_t limit = 0) - ->set_limit_t - { - static_assert(not vendor::is_noop::value, "cannot call limit() without a from()"); - static_assert(vendor::is_noop::value, "cannot call limit() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - {limit}, - _offset, - }; - } - - select_t& set_limit(std::size_t limit) - { - static_assert(is_dynamic_t::value, "cannot call set_limit() in a non-dynamic limit"); - - _limit.set(limit); - - return *this; - } - - template - auto offset(Expr offset) - -> set_offset_t::type>> - { - static_assert(not vendor::is_noop::value, "cannot call offset() without a limit"); - static_assert(vendor::is_noop::value, "cannot call offset() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - {offset}, - }; - } - - auto dynamic_offset(std::size_t offset = 0) - -> set_offset_t - { - static_assert(not vendor::is_noop::value, "cannot call offset() without a limit"); - static_assert(vendor::is_noop::value, "cannot call offset() twice for a single select"); - return { - _flags, - _columns, - _from, - _where, - _group_by, - _having, - _order_by, - _limit, - {offset}, - }; - } - - select_t& set_offset(std::size_t offset) - { - static_assert(is_dynamic_t::value, "cannot call set_offset() in a non-dynamic limit"); - - _offset.set(offset); - - return *this; - } - template struct _pseudo_table_t { @@ -648,9 +195,8 @@ namespace sqlpp { context << "SELECT "; - /* - interpret(t._flags, context); - interpret(t._columns, context); + interpret(t._flag_list, context); + interpret(t._column_list, context); interpret(t._from, context); interpret(t._where, context); interpret(t._group_by, context); @@ -658,60 +204,48 @@ namespace sqlpp interpret(t._order_by, context); interpret(t._limit, context); interpret(t._offset, context); - */ return context; } }; } + template + using blank_select_t = select_t; - /* - - // construct select flag list - namespace detail + blank_select_t select() // FIXME: These should be constexpr { - template - using make_select_flag_list_t = - vendor::select_flag_list_t()...))>; + return { blank_select_t() }; } - // construct select expression list - namespace detail - { - template - using make_select_column_list_t = - vendor::select_column_list_t()...))>; - } - - auto select() - -> select_t>, vendor::select_column_list_t>> + template + auto select(Columns... columns) + -> vendor::update_policies_t, vendor::no_select_column_list_t, vendor::select_column_list_t> { - return { {}, vendor::select_column_list_t>{}, {}, {}, {}, {}, {}, {}, {} }; + return { blank_select_t(), vendor::select_column_list_t(columns...) }; } - template - auto select(NamedExpr... namedExpr) - -> select_t, detail::make_select_column_list_t> + template + blank_select_t dynamic_select() { - return { - { detail::make_flag_tuple(namedExpr...) }, - { detail::make_expression_tuple(namedExpr...) }, - {}, {}, {}, {}, {}, {}, {} - }; + return { blank_select_t() }; } - template - auto dynamic_select(const Db& db, NamedExpr... namedExpr) - -> select_t, detail::make_select_column_list_t> + template + auto dynamic_select(Columns... columns) + -> vendor::update_policies_t, vendor::no_select_column_list_t, vendor::select_column_list_t> { - return { - { detail::make_flag_tuple(namedExpr...) }, - { detail::make_expression_tuple(namedExpr...) }, - {}, {}, {}, {}, {}, {}, {} - }; + return { blank_select_t(), vendor::select_column_list_t(columns...) }; } - */ } #endif diff --git a/include/sqlpp11/vendor/having.h b/include/sqlpp11/vendor/having.h index 116e1e2a..cc5de0ac 100644 --- a/include/sqlpp11/vendor/having.h +++ b/include/sqlpp11/vendor/having.h @@ -52,6 +52,16 @@ namespace sqlpp using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; + having_t(Expressions... expressions): + _expressions(expressions...) + {} + + having_t(const having_t&) = default; + having_t(having_t&&) = default; + having_t& operator=(const having_t&) = default; + having_t& operator=(having_t&&) = default; + ~having_t() = default; + template void add(Expression expr) { diff --git a/include/sqlpp11/vendor/limit.h b/include/sqlpp11/vendor/limit.h index d3b175a5..be74b7c5 100644 --- a/include/sqlpp11/vendor/limit.h +++ b/include/sqlpp11/vendor/limit.h @@ -56,29 +56,30 @@ namespace sqlpp Limit _value; }; - struct dynamic_limit_t - { - using _is_limit = std::true_type; - using _is_dynamic = std::true_type; - - dynamic_limit_t(size_t value): - _value(value) - {} - - dynamic_limit_t(const dynamic_limit_t&) = default; - dynamic_limit_t(dynamic_limit_t&&) = default; - dynamic_limit_t& operator=(const dynamic_limit_t&) = default; - dynamic_limit_t& operator=(dynamic_limit_t&&) = default; - ~dynamic_limit_t() = default; - - void set_limit(std::size_t limit) + template + struct dynamic_limit_t { - _value = limit; - } + using _is_limit = std::true_type; + using _is_dynamic = std::true_type; - dynamic_limit_t& _limit = *this; - std::size_t _value; // FIXME: This should be a serializable! - }; + dynamic_limit_t(size_t value): + _value(value) + {} + + dynamic_limit_t(const dynamic_limit_t&) = default; + dynamic_limit_t(dynamic_limit_t&&) = default; + dynamic_limit_t& operator=(const dynamic_limit_t&) = default; + dynamic_limit_t& operator=(dynamic_limit_t&&) = default; + ~dynamic_limit_t() = default; + + void set_limit(std::size_t limit) + { + _value = limit; + } + + dynamic_limit_t& _limit = *this; + std::size_t _value; // FIXME: This should be a serializable! + }; struct no_limit_t { @@ -92,14 +93,20 @@ namespace sqlpp { }; - template - struct crtp_wrapper_t + template + struct crtp_wrapper_t> { }; template struct crtp_wrapper_t { + template + struct delayed_get_database_t + { + using type = get_database_t; + }; + template auto limit(Arg arg) -> vendor::update_policies_t> @@ -107,19 +114,20 @@ namespace sqlpp return { static_cast(*this), limit_t(arg) }; } - auto dynamic_limit(size_t arg) - -> vendor::update_policies_t + template + auto dynamic_limit(Arg arg) + -> vendor::update_policies_t::type>> { static_assert(not std::is_same, void>::value, "dynamic_limit must not be called in a static statement"); - return { static_cast(*this), dynamic_limit_t(arg) }; + return { static_cast(*this), dynamic_limit_t::type>(arg) }; } }; // Interpreters - template - struct interpreter_t + template + struct interpreter_t> { - using T = dynamic_limit_t; + using T = dynamic_limit_t; static Context& _(const T& t, Context& context) { diff --git a/include/sqlpp11/vendor/offset.h b/include/sqlpp11/vendor/offset.h index 7f4df82b..5af2ee84 100644 --- a/include/sqlpp11/vendor/offset.h +++ b/include/sqlpp11/vendor/offset.h @@ -56,29 +56,30 @@ namespace sqlpp Offset _value; }; - struct dynamic_offset_t - { - using _is_offset = std::true_type; - using _is_dynamic = std::true_type; - - dynamic_offset_t(size_t value): - _value(value) - {} - - dynamic_offset_t(const dynamic_offset_t&) = default; - dynamic_offset_t(dynamic_offset_t&&) = default; - dynamic_offset_t& operator=(const dynamic_offset_t&) = default; - dynamic_offset_t& operator=(dynamic_offset_t&&) = default; - ~dynamic_offset_t() = default; - - void set_offset(std::size_t offset) + template + struct dynamic_offset_t { - _value = offset; - } + using _is_offset = std::true_type; + using _is_dynamic = std::true_type; - dynamic_offset_t& _offset = *this; - std::size_t _value; // FIXME: This should be a serializable! - }; + dynamic_offset_t(size_t value): + _value(value) + {} + + dynamic_offset_t(const dynamic_offset_t&) = default; + dynamic_offset_t(dynamic_offset_t&&) = default; + dynamic_offset_t& operator=(const dynamic_offset_t&) = default; + dynamic_offset_t& operator=(dynamic_offset_t&&) = default; + ~dynamic_offset_t() = default; + + void set_offset(std::size_t offset) + { + _value = offset; + } + + dynamic_offset_t& _offset = *this; + std::size_t _value; // FIXME: This should be a serializable! + }; struct no_offset_t { @@ -92,14 +93,20 @@ namespace sqlpp { }; - template - struct crtp_wrapper_t + template + struct crtp_wrapper_t> { }; template struct crtp_wrapper_t { + template + struct delayed_get_database_t + { + using type = get_database_t; + }; + template auto offset(Arg arg) -> vendor::update_policies_t> @@ -107,11 +114,12 @@ namespace sqlpp return { static_cast(*this), offset_t(arg) }; } - auto dynamic_offset(size_t arg) - -> vendor::update_policies_t + template + auto dynamic_offset(Arg arg) + -> vendor::update_policies_t::type>> { static_assert(not std::is_same, void>::value, "dynamic_offset must not be called in a static statement"); - return { static_cast(*this), dynamic_offset_t(arg) }; + return { static_cast(*this), dynamic_offset_t>(arg) }; } }; @@ -129,10 +137,10 @@ namespace sqlpp } }; - template - struct interpreter_t + template + struct interpreter_t> { - using T = dynamic_offset_t; + using T = dynamic_offset_t; static Context& _(const T& t, Context& context) { diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 58efc51a..3646635e 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -69,15 +69,20 @@ int main() interpret(t.gamma != sqlpp::tvin(false), printer).flush(); interpret(t.alpha == 7, printer).flush(); interpret(t.beta + "kaesekuchen", printer).flush(); + */ - interpret(select(sqlpp::distinct, t.alpha, t.beta), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()), printer).flush(); - interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()).limit(17).offset(3), printer).flush(); + interpret(sqlpp::select(), printer).flush(); + interpret(sqlpp::select().flags(sqlpp::distinct), printer).flush(); + interpret(select(t.alpha, t.beta).flags(sqlpp::distinct), printer).flush(); + interpret(select(t.alpha, t.beta), printer).flush(); + interpret(select(t.alpha, t.beta).from(t), printer).flush(); + interpret(select(t.alpha, t.beta).from(t).where(t.alpha == 3), printer).flush(); + interpret(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma), printer).flush(); + interpret(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")), printer).flush(); + interpret(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()), printer).flush(); + interpret(select(t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()).limit(17).offset(3), printer).flush(); + /* interpret(parameter(sqlpp::bigint(), t.alpha), printer).flush(); interpret(parameter(t.alpha), printer).flush(); interpret(t.alpha == parameter(t.alpha), printer).flush();