0
0
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:
rbock 2014-01-16 22:31:43 +01:00
parent 1c4d041b89
commit 9826ef79e4
13 changed files with 115 additions and 43 deletions

View File

@ -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

View File

@ -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) };

View File

@ -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;

View File

@ -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>

View File

@ -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

View 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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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;
}
};

View File

@ -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>

View File

@ -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);

View File

@ -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;
}