Added extra_tables to select.

With this method you can indicate additional tables that might be added
via add_from(). These tables are considered in the add_column, add
where, etc methods.
This commit is contained in:
rbock
2014-04-21 10:59:29 +02:00
parent f4ec88c83d
commit 815c061979
3 changed files with 123 additions and 5 deletions

View File

@@ -35,6 +35,7 @@
#include <sqlpp11/vendor/select_flag_list.h>
#include <sqlpp11/vendor/select_column_list.h>
#include <sqlpp11/vendor/from.h>
#include <sqlpp11/vendor/extra_tables.h>
#include <sqlpp11/vendor/where.h>
#include <sqlpp11/vendor/group_by.h>
#include <sqlpp11/vendor/having.h>
@@ -62,6 +63,7 @@ namespace sqlpp
typename FlagList = vendor::no_select_flag_list_t,
typename ColumnList = vendor::no_select_column_list_t,
typename From = vendor::no_from_t,
typename ExtraTables = vendor::no_extra_tables_t,
typename Where = vendor::no_where_t,
typename GroupBy = vendor::no_group_by_t,
typename Having = vendor::no_having_t,
@@ -75,6 +77,7 @@ namespace sqlpp
using _flag_list_t = FlagList;
using _column_list_t = ColumnList;
using _from_t = From;
using _extra_tables_t = ExtraTables;
using _where_t = Where;
using _group_by_t = GroupBy;
using _having_t = Having;
@@ -82,12 +85,13 @@ namespace sqlpp
using _limit_t = Limit;
using _offset_t = Offset;
using _statement_t = select_t<Db, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>;
using _statement_t = select_t<Db, FlagList, ColumnList, From, ExtraTables, Where, GroupBy, Having, OrderBy, Limit, Offset>;
struct _methods_t:
public _flag_list_t::template _methods_t<select_policies_t>,
public _column_list_t::template _methods_t<select_policies_t>,
public _from_t::template _methods_t<select_policies_t>,
public _extra_tables_t::template _methods_t<select_policies_t>,
public _where_t::template _methods_t<select_policies_t>,
public _group_by_t::template _methods_t<select_policies_t>,
public _having_t::template _methods_t<select_policies_t>,
@@ -104,7 +108,7 @@ namespace sqlpp
};
template<typename Needle, typename Replacement>
using _new_statement_t = typename _policies_update_t<Needle, Replacement, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>::type;
using _new_statement_t = typename _policies_update_t<Needle, Replacement, FlagList, ColumnList, From, ExtraTables, Where, GroupBy, Having, OrderBy, Limit, Offset>::type;
static_assert(is_noop_t<ColumnList>::value or sqlpp::is_select_column_list_t<ColumnList>::value, "column list of select is neither naught nor a valid column list");
static_assert(is_noop_t<From>::value or sqlpp::is_from_t<From>::value, "from() part of select is neither naught nor a valid from()");
@@ -124,7 +128,7 @@ namespace sqlpp
// The tables not covered by the from.
using _table_set = detail::make_difference_set_t<
_required_tables,
typename _from_t::_table_set // Hint: extra_tables are not used here because they are just helpers for dynamic .add_*() methods
typename _from_t::_table_set // Hint: extra_tables_t is not used here because it is just a helper for dynamic .add_*() methods and should not change the structural integrity
>;
// A select can be used as a pseudo table if
@@ -157,6 +161,7 @@ namespace sqlpp
using _flag_list_t = typename _policies_t::_flag_list_t;
using _column_list_t = typename _policies_t::_column_list_t;
using _from_t = typename _policies_t::_from_t;
using _extra_tables_t = typename _policies_t::_extra_tables_t;
using _where_t = typename _policies_t::_where_t;
using _group_by_t = typename _policies_t::_group_by_t;
using _having_t = typename _policies_t::_having_t;
@@ -252,7 +257,6 @@ namespace sqlpp
{
#warning: need to check in add_xy method as well
#warning: need add_wxy_without_table_check
#warning: might want to add an .extra_tables() method to say which tables might also be used here, say via dynamic_from or because this is a subselect
static_assert(is_table_subset_of_from<_flag_list_t>::value, "flags require additional tables in from()");
static_assert(is_table_subset_of_from<_column_list_t>::value, "selected columns require additional tables in from()");
static_assert(is_table_subset_of_from<_where_t>::value, "where() expression requires additional tables in from()");

114
include/sqlpp11/vendor/extra_tables.h vendored Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013-2014, 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_EXTRA_TABLES_H
#define SQLPP_EXTRA_TABLES_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/logic.h>
#include <sqlpp11/vendor/policy_update.h>
namespace sqlpp
{
namespace vendor
{
// EXTRA_TABLES
template<typename... Tables>
struct extra_tables_t
{
using _is_extra_tables = std::true_type;
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in extra_tables()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>;
extra_tables_t()
{}
extra_tables_t(const extra_tables_t&) = default;
extra_tables_t(extra_tables_t&&) = default;
extra_tables_t& operator=(const extra_tables_t&) = default;
extra_tables_t& operator=(extra_tables_t&&) = default;
~extra_tables_t() = default;
template<typename Policies>
struct _methods_t
{
};
};
struct no_extra_tables_t
{
using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>;
template<typename Policies>
struct _methods_t
{
template<typename T>
using _new_statement_t = typename Policies::template _new_statement_t<no_extra_tables_t, T>;
template<typename... Args>
auto extra_tables(Args...)
-> _new_statement_t<extra_tables_t<Args...>>
{
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_t<Args...>{} };
}
};
};
// Interpreters
template<typename Context, typename Database, typename... Tables>
struct serializer_t<Context, extra_tables_t<Database, Tables...>>
{
using T = extra_tables_t<Database, Tables...>;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename Context>
struct serializer_t<Context, no_extra_tables_t>
{
using T = no_extra_tables_t;
static Context& _(const T& t, Context& context)
{
return context;
}
};
}
}
#endif

View File

@@ -68,7 +68,7 @@ int main()
const bool g = row.gamma;
}
auto s = dynamic_select(db).dynamic_columns(t.alpha).dynamic_flags().dynamic_from(t).dynamic_where().dynamic_group_by(t.alpha).dynamic_order_by().dynamic_having(t.gamma).dynamic_limit().dynamic_offset();
auto s = dynamic_select(db).dynamic_columns(t.alpha).dynamic_flags().dynamic_from(t).extra_tables(f,t).dynamic_where().dynamic_group_by(t.alpha).dynamic_order_by().dynamic_having(t.gamma).dynamic_limit().dynamic_offset();
s.add_flag(sqlpp::distinct);
s.add_column(t.beta);
s.add_from(f);