mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Added interpreters to is_null, multi_column, alias and select pseudo table
This commit is contained in:
parent
1c4d041b89
commit
9826ef79e4
@ -90,15 +90,24 @@ namespace sqlpp
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "("; _expression.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
||||
}
|
||||
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
template<typename Context, typename Expression, typename AliasProvider>
|
||||
struct interpreter_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||
{
|
||||
using T = expression_alias_t<Expression, AliasProvider>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << '(';
|
||||
interpret(t._expression, context);
|
||||
context << ") AS ";
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/sort_order.h>
|
||||
#include <sqlpp11/in_fwd.h>
|
||||
#include <sqlpp11/is_null.h>
|
||||
#include <sqlpp11/is_null_fwd.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -110,13 +110,13 @@ namespace sqlpp
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
is_null_t<true, boolean, Base> is_null() const
|
||||
is_null_t<true, Base> is_null() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
is_null_t<false, boolean, Base> is_not_null() const
|
||||
is_null_t<false, Base> is_not_null() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
|
@ -231,7 +231,7 @@ namespace sqlpp
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
context << T::O::_name;
|
||||
context << O::_name;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/in.h>
|
||||
#include <sqlpp11/is_null.h>
|
||||
#include <sqlpp11/exists.h>
|
||||
#include <sqlpp11/any.h>
|
||||
#include <sqlpp11/some.h>
|
||||
|
@ -27,7 +27,7 @@
|
||||
#ifndef SQLPP_IS_NULL_H
|
||||
#define SQLPP_IS_NULL_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
@ -35,13 +35,12 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// The ValueType should be boolean, this is a hack because boolean is not fully defined when the compiler first gets here...
|
||||
template<bool NotInverted, typename ValueType, typename Operand>
|
||||
struct is_null_t: public ValueType::_base_value_type::template operators<is_null_t<NotInverted, ValueType, Operand>>
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
||||
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
@ -70,19 +69,23 @@ namespace sqlpp
|
||||
is_null_t& operator=(is_null_t&&) = default;
|
||||
~is_null_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert((NotInverted and Db::_supports_is_null)
|
||||
or (_inverted and Db::_supports_is_not_null), "is_null() and/or is_not_null() not supported by current database");
|
||||
_operand.serialize(os, db);
|
||||
os << (_inverted ? " IS NOT NULL" : " IS NULL");
|
||||
}
|
||||
|
||||
private:
|
||||
Operand _operand;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand>
|
||||
struct interpreter_t<Context, detail::is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using T = detail::is_null_t<NotInverted, Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._operand, context);
|
||||
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
39
include/sqlpp11/is_null_fwd.h
Normal file
39
include/sqlpp11/is_null_fwd.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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_IS_NULL_FWD_H
|
||||
#define SQLPP_IS_NULL_FWD_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -52,15 +52,21 @@ namespace sqlpp
|
||||
};
|
||||
using _is_multi_column = std::true_type;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
detail::serialize_tuple(os, db, _columns, ',');
|
||||
}
|
||||
|
||||
std::tuple<NamedExpr...> _columns;
|
||||
};
|
||||
|
||||
template<typename Context, typename AliasProvider, typename... NamedExpr>
|
||||
struct interpreter_t<Context, multi_column_t<AliasProvider, NamedExpr...>>
|
||||
{
|
||||
using T = multi_column_t<AliasProvider, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename AliasProvider, typename... Expr>
|
||||
|
@ -537,7 +537,7 @@ namespace sqlpp
|
||||
struct _pseudo_table_t
|
||||
{
|
||||
using table = typename ExpressionList::template _pseudo_table_t<select_t>;
|
||||
using alias = typename table::template alias_t<AliasProvider>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
|
@ -49,6 +49,7 @@ namespace sqlpp
|
||||
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
using _is_pseudo_table = std::true_type;
|
||||
|
||||
select_pseudo_table_t(const Select& select):
|
||||
_select(select)
|
||||
@ -66,16 +67,21 @@ namespace sqlpp
|
||||
select_pseudo_table_t& operator=(select_pseudo_table_t&& rhs) = default;
|
||||
~select_pseudo_table_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_select_as_table, "select as table not supported by current database");
|
||||
_select.serialize(os, db);
|
||||
}
|
||||
|
||||
Select _select;
|
||||
};
|
||||
|
||||
template<typename Context, typename Select, typename... NamedExpr>
|
||||
struct interpreter_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
||||
{
|
||||
using T = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._select, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,8 @@ namespace sqlpp
|
||||
static_assert(_all_columns::size::value, "at least one column required per table");
|
||||
using _required_insert_columns = typename detail::make_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
|
||||
using _all_of_t = std::tuple<column_t<Table, ColumnSpec>...>;
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = table_alias_t<typename std::decay<AliasProvider>::type, Table, ColumnSpec...>;
|
||||
|
||||
using _is_table = std::true_type;
|
||||
|
||||
@ -80,7 +82,7 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename AliasProvider>
|
||||
table_alias_t<typename std::decay<AliasProvider>::type, Table, ColumnSpec...> as(const AliasProvider&) const
|
||||
_alias_t<AliasProvider> as(const AliasProvider&) const
|
||||
{
|
||||
return {*static_cast<const Table*>(this)};
|
||||
}
|
||||
@ -98,13 +100,13 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Context, typename X>
|
||||
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value, void>::type>
|
||||
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_name_t::_get_name(); // FIXME: need a special rule for pseudo tables
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define SQLPP_TABLE_ALIAS_H
|
||||
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/interpreter.h>
|
||||
#include <sqlpp11/column.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
@ -94,6 +94,7 @@ namespace sqlpp
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_pseudo_table);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_list);
|
||||
|
@ -92,5 +92,10 @@ int main()
|
||||
interpret(t.as(t.alpha), printer).flush();
|
||||
interpret(t.as(t.alpha).beta, printer).flush();
|
||||
|
||||
interpret(multi_column(t.alpha, t.alpha, (t.beta + "cake").as(t.gamma)), printer).flush();
|
||||
interpret(t.alpha.is_null(), printer).flush();
|
||||
|
||||
interpret(select(t.alpha).from(t).where(t.beta > "kaesekuchen").as(t.gamma), printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user