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;
|
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;
|
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
|
#endif
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/sort_order.h>
|
#include <sqlpp11/sort_order.h>
|
||||||
#include <sqlpp11/in_fwd.h>
|
#include <sqlpp11/in_fwd.h>
|
||||||
#include <sqlpp11/is_null.h>
|
#include <sqlpp11/is_null_fwd.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -110,13 +110,13 @@ namespace sqlpp
|
|||||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
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()");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()");
|
||||||
return { *static_cast<const Base*>(this) };
|
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()");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()");
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
|
@ -231,7 +231,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
context << "(";
|
context << "(";
|
||||||
interpret(t._lhs, context);
|
interpret(t._lhs, context);
|
||||||
context << T::O::_name;
|
context << O::_name;
|
||||||
interpret(t._rhs, context);
|
interpret(t._rhs, context);
|
||||||
context << ")";
|
context << ")";
|
||||||
return context;
|
return context;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/column_types.h>
|
#include <sqlpp11/column_types.h>
|
||||||
#include <sqlpp11/in.h>
|
#include <sqlpp11/in.h>
|
||||||
|
#include <sqlpp11/is_null.h>
|
||||||
#include <sqlpp11/exists.h>
|
#include <sqlpp11/exists.h>
|
||||||
#include <sqlpp11/any.h>
|
#include <sqlpp11/any.h>
|
||||||
#include <sqlpp11/some.h>
|
#include <sqlpp11/some.h>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef SQLPP_IS_NULL_H
|
#ifndef SQLPP_IS_NULL_H
|
||||||
#define SQLPP_IS_NULL_H
|
#define SQLPP_IS_NULL_H
|
||||||
|
|
||||||
#include <sstream>
|
#include <sqlpp11/boolean.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
@ -35,13 +35,12 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace detail
|
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 Operand>
|
||||||
template<bool NotInverted, typename ValueType, typename Operand>
|
struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>>
|
||||||
struct is_null_t: public ValueType::_base_value_type::template operators<is_null_t<NotInverted, ValueType, Operand>>
|
|
||||||
{
|
{
|
||||||
static constexpr bool _inverted = not NotInverted;
|
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;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -70,19 +69,23 @@ namespace sqlpp
|
|||||||
is_null_t& operator=(is_null_t&&) = default;
|
is_null_t& operator=(is_null_t&&) = default;
|
||||||
~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;
|
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
|
#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;
|
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;
|
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
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename AliasProvider, typename... Expr>
|
template<typename AliasProvider, typename... Expr>
|
||||||
|
@ -537,7 +537,7 @@ namespace sqlpp
|
|||||||
struct _pseudo_table_t
|
struct _pseudo_table_t
|
||||||
{
|
{
|
||||||
using table = typename ExpressionList::template _pseudo_table_t<select_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>
|
template<typename AliasProvider>
|
||||||
|
@ -49,6 +49,7 @@ namespace sqlpp
|
|||||||
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
||||||
{
|
{
|
||||||
using _value_type = no_value_t;
|
using _value_type = no_value_t;
|
||||||
|
using _is_pseudo_table = std::true_type;
|
||||||
|
|
||||||
select_pseudo_table_t(const Select& select):
|
select_pseudo_table_t(const Select& select):
|
||||||
_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& operator=(select_pseudo_table_t&& rhs) = default;
|
||||||
~select_pseudo_table_t() = 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;
|
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
|
#endif
|
||||||
|
@ -46,6 +46,8 @@ namespace sqlpp
|
|||||||
static_assert(_all_columns::size::value, "at least one column required per table");
|
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 _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>...>;
|
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;
|
using _is_table = std::true_type;
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename AliasProvider>
|
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)};
|
return {*static_cast<const Table*>(this)};
|
||||||
}
|
}
|
||||||
@ -98,13 +100,13 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Context, typename X>
|
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;
|
using T = X;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
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;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define SQLPP_TABLE_ALIAS_H
|
#define SQLPP_TABLE_ALIAS_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ostream>
|
#include <sqlpp11/interpreter.h>
|
||||||
#include <sqlpp11/column.h>
|
#include <sqlpp11/column.h>
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
@ -94,6 +94,7 @@ namespace sqlpp
|
|||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||||
|
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
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);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_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), printer).flush();
|
||||||
interpret(t.as(t.alpha).beta, 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user