mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Added support for dynamic columns to select_expression_list
Dynamic columns are not yet supported in results, though.
This commit is contained in:
parent
3718f4a57c
commit
902583a33b
98
include/sqlpp11/detail/named_serializable.h
Normal file
98
include/sqlpp11/detail/named_serializable.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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_NAMED_SERIALIZABLE_H
|
||||||
|
#define SQLPP_NAMED_SERIALIZABLE_H
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Db>
|
||||||
|
struct named_serializable_t
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
named_serializable_t(T&& t):
|
||||||
|
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(std::forward<T>(t)))
|
||||||
|
{}
|
||||||
|
|
||||||
|
named_serializable_t(const named_serializable_t&) = default;
|
||||||
|
named_serializable_t(named_serializable_t&&) = default;
|
||||||
|
named_serializable_t& operator=(const named_serializable_t&) = default;
|
||||||
|
named_serializable_t& operator=(named_serializable_t&&) = default;
|
||||||
|
~named_serializable_t() = default;
|
||||||
|
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
_impl->serialize(os, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _get_name() const
|
||||||
|
{
|
||||||
|
_impl->_get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct _impl_base
|
||||||
|
{
|
||||||
|
virtual void serialize(std::ostream& os, Db& db) const = 0;
|
||||||
|
virtual std::string _get_name() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct _impl_t: public _impl_base
|
||||||
|
{
|
||||||
|
_impl_t(const T& t):
|
||||||
|
_t(t)
|
||||||
|
{}
|
||||||
|
|
||||||
|
_impl_t(T&& t):
|
||||||
|
_t(std::move(t))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
_t.serialize(os, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _get_name() const
|
||||||
|
{
|
||||||
|
T::_name_t::_get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
T _t;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const _impl_base> _impl;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -27,13 +27,11 @@
|
|||||||
#ifndef SQLPP_SELECT_H
|
#ifndef SQLPP_SELECT_H
|
||||||
#define SQLPP_SELECT_H
|
#define SQLPP_SELECT_H
|
||||||
|
|
||||||
#include <sqlpp11/result_row.h>
|
|
||||||
#include <sqlpp11/result.h>
|
#include <sqlpp11/result.h>
|
||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/select_flag_list.h>
|
#include <sqlpp11/select_flag_list.h>
|
||||||
#include <sqlpp11/select_expression_list.h>
|
#include <sqlpp11/select_expression_list.h>
|
||||||
#include <sqlpp11/select_pseudo_table.h>
|
|
||||||
#include <sqlpp11/from.h>
|
#include <sqlpp11/from.h>
|
||||||
#include <sqlpp11/where.h>
|
#include <sqlpp11/where.h>
|
||||||
#include <sqlpp11/group_by.h>
|
#include <sqlpp11/group_by.h>
|
||||||
@ -42,7 +40,6 @@
|
|||||||
#include <sqlpp11/limit.h>
|
#include <sqlpp11/limit.h>
|
||||||
#include <sqlpp11/offset.h>
|
#include <sqlpp11/offset.h>
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/field.h>
|
|
||||||
|
|
||||||
#include <sqlpp11/detail/wrong.h>
|
#include <sqlpp11/detail/wrong.h>
|
||||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||||
@ -55,7 +52,7 @@ namespace sqlpp
|
|||||||
template<
|
template<
|
||||||
typename Database,
|
typename Database,
|
||||||
typename Flags,
|
typename Flags,
|
||||||
typename... NamedExpr,
|
typename ExpressionList,
|
||||||
typename From,
|
typename From,
|
||||||
typename Where,
|
typename Where,
|
||||||
typename GroupBy,
|
typename GroupBy,
|
||||||
@ -64,11 +61,11 @@ namespace sqlpp
|
|||||||
typename Limit,
|
typename Limit,
|
||||||
typename Offset
|
typename Offset
|
||||||
>
|
>
|
||||||
struct select_t<Database, Flags, select_expression_list_t<std::tuple<NamedExpr...>>, From, Where, GroupBy, Having, OrderBy, Limit, Offset>
|
struct select_t
|
||||||
: public select_expression_list_t<std::tuple<NamedExpr...>>::_value_type::template operators<select_t<
|
: public ExpressionList::_value_type::template operators<select_t<
|
||||||
Database,
|
Database,
|
||||||
Flags,
|
Flags,
|
||||||
select_expression_list_t<std::tuple<NamedExpr...>>,
|
ExpressionList,
|
||||||
From,
|
From,
|
||||||
Where,
|
Where,
|
||||||
GroupBy,
|
GroupBy,
|
||||||
@ -79,7 +76,6 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _Database = Database;
|
using _Database = Database;
|
||||||
using _From = From;
|
using _From = From;
|
||||||
using ExpressionList = select_expression_list_t<std::tuple<NamedExpr...>>;
|
|
||||||
|
|
||||||
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
||||||
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
|
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
|
||||||
@ -94,6 +90,8 @@ namespace sqlpp
|
|||||||
using _is_select = std::true_type;
|
using _is_select = std::true_type;
|
||||||
using _requires_braces = std::true_type;
|
using _requires_braces = std::true_type;
|
||||||
|
|
||||||
|
template<typename ExpressionListT>
|
||||||
|
using set_expression_list_t = select_t<Database, Flags, ExpressionListT, From, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
template<typename FromT>
|
template<typename FromT>
|
||||||
using set_from_t = select_t<Database, Flags, ExpressionList, FromT, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
using set_from_t = select_t<Database, Flags, ExpressionList, FromT, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
template<typename WhereT>
|
template<typename WhereT>
|
||||||
@ -109,7 +107,7 @@ namespace sqlpp
|
|||||||
template<typename OffsetT>
|
template<typename OffsetT>
|
||||||
using set_offset_t = select_t<Database, Flags, ExpressionList, From, Where, GroupBy, Having, OrderBy, Limit, OffsetT>;
|
using set_offset_t = select_t<Database, Flags, ExpressionList, From, Where, GroupBy, Having, OrderBy, Limit, OffsetT>;
|
||||||
|
|
||||||
using _result_row_t = result_row_t<make_field_t<NamedExpr>...>;
|
using _result_row_t = typename ExpressionList::_result_row_t;
|
||||||
|
|
||||||
// Indicators
|
// Indicators
|
||||||
using _value_type = typename std::conditional<
|
using _value_type = typename std::conditional<
|
||||||
@ -166,6 +164,34 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto dynamic_columns()
|
||||||
|
-> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||||
|
static_assert(is_noop<From>::value, "cannot call dynamic_columns() after from()");
|
||||||
|
return {
|
||||||
|
_flags,
|
||||||
|
{_expression_list._expressions},
|
||||||
|
_from,
|
||||||
|
_where,
|
||||||
|
_group_by,
|
||||||
|
_having,
|
||||||
|
_order_by,
|
||||||
|
_limit,
|
||||||
|
_offset
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NamedExpr>
|
||||||
|
select_t& add_column(NamedExpr&& namedExpr)
|
||||||
|
{
|
||||||
|
static_assert(is_dynamic_t<ExpressionList>::value, "cannot call add_column() in a non-dynamic column list");
|
||||||
|
|
||||||
|
_expression_list.add(std::forward<NamedExpr>(namedExpr));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// sqlpp functions
|
// sqlpp functions
|
||||||
template<typename... Table>
|
template<typename... Table>
|
||||||
auto from(Table&&... table)
|
auto from(Table&&... table)
|
||||||
@ -497,7 +523,7 @@ namespace sqlpp
|
|||||||
template<typename AliasProvider>
|
template<typename AliasProvider>
|
||||||
struct _pseudo_table_t
|
struct _pseudo_table_t
|
||||||
{
|
{
|
||||||
using table = select_pseudo_table_t<select_t, NamedExpr...>;
|
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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -573,11 +599,12 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
using make_select_expression_list_t =
|
using make_select_expression_list_t =
|
||||||
select_expression_list_t<decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... NamedExpr>
|
template<typename... NamedExpr>
|
||||||
select_t<void, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>> select(NamedExpr&&... namedExpr)
|
auto select(NamedExpr&&... namedExpr)
|
||||||
|
-> select_t<void, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
||||||
@ -585,12 +612,24 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
template<typename Db, typename... NamedExpr>
|
template<typename Db, typename... NamedExpr>
|
||||||
select_t<typename std::decay<Db>::type, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>> dynamic_select(const Db& db, NamedExpr&&... namedExpr)
|
auto dynamic_select(const Db& db, NamedExpr&&... namedExpr)
|
||||||
|
-> select_t<typename std::decay<Db>::type, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
||||||
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning: need to add dynamic fields
|
||||||
|
/* Idea: Use a vector of serializable or similar for select.
|
||||||
|
* Translate the vector into a map<string, text-similar with an index>, first = name, second = something similar to text which knows its index
|
||||||
|
*
|
||||||
|
* What about default constructing the result? Not a problem. The map is empty then.
|
||||||
|
*
|
||||||
|
* But how to transport the vector of serializables from the select into the result?
|
||||||
|
*
|
||||||
|
* Maybe store the names of the map content in a field in the query?
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,11 @@
|
|||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/expression_fwd.h>
|
#include <sqlpp11/expression_fwd.h>
|
||||||
#include <sqlpp11/no_value.h>
|
#include <sqlpp11/no_value.h>
|
||||||
|
#include <sqlpp11/field.h>
|
||||||
|
#include <sqlpp11/result_row.h>
|
||||||
#include <sqlpp11/table_base.h>
|
#include <sqlpp11/table_base.h>
|
||||||
|
#include <sqlpp11/select_pseudo_table.h>
|
||||||
|
#include <sqlpp11/detail/named_serializable.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/detail/serialize_tuple.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
@ -40,17 +44,39 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename T, typename... Rest>
|
template<typename... Rest>
|
||||||
struct get_first_argument
|
struct get_first_argument_if_unique
|
||||||
{
|
{
|
||||||
using type = T;
|
using _value_type = no_value_t;
|
||||||
|
struct _name_t {};
|
||||||
};
|
};
|
||||||
}
|
|
||||||
template<typename... NamedExpr>
|
template<typename T>
|
||||||
struct select_expression_list_t<std::tuple<NamedExpr...>>
|
struct get_first_argument_if_unique<T>
|
||||||
{
|
{
|
||||||
// check for at least one select expression
|
using _value_type = typename T::_value_type;
|
||||||
static_assert(sizeof...(NamedExpr), "at least one select expression required");
|
using _name_t = typename T::_name_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
struct dynamic_select_expression_list
|
||||||
|
{
|
||||||
|
using type = std::vector<detail::named_serializable_t<Db>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct dynamic_select_expression_list<void>
|
||||||
|
{
|
||||||
|
using type = std::vector<noop>;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Database, typename... NamedExpr>
|
||||||
|
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
|
||||||
|
{
|
||||||
|
using _is_select_expression_list = std::true_type;
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
// check for duplicate select expressions
|
// check for duplicate select expressions
|
||||||
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
||||||
@ -64,27 +90,50 @@ namespace sqlpp
|
|||||||
// check for duplicate select expression names
|
// check for duplicate select expression names
|
||||||
static_assert(not detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
|
static_assert(not detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
|
||||||
|
|
||||||
// declare this to be a select expression
|
|
||||||
using _is_select_expression_list = std::true_type;
|
|
||||||
|
|
||||||
// provide type information for sub-selects that are used as expressions
|
// provide type information for sub-selects that are used as expressions
|
||||||
struct _column_type {};
|
struct _column_type {};
|
||||||
struct _value_type: std::conditional<sizeof...(NamedExpr) == 1, typename detail::get_first_argument<NamedExpr...>::type::_value_type, no_value_t>::type
|
struct _value_type: detail::get_first_argument_if_unique<NamedExpr...>::_value_type
|
||||||
{
|
{
|
||||||
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||||
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||||
using _is_alias = std::false_type;
|
using _is_alias = std::false_type;
|
||||||
};
|
};
|
||||||
struct _no_name_t {};
|
using _name_t = typename detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
|
||||||
using _name_t = typename std::conditional<sizeof...(NamedExpr) == 1, typename detail::get_first_argument<NamedExpr...>::type::_name_t, _no_name_t>::type;
|
|
||||||
|
using _result_row_t = result_row_t<make_field_t<NamedExpr>...>;
|
||||||
|
|
||||||
|
template <typename Select>
|
||||||
|
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
|
||||||
|
|
||||||
|
template <typename Db>
|
||||||
|
using _dynamic_t = select_expression_list_t<Db, std::tuple<NamedExpr...>>;
|
||||||
|
|
||||||
|
template<typename Expr>
|
||||||
|
void add(Expr&& namedExpr)
|
||||||
|
{
|
||||||
|
static_assert(is_named_expression_t<typename std::decay<Expr>::type>::value, "select() arguments require to be named expressions");
|
||||||
|
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
|
// check for at least one select expression
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
|
||||||
|
|
||||||
detail::serialize_tuple(os, db, _expressions, ',');
|
detail::serialize_tuple(os, db, _expressions, ',');
|
||||||
|
bool first = sizeof...(NamedExpr) == 0;
|
||||||
|
for (const auto column : _dynamic_expressions)
|
||||||
|
{
|
||||||
|
if (not first)
|
||||||
|
os << ',';
|
||||||
|
column.serialize(os, db);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<NamedExpr...> _expressions;
|
std::tuple<NamedExpr...> _expressions;
|
||||||
|
typename detail::dynamic_select_expression_list<Database>::type _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace sqlpp
|
|||||||
struct straight_join_t;
|
struct straight_join_t;
|
||||||
|
|
||||||
template<typename FlagTuple> struct select_flag_list_t;
|
template<typename FlagTuple> struct select_flag_list_t;
|
||||||
template<typename NamedExprTuple> struct select_expression_list_t;
|
template<typename Database, typename NamedExprTuple> struct select_expression_list_t;
|
||||||
|
|
||||||
template<typename... TableOrJoin> struct from_t;
|
template<typename... TableOrJoin> struct from_t;
|
||||||
|
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
|
|
||||||
#include "TabSample.h"
|
#include "TabSample.h"
|
||||||
#include <sqlpp11/select.h>
|
#include <sqlpp11/select.h>
|
||||||
|
#include <sqlpp11/connection.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
class DbMock
|
class DbMock: public sqlpp::connection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const std::string& escape(const std::string& text) { return text; }
|
const std::string& escape(const std::string& text) { return text; }
|
||||||
@ -273,6 +274,12 @@ int main()
|
|||||||
std::cerr << "------------------------\n";
|
std::cerr << "------------------------\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that select can be called with zero columns if it is used with dynamic columns.
|
||||||
|
{
|
||||||
|
auto s = dynamic_select(db).dynamic_columns().add_column(t.alpha);
|
||||||
|
s.serialize(std::cerr, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
||||||
using T = sqlpp::detail::wrap_operand<int>::type;
|
using T = sqlpp::detail::wrap_operand<int>::type;
|
||||||
|
Loading…
Reference in New Issue
Block a user